diff --git a/.gitmodules b/.gitmodules index 839de75ef..59d2c0ac9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,14 +14,6 @@ path = extern/jbus url = ../jbus.git branch = master -[submodule "extern/tinyxml2"] - path = extern/tinyxml2 - url = ../tinyxml2.git - branch = master -[submodule "extern/sanitizers-cmake"] - path = extern/sanitizers-cmake - url = https://github.com/arsenm/sanitizers-cmake.git - branch = master [submodule "extern/discord-rpc"] path = extern/discord-rpc url = https://github.com/discordapp/discord-rpc.git @@ -34,10 +26,6 @@ path = extern/fixNES url = https://github.com/FIX94/fixNES.git branch = master -[submodule "extern/libSquish"] - path = extern/libSquish - url = ../libSquish.git - branch = master [submodule "extern/athena"] path = extern/athena url = ../../libAthena/athena.git @@ -66,3 +54,6 @@ [submodule "extern/nativefiledialog"] path = extern/nativefiledialog url = https://github.com/mlabbe/nativefiledialog.git +[submodule "extern/optick"] + path = extern/optick + url = https://github.com/AxioDL/optick.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 94fc8717d..473c03a4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,15 +92,6 @@ if(APPLE AND NOT CMAKE_OSX_SYSROOT) OUTPUT_STRIP_TRAILING_WHITESPACE) endif() -option(METAFORCE_CROSSCOMPILING "Don't build tools; attempt package import" OFF) -if (METAFORCE_CROSSCOMPILING) - set(CMAKE_CROSSCOMPILING On) -endif() - -if(CMAKE_CROSSCOMPILING) - set(HAVE_WORDS_BIGENDIAN_EXITCODE 0 CACHE INTEGER "Makes soxr happy" FORCE) -endif() - # MSVC has a "latest" flag, which always uses the newest standard # when available. GCC and Clang posess no such flag, and must be # manually enforced. CMake, curiously, also doesn't have a "latest" @@ -346,45 +337,15 @@ if (NOT WIN32) set(ZLIB_LIBRARIES ZLIB::ZLIB CACHE STRING "zlib libraries" FORCE) endif() -# TODO migrate bintoc -include(hecl/ApplicationTools.cmake) +include(ExternalProject) +ExternalProject_Add(bintoc + SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/bintoc" + CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH= + INSTALL_COMMAND ${CMAKE_COMMAND} --build . --config Release --target install) +include(${CMAKE_CURRENT_LIST_DIR}/bintoc/bintocHelpers.cmake) add_subdirectory(extern) - -set(DATA_SPEC_LIBS RetroDataSpec AssetNameMap) -set(HECL_DATASPEC_DECLS -"/* RetroCommon specs */ -namespace DataSpec -{ - extern hecl::Database::DataSpecEntry SpecEntMP1; - extern hecl::Database::DataSpecEntry SpecEntMP1PC; - extern hecl::Database::DataSpecEntry SpecEntMP1ORIG; - extern hecl::Database::DataSpecEntry SpecEntMP2; - extern hecl::Database::DataSpecEntry SpecEntMP2PC; - extern hecl::Database::DataSpecEntry SpecEntMP2ORIG; - extern hecl::Database::DataSpecEntry SpecEntMP3; - extern hecl::Database::DataSpecEntry SpecEntMP3PC; - extern hecl::Database::DataSpecEntry SpecEntMP3ORIG; -}") -set(HECL_DATASPEC_PUSHES -" /* RetroCommon */ - hecl::Database::DATA_SPEC_REGISTRY.reserve(9); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP1); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP1PC); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP1ORIG); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP2); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP2PC); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP2ORIG); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3PC); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3ORIG);") - add_subdirectory(imgui) -add_subdirectory(hecl EXCLUDE_FROM_ALL) -target_include_directories(hecl-full PRIVATE ${CMAKE_SOURCE_DIR}) -target_include_directories(hecl-light PRIVATE ${CMAKE_SOURCE_DIR}) -target_link_libraries(hecl-full PRIVATE zeus nod) -target_link_libraries(hecl-light PRIVATE zeus nod) if(NOT TARGET atdna) # Import native atdna if cross-compiling @@ -394,65 +355,20 @@ if(NOT TARGET atdna) endif() endif() -if (NOT CMAKE_CROSSCOMPILING) - add_subdirectory(assetnameparser EXCLUDE_FROM_ALL) -endif () -add_compile_definitions(URDE_ZIP_INPUT_STREAM=1) # Enable CZipInputStream now that zlib header is known -add_subdirectory(DataSpec EXCLUDE_FROM_ALL) - add_subdirectory(NESEmulator EXCLUDE_FROM_ALL) add_subdirectory(aurora) add_subdirectory(Runtime) -add_subdirectory(mpcksum EXCLUDE_FROM_ALL) add_subdirectory(gbalink EXCLUDE_FROM_ALL) -if (NOT WINDOWS_STORE AND NOT NX) - if (APPLE AND EXISTS /opt/local/libexec/qt5) - # macports qt5 (build with +universal) - set(Qt5Widgets_DIR /opt/local/libexec/qt5) - elseif (APPLE AND CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64) - set(QT_HOMEBREW_PATH /usr/local/opt/qt) - elseif (APPLE AND CMAKE_SYSTEM_PROCESSOR STREQUAL arm64) - set(QT_HOMEBREW_PATH /opt/homebrew/opt/qt) - else () - set(QT_HOMEBREW_PATH "") - endif () - - find_package(Qt6Widgets QUIET PATHS ${QT_HOMEBREW_PATH}) - find_package(Qt5Widgets QUIET PATHS ${QT_HOMEBREW_PATH}) - if (Qt6Widgets_FOUND) - message(STATUS "Qt6 found, metaforce-gui will be built") - add_subdirectory(metaforce-gui EXCLUDE_FROM_ALL) - elseif(Qt5Widgets_FOUND) - message(STATUS "Qt5 found, metaforce-gui will be built") - add_subdirectory(metaforce-gui EXCLUDE_FROM_ALL) - else() - message(STATUS "Qt5-6 not found, metaforce-gui will not be built") - endif() -endif() - configure_file(${CMAKE_SOURCE_DIR}/version.h.in ${CMAKE_BINARY_DIR}/version.h) # Packaging logic -list(APPEND BINARY_TARGETS metaforce) # hecl visigen +list(APPEND BINARY_TARGETS metaforce) set(DSYM_ONLY_TARGETS "") if (TARGET crashpad_handler) list(APPEND BINARY_TARGETS crashpad_handler) endif () set(BIN_PREFIX "${CMAKE_INSTALL_PREFIX}") -#if (TARGET metaforce-gui) -# if (APPLE) -# # app bundle already has all needed binaries -# install(TARGETS metaforce-gui DESTINATION ${BIN_PREFIX}) -# list(APPEND DSYM_ONLY_TARGETS metaforce-gui) -# # we have to rename here, cmake is inflexible about bundle naming -# install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_PREFIX}\" COMMAND rm -fr Metaforce.app)") -# install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_PREFIX}\" COMMAND mv metaforce-gui.app Metaforce.app)") -# set(BIN_PREFIX "${BIN_PREFIX}/Metaforce.app/Contents/MacOS") -# else() -# list(APPEND BINARY_TARGETS metaforce-gui) -# endif () -#endif () install(TARGETS ${BINARY_TARGETS} DESTINATION ${BIN_PREFIX}) if (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo) foreach (target IN LISTS BINARY_TARGETS DSYM_ONLY_TARGETS) diff --git a/DataSpec/AssetMap32Download.cmake b/DataSpec/AssetMap32Download.cmake deleted file mode 100644 index d9a017057..000000000 --- a/DataSpec/AssetMap32Download.cmake +++ /dev/null @@ -1,3 +0,0 @@ -message(STATUS "32-bit asset name map not found; downloading to '${CMAKE_CURRENT_BINARY_DIR}/AssetNameMap32.bin'") -file(DOWNLOAD "https://axiodl.com/files/AssetNameMap32.dat" - ${CMAKE_CURRENT_BINARY_DIR}/AssetNameMap32.bin SHOW_PROGRESS EXPECTED_HASH SHA1=90b4e941c192eef41c81e60314f348bc787d1336) diff --git a/DataSpec/AssetMap64Download.cmake b/DataSpec/AssetMap64Download.cmake deleted file mode 100644 index a5502f9b1..000000000 --- a/DataSpec/AssetMap64Download.cmake +++ /dev/null @@ -1,3 +0,0 @@ -message(STATUS "64-bit asset name map not found; downloading to '${CMAKE_CURRENT_BINARY_DIR}/AssetNameMap64.bin'") -file(DOWNLOAD "https://axiodl.com/files/AssetNameMap64.dat" - ${CMAKE_CURRENT_BINARY_DIR}/AssetNameMap64.bin SHOW_PROGRESS EXPECTED_HASH SHA1=e49c03c9fff66adccec7af8120dda091636513e2) diff --git a/DataSpec/AssetNameMap.cpp b/DataSpec/AssetNameMap.cpp deleted file mode 100644 index 350feb0ae..000000000 --- a/DataSpec/AssetNameMap.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "AssetNameMap.hpp" -#include "athena/Compression.hpp" -#include "athena/MemoryReader.hpp" - -extern "C" const uint8_t ASSET_NAME_MP32[]; -extern "C" const size_t ASSET_NAME_MP32_SZ; -extern "C" const size_t ASSET_NAME_MP32_DECOMPRESSED_SZ; -extern "C" const uint8_t ASSET_NAME_MP64[]; -extern "C" const size_t ASSET_NAME_MP64_SZ; -extern "C" const size_t ASSET_NAME_MP64_DECOMPRESSED_SZ; - -namespace DataSpec::AssetNameMap { -logvisor::Module Log("AssetNameMap"); - -struct SAsset { - std::string name; - std::string directory; - hecl::FourCC type; - SAsset() = default; - SAsset(const hecl::FourCC& typeIn, athena::io::IStreamReader& in) : type(typeIn) { - uint32_t nameLen = in.readUint32Big(); - name = in.readString(nameLen); - uint32_t dirLen = in.readUint32Big(); - directory = in.readString(dirLen); - } -}; - -static std::unordered_map g_AssetNameMap; -static bool g_AssetNameMapInit = false; - -void LoadAssetMap(athena::io::MemoryReader& ar) { - if (!ar.hasError()) { - hecl::FourCC magic; - if (ar.length() >= 4) - ar.readBytesToBuf(&magic, 4); - if (magic != FOURCC('AIDM')) - Log.report( - logvisor::Warning, - FMT_STRING("Unable to load asset map; Assets will not have proper filenames for most files.")); - else { - uint32_t assetCount = ar.readUint32Big(); - g_AssetNameMap.reserve(assetCount); - for (uint32_t i = 0; i < assetCount; ++i) { - hecl::FourCC type; - ar.readBytesToBuf(&type, 4); - uint64_t id = ar.readUint64Big(); - g_AssetNameMap[id] = SAsset(type, ar); - } - } - } -} - -void InitAssetNameMap() { - if (g_AssetNameMapInit) - return; - - Log.report(logvisor::Info, FMT_STRING("Initializing asset name database...")); - - /* First load the 32bit map for MP1/2 */ - if (ASSET_NAME_MP32_DECOMPRESSED_SZ != 0u) { - auto* decompressed = new uint8_t[ASSET_NAME_MP32_DECOMPRESSED_SZ]; - athena::io::Compression::decompressZlib(ASSET_NAME_MP32, ASSET_NAME_MP32_SZ, decompressed, - ASSET_NAME_MP32_DECOMPRESSED_SZ); - athena::io::MemoryReader ar(decompressed, ASSET_NAME_MP32_DECOMPRESSED_SZ); - LoadAssetMap(ar); - delete[](decompressed); - } else { - Log.report( - logvisor::Warning, - FMT_STRING("AssetNameMap32 unavailable; Assets will not have proper filenames for most files.")); - } - /* Now load the 64bit map for MP3 */ - if (ASSET_NAME_MP64_DECOMPRESSED_SZ != 0u) { - auto* decompressed = new uint8_t[ASSET_NAME_MP64_DECOMPRESSED_SZ]; - athena::io::Compression::decompressZlib(ASSET_NAME_MP64, ASSET_NAME_MP64_SZ, decompressed, - ASSET_NAME_MP64_DECOMPRESSED_SZ); - athena::io::MemoryReader ar(decompressed, ASSET_NAME_MP64_DECOMPRESSED_SZ); - LoadAssetMap(ar); - delete[](decompressed); - } else { - Log.report( - logvisor::Warning, - FMT_STRING("AssetNameMap64 unavailable; Assets will not have proper filenames for most files.")); - } - g_AssetNameMapInit = true; -} - -const std::string* TranslateIdToName(const UniqueID32& id) { - if (g_AssetNameMap.find(id.toUint64()) == g_AssetNameMap.cend()) - return nullptr; - - return &g_AssetNameMap[id.toUint64()].name; -} - -} // namespace DataSpec::AssetNameMap diff --git a/DataSpec/AssetNameMap.hpp b/DataSpec/AssetNameMap.hpp deleted file mode 100644 index fb3e5c49c..000000000 --- a/DataSpec/AssetNameMap.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include -#include -#include "DNACommon/DNACommon.hpp" - -namespace DataSpec::AssetNameMap { -void InitAssetNameMap(); -const std::string* TranslateIdToName(const UniqueID32&); -const std::string* TranslateIdToName(const UniqueID64&); -} // namespace DataSpec::AssetNameMap diff --git a/DataSpec/AssetNameMapNull.cpp b/DataSpec/AssetNameMapNull.cpp deleted file mode 100644 index b077d2a0f..000000000 --- a/DataSpec/AssetNameMapNull.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -extern "C" const uint8_t ASSET_NAME_MP32[] = {0}; -extern "C" const size_t ASSET_NAME_MP32_SZ = 0; -extern "C" const size_t ASSET_NAME_MP32_DECOMPRESSED_SZ = 0; -extern "C" const uint8_t ASSET_NAME_MP64[] = {0}; -extern "C" const size_t ASSET_NAME_MP64_SZ = 0; -extern "C" const size_t ASSET_NAME_MP64_DECOMPRESSED_SZ = 0; diff --git a/DataSpec/Blender/BlenderSupport.cpp b/DataSpec/Blender/BlenderSupport.cpp deleted file mode 100644 index b5fef6587..000000000 --- a/DataSpec/Blender/BlenderSupport.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include "hecl/Blender/Connection.hpp" -#include "BlenderSupport.hpp" - -extern "C" uint8_t RETRO_MASTER_SHADER[]; -extern "C" size_t RETRO_MASTER_SHADER_SZ; - -namespace DataSpec::Blender { - -bool BuildMasterShader(const hecl::ProjectPath& path) { - hecl::blender::Connection& conn = hecl::blender::Connection::SharedConnection(); - if (!conn.createBlend(path, hecl::blender::BlendType::None)) - return false; - { - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os << std::string_view((char*)RETRO_MASTER_SHADER, RETRO_MASTER_SHADER_SZ); - os << "make_master_shader_library()\n"sv; - } - return conn.saveBlend(); -} - -} // namespace DataSpec::Blender diff --git a/DataSpec/Blender/BlenderSupport.hpp b/DataSpec/Blender/BlenderSupport.hpp deleted file mode 100644 index 8a5cd7eca..000000000 --- a/DataSpec/Blender/BlenderSupport.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include - -namespace DataSpec::Blender { - -bool BuildMasterShader(const hecl::ProjectPath& path); - -} diff --git a/DataSpec/Blender/RetroMasterShader.py b/DataSpec/Blender/RetroMasterShader.py deleted file mode 100644 index 70f837978..000000000 --- a/DataSpec/Blender/RetroMasterShader.py +++ /dev/null @@ -1,1876 +0,0 @@ -"Defines node groups implementing shader components found in Retro games" - -import bpy - - -# Root Eevee Nodes - -# Additive output node -def make_additive_output(): - new_grp = bpy.data.node_groups.new('HECLAdditiveOutput', 'ShaderNodeTree') - shader_input = new_grp.inputs.new('NodeSocketShader', 'Surface') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (0, 0) - - # Add Shader - emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - emissive_add_shader.location = (200, 0) - - # Transparent BDSF (Provides alpha) - transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent') - transparent_bdsf.location = (0, 100) - transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0) - - # Material Output (Final output) - mat_out = new_grp.nodes.new('ShaderNodeOutputMaterial') - mat_out.location = (400, 0) - - # Links - new_grp.links.new(grp_in.outputs['Surface'], emissive_add_shader.inputs[1]) - new_grp.links.new(transparent_bdsf.outputs[0], emissive_add_shader.inputs[0]) - new_grp.links.new(emissive_add_shader.outputs[0], mat_out.inputs['Surface']) - - -# Blend output node -def make_blend_opaque_output(): - for tp in ('HECLBlendOutput', 'HECLOpaqueOutput'): - new_grp = bpy.data.node_groups.new(tp, 'ShaderNodeTree') - shader_input = new_grp.inputs.new('NodeSocketShader', 'Surface') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (0, 0) - - # Material Output (Final output) - mat_out = new_grp.nodes.new('ShaderNodeOutputMaterial') - mat_out.location = (200, 0) - - # Links - new_grp.links.new(grp_in.outputs['Surface'], mat_out.inputs['Surface']) - - -# 0 - RetroShader -def make_retro_shader(): - new_grp = bpy.data.node_groups.new('RetroShader', 'ShaderNodeTree') - surface_output = new_grp.outputs.new('NodeSocketShader', 'Surface') - lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap') - lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0) - diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse') - diffuse_input.default_value = (0.0, 0.0, 0.0, 0.0) - diffuse_mod_input = new_grp.inputs.new('NodeSocketColor', 'DiffuseMod') - diffuse_mod_input.default_value = (1.0, 1.0, 1.0, 1.0) - emissive_input = new_grp.inputs.new('NodeSocketColor', 'Emissive') - emissive_input.default_value = (0.0, 0.0, 0.0, 0.0) - specular_input = new_grp.inputs.new('NodeSocketColor', 'Specular') - specular_input.default_value = (0.0, 0.0, 0.0, 0.0) - ext_spec_input = new_grp.inputs.new('NodeSocketColor', 'ExtendedSpecular') - ext_spec_input.default_value = (0.0, 0.0, 0.0, 0.0) - reflection_input = new_grp.inputs.new('NodeSocketColor', 'Reflection') - reflection_input.default_value = (0.0, 0.0, 0.0, 0.0) - indirect_tex = new_grp.inputs.new('NodeSocketColor', 'IndirectTex') - indirect_tex.default_value = (0.0, 0.0, 0.0, 0.0) - alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'Alpha') - alpha_input.default_value = 1.0 - alpha_input.min_value = 0.0 - alpha_input.max_value = 1.0 - alpha_mod_input = new_grp.inputs.new('NodeSocketFloatFactor', 'AlphaMod') - alpha_mod_input.default_value = 1.0 - alpha_mod_input.min_value = 0.0 - alpha_mod_input.max_value = 1.0 - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-1280, 27) - - # New shader model - new_shader_model = new_grp.nodes.new('ShaderNodeValue') - new_shader_model.name = 'NewShaderModel' - new_shader_model.label = 'NewShaderModel' - new_shader_model.location = (-1280, 118) - new_shader_model.outputs[0].default_value = 0.0 - - # Principled BSDF (For new shader model) - principled_bsdf = new_grp.nodes.new('ShaderNodeBsdfPrincipled') - principled_bsdf.location = (-1038, 874) - principled_bsdf.inputs['Metallic'].default_value = 0.5 - - # Invert (for roughness) - invert = new_grp.nodes.new('ShaderNodeInvert') - invert.location = (-1256, 492) - invert.inputs[0].default_value = 1.0 - - # Gamma (for roughness) - gamma = new_grp.nodes.new('ShaderNodeGamma') - gamma.location = (-1256, 640) - gamma.inputs[1].default_value = 10.0 - - # Diffuse BSDF (Multiplies dynamic lighting with diffuse) - diffuse_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - diffuse_bdsf.location = (-945, 293) - - # Mix shader (interpolates Principled and Diffuse BSDF) - new_shader_model_mix1 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix1.location = (-760, 340) - - # Multiply (Multiples diffuse with diffusemod) - diffuse_mult = new_grp.nodes.new('ShaderNodeMixRGB') - diffuse_mult.location = (-1094, 122) - diffuse_mult.blend_type = 'MULTIPLY' - diffuse_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiples alpha with alphamod) - alpha_mult = new_grp.nodes.new('ShaderNodeMath') - alpha_mult.location = (-1094, -178) - alpha_mult.operation = 'MULTIPLY' - - # Multiply (Multiplies static lightmap with diffuse) - lightmap_mult = new_grp.nodes.new('ShaderNodeMixRGB') - lightmap_mult.location = (-944, 122) - lightmap_mult.blend_type = 'MULTIPLY' - lightmap_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies specular with reflection) - specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - specular_mult.location = (-940, -105) - specular_mult.blend_type = 'MULTIPLY' - specular_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies extended specular with reflection) - extended_specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - extended_specular_mult.location = (-941, -304) - extended_specular_mult.blend_type = 'MULTIPLY' - extended_specular_mult.inputs['Fac'].default_value = 1.0 - - # Add Shader (Adds dynamic diffuse with static diffuse) - diffuse_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - diffuse_add_shader.location = (-587, 209) - - # Mix shader (interpolates resolved reflection with nothing) - new_shader_model_mix2 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix2.location = (-512, -38) - - # Add Shader (Adds emissive with resolved reflection) - emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - emissive_add_shader.location = (-320, 8) - - # Add Shader (Adds specular and extended specular reflections) - specular_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - specular_add_shader.location = (-734, -81) - - # Diffuse BDSF (Multiplies extended specular with dynamic lighting) - extended_specular_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - extended_specular_bdsf.location = (-738, -280) - - # Add shader (Adds diffuse with all emissive sources) - final_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - final_add_shader.location = (-184, 234) - - # Transparent BDSF (Provides alpha) - transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent') - transparent_bdsf.location = (-224, -160) - transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0) - - # Mix Shader (Applies alpha proportion) - alpha_mix = new_grp.nodes.new('ShaderNodeMixShader') - alpha_mix.location = (-40, -112) - - # Group outputs (Final output) - mat_out = new_grp.nodes.new('NodeGroupOutput') - mat_out.location = (150, -88) - - # Links - new_grp.links.new(grp_in.outputs['Diffuse'], diffuse_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DiffuseMod'], diffuse_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Alpha'], alpha_mult.inputs[0]) - new_grp.links.new(grp_in.outputs['AlphaMod'], alpha_mult.inputs[1]) - new_grp.links.new(grp_in.outputs['Lightmap'], lightmap_mult.inputs['Color1']) - new_grp.links.new(diffuse_mult.outputs['Color'], lightmap_mult.inputs['Color2']) - new_grp.links.new(diffuse_mult.outputs['Color'], diffuse_bdsf.inputs['Color']) - new_grp.links.new(diffuse_mult.outputs['Color'], principled_bsdf.inputs['Base Color']) - new_grp.links.new(grp_in.outputs['Emissive'], emissive_add_shader.inputs[0]) - new_grp.links.new(grp_in.outputs['Specular'], specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Specular'], principled_bsdf.inputs['Specular']) - new_grp.links.new(grp_in.outputs['ExtendedSpecular'], extended_specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Reflection'], specular_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Reflection'], extended_specular_mult.inputs['Color2']) - new_grp.links.new(alpha_mult.outputs[0], alpha_mix.inputs['Fac']) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix1.inputs[0]) - new_grp.links.new(diffuse_bdsf.outputs['BSDF'], new_shader_model_mix1.inputs[1]) - new_grp.links.new(grp_in.outputs['Specular'], invert.inputs['Color']) - new_grp.links.new(invert.outputs['Color'], gamma.inputs['Color']) - new_grp.links.new(gamma.outputs['Color'], principled_bsdf.inputs['Roughness']) - new_grp.links.new(principled_bsdf.outputs['BSDF'], new_shader_model_mix1.inputs[2]) - new_grp.links.new(new_shader_model_mix1.outputs['Shader'], diffuse_add_shader.inputs[0]) - new_grp.links.new(lightmap_mult.outputs['Color'], diffuse_add_shader.inputs[1]) - new_grp.links.new(specular_mult.outputs['Color'], specular_add_shader.inputs[0]) - new_grp.links.new(extended_specular_mult.outputs['Color'], extended_specular_bdsf.inputs['Color']) - new_grp.links.new(extended_specular_bdsf.outputs['BSDF'], specular_add_shader.inputs[1]) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix2.inputs[0]) - new_grp.links.new(specular_add_shader.outputs['Shader'], new_shader_model_mix2.inputs[1]) - new_grp.links.new(new_shader_model_mix2.outputs['Shader'], emissive_add_shader.inputs[1]) - new_grp.links.new(diffuse_add_shader.outputs['Shader'], final_add_shader.inputs[0]) - new_grp.links.new(emissive_add_shader.outputs['Shader'], final_add_shader.inputs[1]) - new_grp.links.new(transparent_bdsf.outputs['BSDF'], alpha_mix.inputs[1]) - new_grp.links.new(final_add_shader.outputs['Shader'], alpha_mix.inputs[2]) - new_grp.links.new(alpha_mix.outputs['Shader'], mat_out.inputs['Surface']) - - -def make_retro_dynamic_shader(): - new_grp = bpy.data.node_groups.new('RetroDynamicShader', 'ShaderNodeTree') - surface_output = new_grp.outputs.new('NodeSocketShader', 'Surface') - lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap') - lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0) - diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse') - diffuse_input.default_value = (0.0, 0.0, 0.0, 0.0) - emissive_input = new_grp.inputs.new('NodeSocketColor', 'Emissive') - emissive_input.default_value = (0.0, 0.0, 0.0, 0.0) - specular_input = new_grp.inputs.new('NodeSocketColor', 'Specular') - specular_input.default_value = (0.0, 0.0, 0.0, 0.0) - ext_spec_input = new_grp.inputs.new('NodeSocketColor', 'ExtendedSpecular') - ext_spec_input.default_value = (0.0, 0.0, 0.0, 0.0) - reflection_input = new_grp.inputs.new('NodeSocketColor', 'Reflection') - reflection_input.default_value = (0.0, 0.0, 0.0, 0.0) - indirect_tex = new_grp.inputs.new('NodeSocketColor', 'IndirectTex') - indirect_tex.default_value = (0.0, 0.0, 0.0, 0.0) - alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'Alpha') - alpha_input.default_value = 1.0 - alpha_input.min_value = 0.0 - alpha_input.max_value = 1.0 - dynamic_input = new_grp.inputs.new('NodeSocketColor', 'DynamicTest') - dynamic_input.default_value = (1.0, 1.0, 1.0, 1.0) - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-1460, 27) - - # Multiply (Lightmap dynamic) - lightmap_dynamic = new_grp.nodes.new('ShaderNodeMixRGB') - lightmap_dynamic.location = (-1174, 158) - lightmap_dynamic.blend_type = 'MULTIPLY' - lightmap_dynamic.inputs['Fac'].default_value = 1.0 - - # Multiply (Diffuse dynamic) - diffuse_dynamic = new_grp.nodes.new('ShaderNodeMixRGB') - diffuse_dynamic.location = (-1174, -32) - diffuse_dynamic.blend_type = 'MULTIPLY' - diffuse_dynamic.inputs['Fac'].default_value = 1.0 - - # Multiply (Emissive dynamic) - emissive_dynamic = new_grp.nodes.new('ShaderNodeMixRGB') - emissive_dynamic.location = (-1174, -222) - emissive_dynamic.blend_type = 'MULTIPLY' - emissive_dynamic.inputs['Fac'].default_value = 1.0 - - # New shader model - new_shader_model = new_grp.nodes.new('ShaderNodeValue') - new_shader_model.name = 'NewShaderModel' - new_shader_model.label = 'NewShaderModel' - new_shader_model.location = (-1460, 118) - new_shader_model.outputs[0].default_value = 0.0 - - # Principled BSDF (For new shader model) - principled_bsdf = new_grp.nodes.new('ShaderNodeBsdfPrincipled') - principled_bsdf.location = (-1038, 874) - principled_bsdf.inputs['Metallic'].default_value = 0.5 - - # Invert (for roughness) - invert = new_grp.nodes.new('ShaderNodeInvert') - invert.location = (-1256, 492) - invert.inputs[0].default_value = 1.0 - - # Gamma (for roughness) - gamma = new_grp.nodes.new('ShaderNodeGamma') - gamma.location = (-1256, 640) - gamma.inputs[1].default_value = 10.0 - - # Diffuse BSDF (Multiplies dynamic lighting with diffuse) - diffuse_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - diffuse_bdsf.location = (-945, 293) - - # Mix shader (interpolates Principled and Diffuse BSDF) - new_shader_model_mix1 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix1.location = (-760, 340) - - # Multiply (Multiplies static lightmap with diffuse) - lightmap_mult = new_grp.nodes.new('ShaderNodeMixRGB') - lightmap_mult.location = (-944, 122) - lightmap_mult.blend_type = 'MULTIPLY' - lightmap_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies specular with reflection) - specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - specular_mult.location = (-940, -105) - specular_mult.blend_type = 'MULTIPLY' - specular_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies extended specular with reflection) - extended_specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - extended_specular_mult.location = (-941, -304) - extended_specular_mult.blend_type = 'MULTIPLY' - extended_specular_mult.inputs['Fac'].default_value = 1.0 - - # Add Shader (Adds dynamic diffuse with static diffuse) - diffuse_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - diffuse_add_shader.location = (-587, 209) - - # Mix shader (interpolates resolved reflection with nothing) - new_shader_model_mix2 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix2.location = (-512, -38) - - # Add Shader (Adds emissive with resolved reflection) - emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - emissive_add_shader.location = (-320, 8) - - # Add Shader (Adds specular and extended specular reflections) - specular_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - specular_add_shader.location = (-734, -81) - - # Diffuse BDSF (Multiplies extended specular with dynamic lighting) - extended_specular_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - extended_specular_bdsf.location = (-738, -280) - - # Add shader (Adds diffuse with all emissive sources) - final_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - final_add_shader.location = (-184, 234) - - # Transparent BDSF (Provides alpha) - transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent') - transparent_bdsf.location = (-224, -160) - transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0) - - # Mix Shader (Applies alpha proportion) - alpha_mix = new_grp.nodes.new('ShaderNodeMixShader') - alpha_mix.location = (-40, -112) - - # Group outputs (Final output) - mat_out = new_grp.nodes.new('NodeGroupOutput') - mat_out.location = (150, -88) - - # Links - new_grp.links.new(grp_in.outputs['Lightmap'], lightmap_dynamic.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DynamicTest'], lightmap_dynamic.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Diffuse'], diffuse_dynamic.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DynamicTest'], diffuse_dynamic.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Emissive'], emissive_dynamic.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DynamicTest'], emissive_dynamic.inputs['Color2']) - new_grp.links.new(lightmap_dynamic.outputs['Color'], lightmap_mult.inputs['Color1']) - new_grp.links.new(diffuse_dynamic.outputs['Color'], lightmap_mult.inputs['Color2']) - new_grp.links.new(diffuse_dynamic.outputs['Color'], diffuse_bdsf.inputs['Color']) - new_grp.links.new(diffuse_dynamic.outputs['Color'], principled_bsdf.inputs['Base Color']) - new_grp.links.new(emissive_dynamic.outputs['Color'], emissive_add_shader.inputs[0]) - new_grp.links.new(grp_in.outputs['Specular'], specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Specular'], principled_bsdf.inputs['Specular']) - new_grp.links.new(grp_in.outputs['ExtendedSpecular'], extended_specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Reflection'], specular_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Reflection'], extended_specular_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Alpha'], alpha_mix.inputs['Fac']) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix1.inputs[0]) - new_grp.links.new(diffuse_bdsf.outputs['BSDF'], new_shader_model_mix1.inputs[1]) - new_grp.links.new(grp_in.outputs['Specular'], invert.inputs['Color']) - new_grp.links.new(invert.outputs['Color'], gamma.inputs['Color']) - new_grp.links.new(gamma.outputs['Color'], principled_bsdf.inputs['Roughness']) - new_grp.links.new(principled_bsdf.outputs['BSDF'], new_shader_model_mix1.inputs[2]) - new_grp.links.new(new_shader_model_mix1.outputs['Shader'], diffuse_add_shader.inputs[0]) - new_grp.links.new(lightmap_mult.outputs['Color'], diffuse_add_shader.inputs[1]) - new_grp.links.new(specular_mult.outputs['Color'], specular_add_shader.inputs[0]) - new_grp.links.new(extended_specular_mult.outputs['Color'], extended_specular_bdsf.inputs['Color']) - new_grp.links.new(extended_specular_bdsf.outputs['BSDF'], specular_add_shader.inputs[1]) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix2.inputs[0]) - new_grp.links.new(specular_add_shader.outputs['Shader'], new_shader_model_mix2.inputs[1]) - new_grp.links.new(new_shader_model_mix2.outputs['Shader'], emissive_add_shader.inputs[1]) - new_grp.links.new(diffuse_add_shader.outputs['Shader'], final_add_shader.inputs[0]) - new_grp.links.new(emissive_add_shader.outputs['Shader'], final_add_shader.inputs[1]) - new_grp.links.new(transparent_bdsf.outputs['BSDF'], alpha_mix.inputs[1]) - new_grp.links.new(final_add_shader.outputs['Shader'], alpha_mix.inputs[2]) - new_grp.links.new(alpha_mix.outputs['Shader'], mat_out.inputs['Surface']) - - -def make_retro_dynamic_alpha_shader(): - new_grp = bpy.data.node_groups.new('RetroDynamicAlphaShader', 'ShaderNodeTree') - surface_output = new_grp.outputs.new('NodeSocketShader', 'Surface') - lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap') - lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0) - diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse') - diffuse_input.default_value = (0.0, 0.0, 0.0, 0.0) - emissive_input = new_grp.inputs.new('NodeSocketColor', 'Emissive') - emissive_input.default_value = (0.0, 0.0, 0.0, 0.0) - specular_input = new_grp.inputs.new('NodeSocketColor', 'Specular') - specular_input.default_value = (0.0, 0.0, 0.0, 0.0) - ext_spec_input = new_grp.inputs.new('NodeSocketColor', 'ExtendedSpecular') - ext_spec_input.default_value = (0.0, 0.0, 0.0, 0.0) - reflection_input = new_grp.inputs.new('NodeSocketColor', 'Reflection') - reflection_input.default_value = (0.0, 0.0, 0.0, 0.0) - indirect_tex = new_grp.inputs.new('NodeSocketColor', 'IndirectTex') - indirect_tex.default_value = (0.0, 0.0, 0.0, 0.0) - alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'Alpha') - alpha_input.default_value = 1.0 - alpha_input.min_value = 0.0 - alpha_input.max_value = 1.0 - dynamic_input = new_grp.inputs.new('NodeSocketColor', 'DynamicTest') - dynamic_input.default_value = (1.0, 1.0, 1.0, 1.0) - dynamic_alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'DynamicAlphaTest') - dynamic_alpha_input.default_value = 1.0 - dynamic_alpha_input.min_value = 0.0 - dynamic_alpha_input.max_value = 1.0 - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-1460, 27) - - # Multiply (Lightmap dynamic) - lightmap_dynamic = new_grp.nodes.new('ShaderNodeMixRGB') - lightmap_dynamic.location = (-1174, 158) - lightmap_dynamic.blend_type = 'MULTIPLY' - lightmap_dynamic.inputs['Fac'].default_value = 1.0 - - # Multiply (Diffuse dynamic) - diffuse_dynamic = new_grp.nodes.new('ShaderNodeMixRGB') - diffuse_dynamic.location = (-1174, -32) - diffuse_dynamic.blend_type = 'MULTIPLY' - diffuse_dynamic.inputs['Fac'].default_value = 1.0 - - # Multiply (Emissive dynamic) - emissive_dynamic = new_grp.nodes.new('ShaderNodeMixRGB') - emissive_dynamic.location = (-1174, -222) - emissive_dynamic.blend_type = 'MULTIPLY' - emissive_dynamic.inputs['Fac'].default_value = 1.0 - - # Multiply (Alpha dynamic) - alpha_dynamic = new_grp.nodes.new('ShaderNodeMath') - alpha_dynamic.location = (-1174, -410) - alpha_dynamic.operation = 'MULTIPLY' - - # New shader model - new_shader_model = new_grp.nodes.new('ShaderNodeValue') - new_shader_model.name = 'NewShaderModel' - new_shader_model.label = 'NewShaderModel' - new_shader_model.location = (-1460, 118) - new_shader_model.outputs[0].default_value = 0.0 - - # Principled BSDF (For new shader model) - principled_bsdf = new_grp.nodes.new('ShaderNodeBsdfPrincipled') - principled_bsdf.location = (-1038, 874) - principled_bsdf.inputs['Metallic'].default_value = 0.5 - - # Invert (for roughness) - invert = new_grp.nodes.new('ShaderNodeInvert') - invert.location = (-1256, 492) - invert.inputs[0].default_value = 1.0 - - # Gamma (for roughness) - gamma = new_grp.nodes.new('ShaderNodeGamma') - gamma.location = (-1256, 640) - gamma.inputs[1].default_value = 10.0 - - # Diffuse BSDF (Multiplies dynamic lighting with diffuse) - diffuse_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - diffuse_bdsf.location = (-945, 293) - - # Mix shader (interpolates Principled and Diffuse BSDF) - new_shader_model_mix1 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix1.location = (-760, 340) - - # Multiply (Multiplies static lightmap with diffuse) - lightmap_mult = new_grp.nodes.new('ShaderNodeMixRGB') - lightmap_mult.location = (-944, 122) - lightmap_mult.blend_type = 'MULTIPLY' - lightmap_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies specular with reflection) - specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - specular_mult.location = (-940, -105) - specular_mult.blend_type = 'MULTIPLY' - specular_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies extended specular with reflection) - extended_specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - extended_specular_mult.location = (-941, -304) - extended_specular_mult.blend_type = 'MULTIPLY' - extended_specular_mult.inputs['Fac'].default_value = 1.0 - - # Add Shader (Adds dynamic diffuse with static diffuse) - diffuse_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - diffuse_add_shader.location = (-587, 209) - - # Mix shader (interpolates resolved reflection with nothing) - new_shader_model_mix2 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix2.location = (-512, -38) - - # Add Shader (Adds emissive with resolved reflection) - emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - emissive_add_shader.location = (-320, 8) - - # Add Shader (Adds specular and extended specular reflections) - specular_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - specular_add_shader.location = (-734, -81) - - # Diffuse BDSF (Multiplies extended specular with dynamic lighting) - extended_specular_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - extended_specular_bdsf.location = (-738, -280) - - # Add shader (Adds diffuse with all emissive sources) - final_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - final_add_shader.location = (-184, 234) - - # Transparent BDSF (Provides alpha) - transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent') - transparent_bdsf.location = (-224, -160) - transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0) - - # Mix Shader (Applies alpha proportion) - alpha_mix = new_grp.nodes.new('ShaderNodeMixShader') - alpha_mix.location = (-40, -112) - - # Material Output (Final output) - mat_out = new_grp.nodes.new('NodeGroupOutput') - mat_out.location = (150, -88) - - # Links - new_grp.links.new(grp_in.outputs['Lightmap'], lightmap_dynamic.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DynamicTest'], lightmap_dynamic.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Diffuse'], diffuse_dynamic.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DynamicTest'], diffuse_dynamic.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Emissive'], emissive_dynamic.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DynamicTest'], emissive_dynamic.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Alpha'], alpha_dynamic.inputs[0]) - new_grp.links.new(grp_in.outputs['DynamicAlphaTest'], alpha_dynamic.inputs[1]) - new_grp.links.new(lightmap_dynamic.outputs['Color'], lightmap_mult.inputs['Color1']) - new_grp.links.new(diffuse_dynamic.outputs['Color'], lightmap_mult.inputs['Color2']) - new_grp.links.new(diffuse_dynamic.outputs['Color'], diffuse_bdsf.inputs['Color']) - new_grp.links.new(diffuse_dynamic.outputs['Color'], principled_bsdf.inputs['Base Color']) - new_grp.links.new(emissive_dynamic.outputs['Color'], emissive_add_shader.inputs[0]) - new_grp.links.new(grp_in.outputs['Specular'], specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Specular'], principled_bsdf.inputs['Specular']) - new_grp.links.new(grp_in.outputs['ExtendedSpecular'], extended_specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Reflection'], specular_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Reflection'], extended_specular_mult.inputs['Color2']) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix1.inputs[0]) - new_grp.links.new(diffuse_bdsf.outputs['BSDF'], new_shader_model_mix1.inputs[1]) - new_grp.links.new(grp_in.outputs['Specular'], invert.inputs['Color']) - new_grp.links.new(invert.outputs['Color'], gamma.inputs['Color']) - new_grp.links.new(gamma.outputs['Color'], principled_bsdf.inputs['Roughness']) - new_grp.links.new(principled_bsdf.outputs['BSDF'], new_shader_model_mix1.inputs[2]) - new_grp.links.new(new_shader_model_mix1.outputs['Shader'], diffuse_add_shader.inputs[0]) - new_grp.links.new(alpha_dynamic.outputs['Value'], alpha_mix.inputs['Fac']) - new_grp.links.new(lightmap_mult.outputs['Color'], diffuse_add_shader.inputs[1]) - new_grp.links.new(specular_mult.outputs['Color'], specular_add_shader.inputs[0]) - new_grp.links.new(extended_specular_mult.outputs['Color'], extended_specular_bdsf.inputs['Color']) - new_grp.links.new(extended_specular_bdsf.outputs['BSDF'], specular_add_shader.inputs[1]) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix2.inputs[0]) - new_grp.links.new(specular_add_shader.outputs['Shader'], new_shader_model_mix2.inputs[1]) - new_grp.links.new(new_shader_model_mix2.outputs['Shader'], emissive_add_shader.inputs[1]) - new_grp.links.new(diffuse_add_shader.outputs['Shader'], final_add_shader.inputs[0]) - new_grp.links.new(emissive_add_shader.outputs['Shader'], final_add_shader.inputs[1]) - new_grp.links.new(transparent_bdsf.outputs['BSDF'], alpha_mix.inputs[1]) - new_grp.links.new(final_add_shader.outputs['Shader'], alpha_mix.inputs[2]) - new_grp.links.new(alpha_mix.outputs['Shader'], mat_out.inputs['Surface']) - - -def make_retro_dynamic_character_shader(): - new_grp = bpy.data.node_groups.new('RetroDynamicCharacterShader', 'ShaderNodeTree') - surface_output = new_grp.outputs.new('NodeSocketShader', 'Surface') - lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap') - lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0) - diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse') - diffuse_input.default_value = (0.0, 0.0, 0.0, 0.0) - emissive_input = new_grp.inputs.new('NodeSocketColor', 'Emissive') - emissive_input.default_value = (0.0, 0.0, 0.0, 0.0) - specular_input = new_grp.inputs.new('NodeSocketColor', 'Specular') - specular_input.default_value = (0.0, 0.0, 0.0, 0.0) - ext_spec_input = new_grp.inputs.new('NodeSocketColor', 'ExtendedSpecular') - ext_spec_input.default_value = (0.0, 0.0, 0.0, 0.0) - reflection_input = new_grp.inputs.new('NodeSocketColor', 'Reflection') - reflection_input.default_value = (0.0, 0.0, 0.0, 0.0) - indirect_tex = new_grp.inputs.new('NodeSocketColor', 'IndirectTex') - indirect_tex.default_value = (0.0, 0.0, 0.0, 0.0) - alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'Alpha') - alpha_input.default_value = 1.0 - alpha_input.min_value = 0.0 - alpha_input.max_value = 1.0 - dynamic_input = new_grp.inputs.new('NodeSocketColor', 'DynamicTest') - dynamic_input.default_value = (1.0, 1.0, 1.0, 1.0) - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-1460, 27) - - # Multiply (Emissive dynamic) - emissive_dynamic = new_grp.nodes.new('ShaderNodeMixRGB') - emissive_dynamic.location = (-1174, -32) - emissive_dynamic.blend_type = 'MULTIPLY' - emissive_dynamic.inputs['Fac'].default_value = 1.0 - - # New shader model - new_shader_model = new_grp.nodes.new('ShaderNodeValue') - new_shader_model.name = 'NewShaderModel' - new_shader_model.label = 'NewShaderModel' - new_shader_model.location = (-1460, 118) - new_shader_model.outputs[0].default_value = 0.0 - - # Principled BSDF (For new shader model) - principled_bsdf = new_grp.nodes.new('ShaderNodeBsdfPrincipled') - principled_bsdf.location = (-1038, 874) - principled_bsdf.inputs['Metallic'].default_value = 0.5 - - # Invert (for roughness) - invert = new_grp.nodes.new('ShaderNodeInvert') - invert.location = (-1256, 492) - invert.inputs[0].default_value = 1.0 - - # Gamma (for roughness) - gamma = new_grp.nodes.new('ShaderNodeGamma') - gamma.location = (-1256, 640) - gamma.inputs[1].default_value = 10.0 - - # Diffuse BSDF (Multiplies dynamic lighting with diffuse) - diffuse_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - diffuse_bdsf.location = (-945, 293) - - # Mix shader (interpolates Principled and Diffuse BSDF) - new_shader_model_mix1 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix1.location = (-760, 340) - - # Multiply (Multiplies static lightmap with diffuse) - lightmap_mult = new_grp.nodes.new('ShaderNodeMixRGB') - lightmap_mult.location = (-944, 122) - lightmap_mult.blend_type = 'MULTIPLY' - lightmap_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies specular with reflection) - specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - specular_mult.location = (-940, -105) - specular_mult.blend_type = 'MULTIPLY' - specular_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies extended specular with reflection) - extended_specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - extended_specular_mult.location = (-941, -304) - extended_specular_mult.blend_type = 'MULTIPLY' - extended_specular_mult.inputs['Fac'].default_value = 1.0 - - # Add Shader (Adds dynamic diffuse with static diffuse) - diffuse_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - diffuse_add_shader.location = (-587, 209) - - # Mix shader (interpolates resolved reflection with nothing) - new_shader_model_mix2 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix2.location = (-512, -38) - - # Add Shader (Adds emissive with resolved reflection) - emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - emissive_add_shader.location = (-320, 8) - - # Add Shader (Adds specular and extended specular reflections) - specular_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - specular_add_shader.location = (-734, -81) - - # Diffuse BDSF (Multiplies extended specular with dynamic lighting) - extended_specular_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - extended_specular_bdsf.location = (-738, -280) - - # Add shader (Adds diffuse with all emissive sources) - final_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - final_add_shader.location = (-184, 234) - - # Transparent BDSF (Provides alpha) - transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent') - transparent_bdsf.location = (-224, -160) - transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0) - - # Mix Shader (Applies alpha proportion) - alpha_mix = new_grp.nodes.new('ShaderNodeMixShader') - alpha_mix.location = (-40, -112) - - # Material Output (Final output) - mat_out = new_grp.nodes.new('NodeGroupOutput') - mat_out.location = (150, -88) - - # Links - new_grp.links.new(grp_in.outputs['Emissive'], emissive_dynamic.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DynamicTest'], emissive_dynamic.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Lightmap'], lightmap_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Diffuse'], lightmap_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Diffuse'], diffuse_bdsf.inputs['Color']) - new_grp.links.new(grp_in.outputs['Diffuse'], principled_bsdf.inputs['Base Color']) - new_grp.links.new(emissive_dynamic.outputs['Color'], emissive_add_shader.inputs[0]) - new_grp.links.new(grp_in.outputs['Specular'], specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Specular'], principled_bsdf.inputs['Specular']) - new_grp.links.new(grp_in.outputs['ExtendedSpecular'], extended_specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Reflection'], specular_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Reflection'], extended_specular_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Alpha'], alpha_mix.inputs['Fac']) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix1.inputs[0]) - new_grp.links.new(diffuse_bdsf.outputs['BSDF'], new_shader_model_mix1.inputs[1]) - new_grp.links.new(grp_in.outputs['Specular'], invert.inputs['Color']) - new_grp.links.new(invert.outputs['Color'], gamma.inputs['Color']) - new_grp.links.new(gamma.outputs['Color'], principled_bsdf.inputs['Roughness']) - new_grp.links.new(principled_bsdf.outputs['BSDF'], new_shader_model_mix1.inputs[2]) - new_grp.links.new(new_shader_model_mix1.outputs['Shader'], diffuse_add_shader.inputs[0]) - new_grp.links.new(lightmap_mult.outputs['Color'], diffuse_add_shader.inputs[1]) - new_grp.links.new(specular_mult.outputs['Color'], specular_add_shader.inputs[0]) - new_grp.links.new(extended_specular_mult.outputs['Color'], extended_specular_bdsf.inputs['Color']) - new_grp.links.new(extended_specular_bdsf.outputs['BSDF'], specular_add_shader.inputs[1]) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix2.inputs[0]) - new_grp.links.new(specular_add_shader.outputs['Shader'], new_shader_model_mix2.inputs[1]) - new_grp.links.new(new_shader_model_mix2.outputs['Shader'], emissive_add_shader.inputs[1]) - new_grp.links.new(diffuse_add_shader.outputs['Shader'], final_add_shader.inputs[0]) - new_grp.links.new(emissive_add_shader.outputs['Shader'], final_add_shader.inputs[1]) - new_grp.links.new(transparent_bdsf.outputs['BSDF'], alpha_mix.inputs[1]) - new_grp.links.new(final_add_shader.outputs['Shader'], alpha_mix.inputs[2]) - new_grp.links.new(alpha_mix.outputs['Shader'], mat_out.inputs['Surface']) - - -# MP3 / DKCR Material Passes: -# https://wiki.axiodl.com/w/Materials_(Metroid_Prime_3) - -def make_retro_shader_mp3_color(): - new_grp = bpy.data.node_groups.new("__RetroShaderMP3Color", "ShaderNodeTree") - new_grp.use_fake_user = True - input = new_grp.inputs.new("NodeSocketColor", "DIFFC") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketColor", "DIFBC") - input.default_value = (1.0, 1.0, 1.0, 1.0) - input = new_grp.inputs.new("NodeSocketColor", "CLRC") - input.default_value = (0.5, 0.5, 0.5, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "CLRA") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "TRAN") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "RFLDC") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "RFLDA") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "RFLV") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketColor", "LRLD") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketColor", "LURDC") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "LURDA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "INCAC") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketInt", "Add INCA") - input.default_value = 0 - input.min_value = 0 - input.max_value = 1 - input = new_grp.inputs.new("NodeSocketFloatFactor", "OPAC") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - new_grp.outputs.new("NodeSocketShader", "Shader") - nodes = {} - node = new_grp.nodes.new("ShaderNodeBsdfDiffuse") - node.name = "Diffuse BSDF.004" - nodes["Diffuse BSDF.004"] = node - node.label = "" - node.location = (-196.910400390625, -503.60546875) - node.inputs[0].default_value = (0.800000011920929, 0.800000011920929, 0.800000011920929, 1.0) - node.inputs[1].default_value = 0.0 - node.inputs[2].default_value = (0.0, 0.0, 0.0) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.009" - nodes["Add Shader.009"] = node - node.label = "" - node.location = (14.618888854980469, -571.516357421875) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.008" - nodes["Add Shader.008"] = node - node.label = "" - node.location = (6.4276123046875, -926.3602905273438) - node = new_grp.nodes.new("ShaderNodeBsdfDiffuse") - node.name = "Diffuse BSDF.005" - nodes["Diffuse BSDF.005"] = node - node.label = "" - node.location = (-189.85516357421875, -865.79345703125) - node.inputs[0].default_value = (0.800000011920929, 0.800000011920929, 0.800000011920929, 1.0) - node.inputs[1].default_value = 0.0 - node.inputs[2].default_value = (0.0, 0.0, 0.0) - node = new_grp.nodes.new("ShaderNodeMixRGB") - node.name = "Mix.005" - nodes["Mix.005"] = node - node.label = "" - node.location = (-190.5804901123047, -1017.0886840820312) - node.blend_type = "MULTIPLY" - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node = new_grp.nodes.new("ShaderNodeMixRGB") - node.name = "Mix.004" - nodes["Mix.004"] = node - node.label = "" - node.location = (-381.6676940917969, -870.815673828125) - node.blend_type = "MULTIPLY" - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.006" - nodes["Add Shader.006"] = node - node.label = "" - node.location = (220.7507781982422, -724.6066284179688) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.005" - nodes["Add Shader.005"] = node - node.label = "" - node.location = (218.0698699951172, -528.0934448242188) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.007" - nodes["Add Shader.007"] = node - node.label = "" - node.location = (388.0714416503906, -600.8295288085938) - node = new_grp.nodes.new("ShaderNodeMixRGB") - node.name = "Mix.002" - nodes["Mix.002"] = node - node.label = "" - node.location = (-192.1793212890625, -281.65264892578125) - node.blend_type = "MULTIPLY" - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.010" - nodes["Add Shader.010"] = node - node.label = "" - node.location = (522.2215576171875, -284.7532653808594) - node = new_grp.nodes.new("ShaderNodeMixRGB") - node.name = "Mix.001" - nodes["Mix.001"] = node - node.label = "" - node.location = (-198.2812957763672, -13.079503059387207) - node.blend_type = "MULTIPLY" - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node = new_grp.nodes.new("ShaderNodeBsdfDiffuse") - node.name = "Diffuse BSDF.001" - nodes["Diffuse BSDF.001"] = node - node.label = "" - node.location = (-200.4605255126953, 138.9542694091797) - node.inputs[0].default_value = (0.800000011920929, 0.800000011920929, 0.800000011920929, 1.0) - node.inputs[1].default_value = 0.0 - node.inputs[2].default_value = (0.0, 0.0, 0.0) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.001" - nodes["Add Shader.001"] = node - node.label = "" - node.location = (-14.161624908447266, 32.61324691772461) - node = new_grp.nodes.new("NodeGroupOutput") - node.name = "Group Output" - nodes["Group Output"] = node - node.label = "" - node.location = (948.8831176757812, -299.1160583496094) - node = new_grp.nodes.new("ShaderNodeBsdfTransparent") - node.name = "Transparent BSDF.001" - nodes["Transparent BSDF.001"] = node - node.label = "" - node.location = (604.5911254882812, -88.7776870727539) - node.inputs[0].default_value = (1.0, 1.0, 1.0, 1.0) - node = new_grp.nodes.new("ShaderNodeMixShader") - node.name = "Mix Shader" - nodes["Mix Shader"] = node - node.label = "" - node.location = (772.179443359375, -91.1546401977539) - node.inputs[0].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.012" - nodes["Add Shader.012"] = node - node.label = "" - node.location = (776.751953125, -432.8694152832031) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.011" - nodes["Add Shader.011"] = node - node.label = "" - node.location = (779.857177734375, -294.9550476074219) - node = new_grp.nodes.new("ShaderNodeMixRGB") - node.name = "Mix.006" - nodes["Mix.006"] = node - node.label = "" - node.location = (-192.534912109375, -643.984619140625) - node.blend_type = "MULTIPLY" - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node = new_grp.nodes.new("ShaderNodeMixRGB") - node.name = "Mix.003" - nodes["Mix.003"] = node - node.label = "" - node.location = (-374.2341003417969, -515.1140747070312) - node.blend_type = "MULTIPLY" - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node = new_grp.nodes.new("ShaderNodeMixRGB") - node.name = "Mix" - nodes["Mix"] = node - node.label = "" - node.location = (-500.3056640625, -114.82369995117188) - node.blend_type = "MULTIPLY" - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math" - nodes["Math"] = node - node.label = "" - node.location = (454.39404296875, 96.02081298828125) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math.001" - nodes["Math.001"] = node - node.label = "" - node.location = (619.3079223632812, 90.52423095703125) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math.002" - nodes["Math.002"] = node - node.label = "" - node.location = (785.3211059570312, 81.7295913696289) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeBsdfTransparent") - node.name = "Transparent BSDF" - nodes["Transparent BSDF"] = node - node.label = "" - node.location = (597.9944458007812, -480.7802734375) - node.inputs[0].default_value = (1.0, 1.0, 1.0, 1.0) - node = new_grp.nodes.new("NodeGroupInput") - node.name = "Group Input" - nodes["Group Input"] = node - node.label = "" - node.location = (-669.6587524414062, -193.9534149169922) - new_grp.links.new(nodes["Group Input"].outputs[0], nodes["Mix"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[1], nodes["Mix"].inputs[2]) - new_grp.links.new(nodes["Mix"].outputs[0], nodes["Mix.001"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[2], nodes["Mix.001"].inputs[2]) - new_grp.links.new(nodes["Mix.001"].outputs[0], nodes["Add Shader.001"].inputs[1]) - new_grp.links.new(nodes["Diffuse BSDF.001"].outputs[0], nodes["Add Shader.001"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[2], nodes["Diffuse BSDF.001"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[5], nodes["Mix.002"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[7], nodes["Mix.002"].inputs[2]) - new_grp.links.new(nodes["Mix.002"].outputs[0], nodes["Add Shader.005"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[5], nodes["Mix.003"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[8], nodes["Mix.003"].inputs[2]) - new_grp.links.new(nodes["Mix.003"].outputs[0], nodes["Diffuse BSDF.004"].inputs[0]) - new_grp.links.new(nodes["Diffuse BSDF.004"].outputs[0], nodes["Add Shader.009"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[5], nodes["Mix.004"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[10], nodes["Mix.004"].inputs[2]) - new_grp.links.new(nodes["Mix.004"].outputs[0], nodes["Diffuse BSDF.005"].inputs[0]) - new_grp.links.new(nodes["Diffuse BSDF.005"].outputs[0], nodes["Add Shader.008"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[9], nodes["Add Shader.006"].inputs[0]) - new_grp.links.new(nodes["Add Shader.005"].outputs[0], nodes["Add Shader.007"].inputs[0]) - new_grp.links.new(nodes["Add Shader.006"].outputs[0], nodes["Add Shader.007"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[10], nodes["Mix.005"].inputs[2]) - new_grp.links.new(nodes["Mix"].outputs[0], nodes["Mix.005"].inputs[1]) - new_grp.links.new(nodes["Add Shader.008"].outputs[0], nodes["Add Shader.006"].inputs[1]) - new_grp.links.new(nodes["Mix.005"].outputs[0], nodes["Add Shader.008"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[8], nodes["Mix.006"].inputs[2]) - new_grp.links.new(nodes["Mix"].outputs[0], nodes["Mix.006"].inputs[1]) - new_grp.links.new(nodes["Add Shader.009"].outputs[0], nodes["Add Shader.005"].inputs[1]) - new_grp.links.new(nodes["Mix.006"].outputs[0], nodes["Add Shader.009"].inputs[1]) - new_grp.links.new(nodes["Add Shader.007"].outputs[0], nodes["Add Shader.010"].inputs[1]) - new_grp.links.new(nodes["Add Shader.001"].outputs[0], nodes["Add Shader.010"].inputs[0]) - new_grp.links.new(nodes["Transparent BSDF"].outputs[0], nodes["Add Shader.012"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[11], nodes["Add Shader.012"].inputs[0]) - new_grp.links.new(nodes["Add Shader.012"].outputs[0], nodes["Add Shader.011"].inputs[1]) - new_grp.links.new(nodes["Add Shader.011"].outputs[0], nodes["Group Output"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[3], nodes["Math"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[13], nodes["Math"].inputs[1]) - new_grp.links.new(nodes["Math"].outputs[0], nodes["Math.001"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[4], nodes["Math.001"].inputs[1]) - new_grp.links.new(nodes["Math.001"].outputs[0], nodes["Math.002"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[6], nodes["Math.002"].inputs[0]) - new_grp.links.new(nodes["Math.002"].outputs[0], nodes["Mix Shader"].inputs[0]) - new_grp.links.new(nodes["Transparent BSDF.001"].outputs[0], nodes["Mix Shader"].inputs[1]) - new_grp.links.new(nodes["Add Shader.010"].outputs[0], nodes["Mix Shader"].inputs[2]) - new_grp.links.new(nodes["Mix Shader"].outputs[0], nodes["Add Shader.011"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[12], nodes["Transparent BSDF"].inputs[0]) - - -def make_retro_shader_mp3_bloom(): - new_grp = bpy.data.node_groups.new("__RetroShaderMP3Bloom", "ShaderNodeTree") - new_grp.use_fake_user = True - input = new_grp.inputs.new("NodeSocketFloatFactor", "DIFFA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "DIFBA") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOL") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOD") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLODB") - input.default_value = 0.5 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "TRAN") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "INCAA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BNIF") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOI") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOIB") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "OPAC") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketInt", "Add INCA") - input.default_value = 0 - input.min_value = 0 - input.max_value = 1 - new_grp.outputs.new("NodeSocketShader", "Shader") - nodes = {} - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math.003" - nodes["Math.003"] = node - node.label = "" - node.location = (-131.26889038085938, -228.6888885498047) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math" - nodes["Math"] = node - node.label = "" - node.location = (-501.6487731933594, -144.7719268798828) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math.002" - nodes["Math.002"] = node - node.label = "" - node.location = (-328.3370666503906, -209.53160095214844) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("NodeGroupOutput") - node.name = "Group Output" - nodes["Group Output"] = node - node.label = "" - node.location = (1109.7938232421875, -257.2006530761719) - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math.001" - nodes["Math.001"] = node - node.label = "" - node.location = (129.59579467773438, -299.0679626464844) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeBsdfDiffuse") - node.name = "Diffuse BSDF.002" - nodes["Diffuse BSDF.002"] = node - node.label = "" - node.location = (122.80331420898438, -150.7427520751953) - node.inputs[0].default_value = (0.800000011920929, 0.800000011920929, 0.800000011920929, 1.0) - node.inputs[1].default_value = 0.0 - node.inputs[2].default_value = (0.0, 0.0, 0.0) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.002" - nodes["Add Shader.002"] = node - node.label = "" - node.location = (312.7171325683594, -220.0266571044922) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.005" - nodes["Add Shader.005"] = node - node.label = "" - node.location = (-165.06072998046875, -549.3956298828125) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.006" - nodes["Add Shader.006"] = node - node.label = "" - node.location = (20.3157958984375, -545.8302612304688) - node = new_grp.nodes.new("ShaderNodeBsdfTransparent") - node.name = "Transparent BSDF.001" - nodes["Transparent BSDF.001"] = node - node.label = "" - node.location = (205.5854034423828, -558.1273803710938) - node.inputs[0].default_value = (1.0, 1.0, 1.0, 1.0) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.001" - nodes["Add Shader.001"] = node - node.label = "" - node.location = (399.876708984375, -533.2184448242188) - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math.004" - nodes["Math.004"] = node - node.label = "" - node.location = (-354.23876953125, -508.8504943847656) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader" - nodes["Add Shader"] = node - node.label = "" - node.location = (875.3080444335938, -248.47450256347656) - node = new_grp.nodes.new("ShaderNodeBsdfTransparent") - node.name = "Transparent BSDF" - nodes["Transparent BSDF"] = node - node.label = "" - node.location = (502.63671875, -341.6871032714844) - node.inputs[0].default_value = (1.0, 1.0, 1.0, 1.0) - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math.006" - nodes["Math.006"] = node - node.label = "" - node.location = (505.8763122558594, -171.7743377685547) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeMixShader") - node.name = "Mix Shader" - nodes["Mix Shader"] = node - node.label = "" - node.location = (682.0885620117188, -169.31057739257812) - node.inputs[0].default_value = 0.5 - node = new_grp.nodes.new("NodeGroupInput") - node.name = "Group Input" - nodes["Group Input"] = node - node.label = "" - node.location = (-669.6587524414062, -193.9534149169922) - new_grp.links.new(nodes["Group Input"].outputs[0], nodes["Math"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[1], nodes["Math"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[3], nodes["Math.002"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[4], nodes["Math.003"].inputs[1]) - new_grp.links.new(nodes["Math.002"].outputs[0], nodes["Math.003"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[2], nodes["Math.002"].inputs[0]) - new_grp.links.new(nodes["Math"].outputs[0], nodes["Math.001"].inputs[0]) - new_grp.links.new(nodes["Diffuse BSDF.002"].outputs[0], nodes["Add Shader.002"].inputs[0]) - new_grp.links.new(nodes["Math.001"].outputs[0], nodes["Add Shader.002"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[10], nodes["Math.006"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[5], nodes["Math.006"].inputs[0]) - new_grp.links.new(nodes["Math.006"].outputs[0], nodes["Mix Shader"].inputs[0]) - new_grp.links.new(nodes["Transparent BSDF"].outputs[0], nodes["Mix Shader"].inputs[1]) - new_grp.links.new(nodes["Transparent BSDF.001"].outputs[0], nodes["Add Shader.001"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[6], nodes["Math.004"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[7], nodes["Math.004"].inputs[1]) - new_grp.links.new(nodes["Math.003"].outputs[0], nodes["Math.001"].inputs[1]) - new_grp.links.new(nodes["Math.003"].outputs[0], nodes["Diffuse BSDF.002"].inputs[0]) - new_grp.links.new(nodes["Math.004"].outputs[0], nodes["Add Shader.005"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[8], nodes["Add Shader.005"].inputs[1]) - new_grp.links.new(nodes["Add Shader.005"].outputs[0], nodes["Add Shader.006"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[9], nodes["Add Shader.006"].inputs[1]) - new_grp.links.new(nodes["Add Shader.006"].outputs[0], nodes["Add Shader.001"].inputs[1]) - new_grp.links.new(nodes["Add Shader"].outputs[0], nodes["Group Output"].inputs[0]) - new_grp.links.new(nodes["Mix Shader"].outputs[0], nodes["Add Shader"].inputs[0]) - new_grp.links.new(nodes["Add Shader.002"].outputs[0], nodes["Mix Shader"].inputs[2]) - new_grp.links.new(nodes["Add Shader.001"].outputs[0], nodes["Add Shader"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[11], nodes["Transparent BSDF.001"].inputs[0]) - - -def make_retro_shader_mp3(): - new_grp = bpy.data.node_groups.new("RetroShaderMP3", "ShaderNodeTree") - new_grp.use_fake_user = True - input = new_grp.inputs.new("NodeSocketColor", "DIFFC") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "DIFFA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "DIFBC") - input.default_value = (1.0, 1.0, 1.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "DIFBA") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOL") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOD") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLODB") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "CLR") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "CLRA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "TRAN") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "RFLD") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "RFLDA") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "RFLV") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketColor", "LRLD") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketColor", "LURDC") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "LURDA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "INCAC") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "INCAA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketInt", "Add INCA") - input.default_value = 0 - input.min_value = 0 - input.max_value = 1 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BNIF") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOI") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOIB") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "OPAC") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "XRAYC") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "XRAYA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "XRBR") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - nodes = {} - node = new_grp.nodes.new("ShaderNodeMixShader") - node.name = "Mix Shader" - nodes["Mix Shader"] = node - node.label = "" - node.location = (-118.33348846435547, -291.9857482910156) - node.inputs[0].default_value = 0.0 - node = new_grp.nodes.new("ShaderNodeOutputMaterial") - node.name = "Material Output" - nodes["Material Output"] = node - node.label = "" - node.location = (81.25957489013672, -265.6065368652344) - node.inputs[2].default_value = (0.0, 0.0, 0.0) - node = new_grp.nodes.new("ShaderNodeGroup") - node.name = "Group.001" - nodes["Group.001"] = node - node.label = "" - node.location = (-358.6896057128906, -60.17391586303711) - node.node_tree = bpy.data.node_groups["__RetroShaderMP3Color"] - node.inputs[0].default_value = (1.0, 1.0, 1.0, 1.0) - node.inputs[1].default_value = (1.0, 1.0, 1.0, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[3].default_value = 0.5 - node.inputs[4].default_value = 0.5 - node.inputs[5].default_value = (0.0, 0.0, 0.0, 1.0) - node.inputs[6].default_value = 0.5 - node.inputs[7].default_value = (0.0, 0.0, 0.0, 1.0) - node.inputs[8].default_value = (0.0, 0.0, 0.0, 1.0) - node.inputs[9].default_value = (0.0, 0.0, 0.0, 1.0) - node.inputs[10].default_value = 0.0 - node.inputs[11].default_value = (0.0, 0.0, 0.0, 1.0) - node.inputs[12].default_value = 0 - node.inputs[13].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeGroup") - node.name = "Group" - nodes["Group"] = node - node.label = "" - node.location = (-356.9021301269531, -446.9474182128906) - node.node_tree = bpy.data.node_groups["__RetroShaderMP3Bloom"] - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = 1.0 - node.inputs[2].default_value = 0.0 - node.inputs[3].default_value = 0.0 - node.inputs[4].default_value = 0.5 - node.inputs[5].default_value = 0.5 - node.inputs[6].default_value = 0.0 - node.inputs[7].default_value = 0.0 - node.inputs[8].default_value = 0.0 - node.inputs[9].default_value = 0.0 - node.inputs[10].default_value = 0.5 - node.inputs[11].default_value = 0 - node = new_grp.nodes.new("NodeGroupInput") - node.name = "Group Input" - nodes["Group Input"] = node - node.label = "" - node.location = (-669.6587524414062, -193.9534149169922) - new_grp.links.new(nodes["Group Input"].outputs[0], nodes["Group.001"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[1], nodes["Group"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[3], nodes["Group"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[4], nodes["Group"].inputs[2]) - new_grp.links.new(nodes["Group Input"].outputs[5], nodes["Group"].inputs[3]) - new_grp.links.new(nodes["Group Input"].outputs[6], nodes["Group"].inputs[4]) - new_grp.links.new(nodes["Group Input"].outputs[17], nodes["Group"].inputs[6]) - new_grp.links.new(nodes["Group Input"].outputs[19], nodes["Group"].inputs[7]) - new_grp.links.new(nodes["Group Input"].outputs[20], nodes["Group"].inputs[8]) - new_grp.links.new(nodes["Group Input"].outputs[2], nodes["Group.001"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[7], nodes["Group.001"].inputs[2]) - new_grp.links.new(nodes["Group Input"].outputs[10], nodes["Group.001"].inputs[5]) - new_grp.links.new(nodes["Group Input"].outputs[12], nodes["Group.001"].inputs[7]) - new_grp.links.new(nodes["Group Input"].outputs[13], nodes["Group.001"].inputs[8]) - new_grp.links.new(nodes["Group Input"].outputs[14], nodes["Group.001"].inputs[9]) - new_grp.links.new(nodes["Group Input"].outputs[15], nodes["Group.001"].inputs[10]) - new_grp.links.new(nodes["Group Input"].outputs[16], nodes["Group.001"].inputs[11]) - new_grp.links.new(nodes["Group.001"].outputs[0], nodes["Mix Shader"].inputs[1]) - new_grp.links.new(nodes["Group"].outputs[0], nodes["Mix Shader"].inputs[2]) - new_grp.links.new(nodes["Mix Shader"].outputs[0], nodes["Material Output"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[21], nodes["Group"].inputs[9]) - new_grp.links.new(nodes["Group Input"].outputs[8], nodes["Group.001"].inputs[3]) - new_grp.links.new(nodes["Group Input"].outputs[9], nodes["Group.001"].inputs[4]) - new_grp.links.new(nodes["Group Input"].outputs[11], nodes["Group.001"].inputs[6]) - new_grp.links.new(nodes["Group Input"].outputs[22], nodes["Group.001"].inputs[13]) - new_grp.links.new(nodes["Group Input"].outputs[9], nodes["Group"].inputs[5]) - new_grp.links.new(nodes["Group Input"].outputs[22], nodes["Group"].inputs[10]) - new_grp.links.new(nodes["Group Input"].outputs[18], nodes["Group.001"].inputs[12]) - new_grp.links.new(nodes["Group Input"].outputs[18], nodes["Group"].inputs[11]) - - -ROOT_SHADER_GROUPS = ( - make_retro_shader, - make_retro_dynamic_shader, - make_retro_dynamic_alpha_shader, - make_retro_dynamic_character_shader, - make_retro_shader_mp3_color, - make_retro_shader_mp3_bloom, - make_retro_shader_mp3 -) - - -# UV animation nodes: -# https://wiki.axiodl.com/w/Materials_(Metroid_Prime)#UV_Animations - -# 0 - Modelview Inverse (zero translation) -def make_uva0(): - new_grp = bpy.data.node_groups.new('RetroUVMode0NodeN', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-100, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (1000, 0) - - # Vector Transform to bring world space into camera space - vec_xf = new_grp.nodes.new('ShaderNodeVectorTransform') - vec_xf.location = (100, 0) - vec_xf.vector_type = 'NORMAL' - vec_xf.convert_from = 'WORLD' - vec_xf.convert_to = 'CAMERA' - - # UV scale (to match GameCube's UV-coordinate space) - uv_scale = new_grp.nodes.new('ShaderNodeMapping') - uv_scale.location = (400, -400) - uv_scale.vector_type = 'TEXTURE' - uv_scale.inputs['Scale'].default_value = (2.0, 2.0, 0.0) - uv_scale.inputs['Location'].default_value = (1.0, 1.0, 0.0) - - # Links - new_grp.links.new(grp_in.outputs[0], vec_xf.inputs[0]) - new_grp.links.new(vec_xf.outputs[0], uv_scale.inputs[0]) - new_grp.links.new(uv_scale.outputs[0], grp_out.inputs[0]) - - -# 1 - Modelview Inverse -def make_uva1(): - new_grp = bpy.data.node_groups.new('RetroUVMode1NodeN', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-300, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (500, 0) - - # Links - new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0]) - - -# 2 - UV Scroll -def make_uva2(): - new_grp = bpy.data.node_groups.new('RetroUVMode2Node', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.inputs.new('NodeSocketVector', 'Offset') - new_grp.inputs.new('NodeSocketVector', 'Scale') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-457, 22) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (500, 0) - - # Mapping - mapping = new_grp.nodes.new('ShaderNodeMapping') - mapping.location = (-235, 125) - for drv in mapping.inputs['Scale'].driver_add('default_value'): - drv.driver.expression = 'frame/60' - - # Adder1 - adder1 = new_grp.nodes.new('ShaderNodeVectorMath') - adder1.operation = 'ADD' - adder1.location = (100, 0) - - # Adder2 - adder2 = new_grp.nodes.new('ShaderNodeVectorMath') - adder2.operation = 'ADD' - adder2.location = (100, 200) - - # Links - new_grp.links.new(grp_in.outputs[0], adder2.inputs[0]) - new_grp.links.new(grp_in.outputs[1], adder1.inputs[0]) - new_grp.links.new(grp_in.outputs[2], mapping.inputs[0]) - new_grp.links.new(mapping.outputs[0], adder1.inputs[1]) - new_grp.links.new(adder1.outputs[0], adder2.inputs[1]) - new_grp.links.new(adder2.outputs[0], grp_out.inputs[0]) - - -# 3 - Rotation -def make_uva3(): - new_grp = bpy.data.node_groups.new('RetroUVMode3Node', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.inputs.new('NodeSocketFloat', 'Offset') - new_grp.inputs.new('NodeSocketFloat', 'Scale') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-100, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (700, 0) - - # Adder1 - add1 = new_grp.nodes.new('ShaderNodeMath') - add1.operation = 'ADD' - add1.location = (500, 0) - - # Multiply - mult = new_grp.nodes.new('ShaderNodeMath') - mult.operation = 'MULTIPLY' - mult.location = (230, -112) - drv = mult.inputs[1].driver_add('default_value') - drv.driver.expression = 'frame/60' - - # Links - new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0]) - new_grp.links.new(grp_in.outputs[1], add1.inputs[0]) - new_grp.links.new(grp_in.outputs[2], mult.inputs[0]) - new_grp.links.new(mult.outputs[0], add1.inputs[1]) - - -# 4 - Horizontal Filmstrip Animation -def make_uva4(): - new_grp = bpy.data.node_groups.new('RetroUVMode4Node', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.inputs.new('NodeSocketFloat', 'Scale') - new_grp.inputs.new('NodeSocketFloat', 'NumFrames') - new_grp.inputs.new('NodeSocketFloat', 'Step') - new_grp.inputs.new('NodeSocketFloat', 'Offset') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-1000, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (800, 0) - - # Multiply1 - mult1 = new_grp.nodes.new('ShaderNodeMath') - mult1.operation = 'MULTIPLY' - mult1.location = (-800, 0) - - # Multiply2 - mult2 = new_grp.nodes.new('ShaderNodeMath') - mult2.operation = 'MULTIPLY' - mult2.location = (-600, 0) - - # Modulo - mod1 = new_grp.nodes.new('ShaderNodeMath') - mod1.operation = 'MODULO' - mod1.inputs[1].default_value = 1.0 - mod1.location = (-400, 0) - - # Multiply3 - mult3 = new_grp.nodes.new('ShaderNodeMath') - mult3.operation = 'MULTIPLY' - mult3.location = (-200, 0) - - # Multiply4 - mult4 = new_grp.nodes.new('ShaderNodeMath') - mult4.operation = 'MULTIPLY' - mult4.location = (0, 0) - - # Mapping - map1 = new_grp.nodes.new('ShaderNodeMapping') - map1.inputs['Scale'].default_value = (1.0, 0.0, 0.0) - map1.location = (200, 0) - - # Add - add1 = new_grp.nodes.new('ShaderNodeVectorMath') - add1.operation = 'ADD' - add1.location = (600, 0) - - # Timing Add - time_add = new_grp.nodes.new('ShaderNodeMath') - time_add.operation = 'ADD' - time_add.location = (-802, -180) - drv = time_add.inputs[1].driver_add('default_value') - drv.driver.expression = 'frame/60' - - # Floor - floor = new_grp.nodes.new('ShaderNodeMath') - floor.operation = 'FLOOR' - floor.location = (-204, -180) - floor.inputs[1].default_value = 0.0 - - # Links - new_grp.links.new(grp_in.outputs[0], add1.inputs[1]) - new_grp.links.new(grp_in.outputs[1], mult1.inputs[1]) - new_grp.links.new(grp_in.outputs[2], mult3.inputs[1]) - new_grp.links.new(grp_in.outputs[3], mult4.inputs[1]) - new_grp.links.new(grp_in.outputs[3], mult1.inputs[0]) - new_grp.links.new(grp_in.outputs[4], time_add.inputs[0]) - new_grp.links.new(time_add.outputs[0], mult2.inputs[1]) - new_grp.links.new(mult1.outputs[0], mult2.inputs[0]) - new_grp.links.new(mult2.outputs[0], mod1.inputs[0]) - new_grp.links.new(mod1.outputs[0], mult3.inputs[0]) - new_grp.links.new(mult3.outputs[0], floor.inputs[0]) - new_grp.links.new(floor.outputs[0], mult4.inputs[0]) - new_grp.links.new(mult4.outputs[0], map1.inputs[0]) - new_grp.links.new(map1.outputs[0], add1.inputs[0]) - new_grp.links.new(add1.outputs[0], grp_out.inputs[0]) - - -# 5 - Vertical Filmstrip Animation -def make_uva5(): - new_grp = bpy.data.node_groups.new('RetroUVMode5Node', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.inputs.new('NodeSocketFloat', 'Scale') - new_grp.inputs.new('NodeSocketFloat', 'NumFrames') - new_grp.inputs.new('NodeSocketFloat', 'Step') - new_grp.inputs.new('NodeSocketFloat', 'Offset') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-1000, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (800, 0) - - # Multiply1 - mult1 = new_grp.nodes.new('ShaderNodeMath') - mult1.operation = 'MULTIPLY' - mult1.location = (-800, 0) - - # Multiply2 - mult2 = new_grp.nodes.new('ShaderNodeMath') - mult2.operation = 'MULTIPLY' - mult2.location = (-600, 0) - - # Modulo - mod1 = new_grp.nodes.new('ShaderNodeMath') - mod1.operation = 'MODULO' - mod1.inputs[1].default_value = 1.0 - mod1.location = (-400, 0) - - # Multiply3 - mult3 = new_grp.nodes.new('ShaderNodeMath') - mult3.operation = 'MULTIPLY' - mult3.location = (-200, 0) - - # Multiply4 - mult4 = new_grp.nodes.new('ShaderNodeMath') - mult4.operation = 'MULTIPLY' - mult4.location = (0, 0) - - # Mapping - map1 = new_grp.nodes.new('ShaderNodeMapping') - map1.inputs['Scale'].default_value = (0.0, 1.0, 0.0) - map1.location = (200, 0) - - # Add - add1 = new_grp.nodes.new('ShaderNodeVectorMath') - add1.operation = 'ADD' - add1.location = (600, 0) - - # Timing Add - time_add = new_grp.nodes.new('ShaderNodeMath') - time_add.operation = 'ADD' - time_add.location = (-802, -180) - drv = time_add.inputs[1].driver_add('default_value') - drv.driver.expression = 'frame/60' - - # Floor - floor = new_grp.nodes.new('ShaderNodeMath') - floor.operation = 'FLOOR' - floor.location = (-204, -180) - floor.inputs[1].default_value = 0.0 - - # Links - new_grp.links.new(grp_in.outputs[0], add1.inputs[1]) - new_grp.links.new(grp_in.outputs[1], mult1.inputs[1]) - new_grp.links.new(grp_in.outputs[2], mult3.inputs[1]) - new_grp.links.new(grp_in.outputs[3], mult4.inputs[1]) - new_grp.links.new(grp_in.outputs[3], mult1.inputs[0]) - new_grp.links.new(grp_in.outputs[4], time_add.inputs[0]) - new_grp.links.new(time_add.outputs[0], mult2.inputs[1]) - new_grp.links.new(mult1.outputs[0], mult2.inputs[0]) - new_grp.links.new(mult2.outputs[0], mod1.inputs[0]) - new_grp.links.new(mod1.outputs[0], mult3.inputs[0]) - new_grp.links.new(mult3.outputs[0], floor.inputs[0]) - new_grp.links.new(floor.outputs[0], mult4.inputs[0]) - new_grp.links.new(mult4.outputs[0], map1.inputs[0]) - new_grp.links.new(map1.outputs[0], add1.inputs[0]) - new_grp.links.new(add1.outputs[0], grp_out.inputs[0]) - - -# 6 - Model Matrix -def make_uva6(): - new_grp = bpy.data.node_groups.new('RetroUVMode6NodeN', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-100, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (300, 0) - - # Geometry input - geom_in = new_grp.nodes.new('ShaderNodeTexCoord') - geom_in.location = (-300, 0) - - # Adder1 - adder1 = new_grp.nodes.new('ShaderNodeVectorMath') - adder1.operation = 'ADD' - adder1.location = (100, 0) - - # Links - new_grp.links.new(grp_in.outputs[0], adder1.inputs[0]) - new_grp.links.new(geom_in.outputs['Object'], adder1.inputs[1]) - new_grp.links.new(adder1.outputs[0], grp_out.inputs[0]) - - -# 7 - Mode Who Must Not Be Named -def make_uva7(): - new_grp = bpy.data.node_groups.new('RetroUVMode7NodeN', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.inputs.new('NodeSocketFloat', 'ParamA') - new_grp.inputs.new('NodeSocketFloat', 'ParamB') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-800, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (0, 0) - - # Geometry input - geom_in = new_grp.nodes.new('ShaderNodeTexCoord') - geom_in.location = (-1000, 0) - - # View flip - view_flip = new_grp.nodes.new('ShaderNodeMapping') - view_flip.location = (-800, -150) - view_flip.vector_type = 'TEXTURE' - view_flip.inputs['Scale'].default_value = (-1.0, -1.0, 1.0) - - # Separate - sep1 = new_grp.nodes.new('ShaderNodeSeparateRGB') - sep1.location = (-400, -200) - - # Add1 - add1 = new_grp.nodes.new('ShaderNodeMath') - add1.operation = 'ADD' - add1.location = (-200, -200) - - # Multiply1 - mult1 = new_grp.nodes.new('ShaderNodeMath') - mult1.operation = 'MULTIPLY' - mult1.inputs[1].default_value = 0.025 - mult1.location = (0, -200) - - # Multiply2 - mult2 = new_grp.nodes.new('ShaderNodeMath') - mult2.operation = 'MULTIPLY' - mult2.location = (200, -200) - - # Multiply3 - mult3 = new_grp.nodes.new('ShaderNodeMath') - mult3.operation = 'MULTIPLY' - mult3.inputs[1].default_value = 0.05 - mult3.location = (0, -400) - - # Multiply4 - mult4 = new_grp.nodes.new('ShaderNodeMath') - mult4.operation = 'MULTIPLY' - mult4.location = (200, -400) - - # Combine1 - comb1 = new_grp.nodes.new('ShaderNodeCombineRGB') - comb1.location = (400, -300) - - # Combine2 - comb2 = new_grp.nodes.new('ShaderNodeCombineRGB') - comb2.location = (-600, 0) - - # Multiply5 - mult5 = new_grp.nodes.new('ShaderNodeMixRGB') - mult5.blend_type = 'MULTIPLY' - mult5.inputs[0].default_value = 1.0 - mult5.location = (-400, 0) - - # Add2 - add2 = new_grp.nodes.new('ShaderNodeVectorMath') - add2.operation = 'ADD' - add2.location = (-200, 0) - - # Links - new_grp.links.new(grp_in.outputs[0], add2.inputs[0]) - new_grp.links.new(geom_in.outputs['Window'], view_flip.inputs[0]) - new_grp.links.new(view_flip.outputs[0], sep1.inputs[0]) - new_grp.links.new(grp_in.outputs[1], comb2.inputs[0]) - new_grp.links.new(grp_in.outputs[1], comb2.inputs[1]) - new_grp.links.new(grp_in.outputs[1], comb2.inputs[2]) - new_grp.links.new(comb2.outputs[0], mult5.inputs[1]) - new_grp.links.new(grp_in.outputs[2], mult2.inputs[1]) - new_grp.links.new(grp_in.outputs[2], mult4.inputs[1]) - new_grp.links.new(sep1.outputs[0], add1.inputs[0]) - new_grp.links.new(sep1.outputs[1], add1.inputs[1]) - new_grp.links.new(sep1.outputs[2], mult3.inputs[0]) - new_grp.links.new(add1.outputs[0], mult1.inputs[0]) - new_grp.links.new(mult1.outputs[0], mult2.inputs[0]) - new_grp.links.new(mult2.outputs[0], comb1.inputs[0]) - new_grp.links.new(mult3.outputs[0], mult4.inputs[0]) - new_grp.links.new(mult4.outputs[0], comb1.inputs[1]) - new_grp.links.new(comb1.outputs[0], mult5.inputs[2]) - new_grp.links.new(mult5.outputs[0], add2.inputs[1]) - new_grp.links.new(add2.outputs[0], grp_out.inputs[0]) - - -# 8 - Mode 8 -def make_uva8(): - new_grp = bpy.data.node_groups.new('RetroUVMode8Node', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.inputs.new('NodeSocketFloat', 'Param1') - new_grp.inputs.new('NodeSocketFloat', 'Param2') - new_grp.inputs.new('NodeSocketFloat', 'Param3') - new_grp.inputs.new('NodeSocketFloat', 'Param4') - new_grp.inputs.new('NodeSocketFloat', 'Param5') - new_grp.inputs.new('NodeSocketFloat', 'Param6') - new_grp.inputs.new('NodeSocketFloat', 'Param7') - new_grp.inputs.new('NodeSocketFloat', 'Param8') - new_grp.inputs.new('NodeSocketFloat', 'Param9') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-800, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (0, 0) - - # Links - new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0]) - - -UV_ANIMATION_GROUPS = ( - make_uva0, - make_uva1, - make_uva2, - make_uva3, - make_uva4, - make_uva5, - make_uva6, - make_uva7, - make_uva8 -) - - -def make_master_shader_library(): - make_additive_output() - make_blend_opaque_output() - for shad in ROOT_SHADER_GROUPS: - shad() - for uva in UV_ANIMATION_GROUPS: - uva() diff --git a/DataSpec/CMakeLists.txt b/DataSpec/CMakeLists.txt deleted file mode 100644 index 54cbdd334..000000000 --- a/DataSpec/CMakeLists.txt +++ /dev/null @@ -1,91 +0,0 @@ -# Assembles a source/header pair list for use in a DNA library -macro(make_dnalist) - file(RELATIVE_PATH subdir "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_LIST_DIR}") - set(CMAKE_CURRENT_LIST_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/${subdir}") - file(MAKE_DIRECTORY "${CMAKE_CURRENT_LIST_BINARY_DIR}") - foreach (type ${ARGN}) - get_filename_component(dir ${type} DIRECTORY) - if (dir) - file(MAKE_DIRECTORY "${CMAKE_CURRENT_LIST_BINARY_DIR}/${dir}") - set(dir "${dir}/") - endif () - get_filename_component(name ${type} NAME) - list(APPEND DNA_SOURCES "${subdir}/${dir}atdna_${name}.cpp") - list(APPEND DNA_HEADERS "${subdir}/${dir}${name}.hpp") - endforeach () -endmacro() - -# Assembles source files together for the main DataSpecCommon library -macro(dataspec_add_list rel_path a_list) - unset(tmp_list) - foreach (path IN LISTS ${a_list}) - if (IS_ABSOLUTE ${path}) - list(APPEND tmp_list "${path}") - else () - list(APPEND tmp_list "${rel_path}/${path}") - endif () - endforeach (path) - set(${a_list} "${tmp_list}") -endmacro(dataspec_add_list) - -# Each game's DNA library -unset(DNA_SOURCES) -unset(DNA_HEADERS) -include(DNACommon/CMakeLists.txt) -include(DNAMP1/CMakeLists.txt) -include(DNAMP2/CMakeLists.txt) -include(DNAMP3/CMakeLists.txt) - -# Embed master shader script -bintoc(RetroMasterShader.cpp Blender/RetroMasterShader.py RETRO_MASTER_SHADER) - -# Download asset name databases -add_custom_command(OUTPUT AssetNameMap32.bin COMMAND ${CMAKE_COMMAND} ARGS -P - ${CMAKE_CURRENT_SOURCE_DIR}/AssetMap32Download.cmake) -bintoc_compress(AssetNameMap32.cpp ${CMAKE_CURRENT_BINARY_DIR}/AssetNameMap32.bin ASSET_NAME_MP32) - -add_custom_command(OUTPUT AssetNameMap64.bin COMMAND ${CMAKE_COMMAND} ARGS -P - ${CMAKE_CURRENT_SOURCE_DIR}/AssetMap64Download.cmake) -bintoc_compress(AssetNameMap64.cpp ${CMAKE_CURRENT_BINARY_DIR}/AssetNameMap64.bin ASSET_NAME_MP64) - -# Each game's DataSpec implementation -add_library(RetroDataSpec - SpecBase.cpp - ${DNACOMMON_SOURCES} - SpecMP1.cpp - ${DNAMP1_SOURCES} - ${ScriptObjectsMP1_SOURCES} - ${DNAMP1_SFX_SOURCES} - SpecMP2.cpp - ${DNAMP2_SOURCES} - SpecMP3.cpp - ${DNAMP3_SOURCES} - Blender/BlenderSupport.hpp - Blender/BlenderSupport.cpp - Blender/RetroMasterShader.py - AssetNameMap.hpp - AssetNameMap.cpp - RetroMasterShader.cpp) -add_library(AssetNameMap - AssetNameMap32.bin AssetNameMap32.cpp - AssetNameMap64.bin AssetNameMap64.cpp) -add_library(AssetNameMapNull - AssetNameMapNull.cpp) - -get_target_property(HECL_INCLUDES hecl-full INCLUDE_DIRECTORIES) -target_include_directories(RetroDataSpec PUBLIC ${HECL_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}) -target_link_libraries(RetroDataSpec PUBLIC amuse zeus nod squish ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} lzokay logvisor aurora xxhash) -if (COMMAND add_sanitizers) - add_sanitizers(RetroDataSpec) -endif () - -# Resolve all DNA sources into target -list(LENGTH DNA_SOURCES count) -math(EXPR count "${count}-1") -foreach (i RANGE ${count}) - list(GET DNA_SOURCES ${i} src) - list(GET DNA_HEADERS ${i} header) - target_atdna(RetroDataSpec ${src} ${header}) -endforeach () - -add_custom_target(genexdebug COMMAND ${CMAKE_COMMAND} -E echo "$") diff --git a/DataSpec/DNACommon/ANCS.cpp b/DataSpec/DNACommon/ANCS.cpp deleted file mode 100644 index 13e5f67f3..000000000 --- a/DataSpec/DNACommon/ANCS.cpp +++ /dev/null @@ -1,282 +0,0 @@ -#include "DataSpec/DNACommon/ANCS.hpp" - -#include "DataSpec/DNACommon/CMDL.hpp" -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/RigInverter.hpp" -#include "DataSpec/DNAMP1/DNAMP1.hpp" -#include "DataSpec/DNAMP1/ANCS.hpp" -#include "DataSpec/DNAMP2/DNAMP2.hpp" -#include "DataSpec/DNAMP2/ANCS.hpp" -#include "DataSpec/DNAMP3/DNAMP3.hpp" -#include "DataSpec/DNAMP3/CHAR.hpp" - -#include - -namespace DataSpec::DNAANCS { - -template -bool ReadANCSToBlender(hecl::blender::Token& btok, const ANCSDNA& ancs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const SpecBase& dataspec, - std::function fileChanged, bool force) { - auto& conn = btok.getBlenderConnection(); - /* Extract character CMDL/CSKR/CINF first */ - std::vector> chResInfo; - ancs.getCharacterResInfo(chResInfo); - for (const auto& info : chResInfo) { - const nod::Node* node; - if (const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, &node, true, false)) { - hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); - if (force || cmdlPath.isNone()) { - cmdlPath.makeDirChain(false); - if (!conn.createBlend(cmdlPath, hecl::blender::BlendType::Mesh)) - return false; - - std::string bestName = pakRouter.getBestEntryName(*cmdlE); - fileChanged(bestName.c_str()); - - typename ANCSDNA::CSKRType cskr; - pakRouter.lookupAndReadDNA(info.cskr, cskr); - typename ANCSDNA::CINFType cinf; - pakRouter.lookupAndReadDNA(info.cinf, cinf); - using RigPair = std::pair, - std::pair>; - RigPair rigPair({info.cskr, &cskr}, {info.cinf, &cinf}); - - PAKEntryReadStream rs = cmdlE->beginReadStream(*node); - DNACMDL::ReadCMDLToBlender( - conn, rs, pakRouter, *cmdlE, dataspec, rigPair); - - conn.saveBlend(); - } - } - if (const typename PAKRouter::EntryType* cinfE = pakRouter.lookupEntry(info.cinf, &node, true, false)) { - hecl::ProjectPath cinfPath = pakRouter.getWorking(cinfE); - if (cinfPath.getPathType() == hecl::ProjectPath::Type::None) { - PAKEntryReadStream rs = cinfE->beginReadStream(*node); - ANCSDNA::CINFType::Extract(dataspec, rs, cinfPath, pakRouter, *cinfE, false, btok, fileChanged); - } - } - } - - /* Extract attachment CMDL/CSKR/CINFs first */ - auto attRange = pakRouter.lookupCharacterAttachmentRigs(entry.id); - for (auto it = attRange.first; it != attRange.second; ++it) { - auto cinfid = it->second.first.cinf; - auto cmdlid = it->second.first.cmdl; - - const nod::Node* node; - if (const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(cmdlid, &node, true, false)) { - hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); - if (force || cmdlPath.isNone()) { - cmdlPath.makeDirChain(false); - if (!conn.createBlend(cmdlPath, hecl::blender::BlendType::Mesh)) { - return false; - } - - std::string bestName = pakRouter.getBestEntryName(*cmdlE); - fileChanged(bestName.c_str()); - - const auto* rp = pakRouter.lookupCMDLRigPair(cmdlid); - typename ANCSDNA::CSKRType cskr; - pakRouter.lookupAndReadDNA(rp->cskr, cskr); - typename ANCSDNA::CINFType cinf; - pakRouter.lookupAndReadDNA(rp->cinf, cinf); - using RigPair = std::pair, - std::pair>; - RigPair rigPair({rp->cskr, &cskr}, {rp->cinf, &cinf}); - - PAKEntryReadStream rs = cmdlE->beginReadStream(*node); - DNACMDL::ReadCMDLToBlender( - conn, rs, pakRouter, *cmdlE, dataspec, rigPair); - - conn.saveBlend(); - } - } - if (cinfid.isValid()) { - if (const typename PAKRouter::EntryType* cinfE = pakRouter.lookupEntry(cinfid, &node, true, false)) { - hecl::ProjectPath cinfPath = pakRouter.getWorking(cinfE); - if (cinfPath.getPathType() == hecl::ProjectPath::Type::None) { - PAKEntryReadStream rs = cinfE->beginReadStream(*node); - ANCSDNA::CINFType::Extract(dataspec, rs, cinfPath, pakRouter, *cinfE, false, btok, fileChanged); - } - } - } - } - - std::string bestName = pakRouter.getBestEntryName(entry); - fileChanged(bestName.c_str()); - - /* Establish ANCS blend */ - if (!conn.createBlend(outPath, hecl::blender::BlendType::Actor)) - return false; - - std::string firstName; - typename ANCSDNA::CINFType firstCinf; - { - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - - os.format(FMT_STRING("import bpy\n" - "from mathutils import Vector\n" - "bpy.context.scene.name = '{}'\n" - "bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n" - "\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "actor_data = bpy.context.scene.hecl_sact_data\n" - "arm_obj = None\n"), - pakRouter.getBestEntryName(entry)); - - std::unordered_set cinfsDone; - for (const auto& info : chResInfo) { - /* Provide data to add-on */ - os.format(FMT_STRING("actor_subtype = actor_data.subtypes.add()\n" - "actor_subtype.name = '{}'\n\n"), - info.name); - - /* Build CINF if needed */ - if (cinfsDone.find(info.cinf) == cinfsDone.end()) { - if (const typename PAKRouter::EntryType* cinfE = pakRouter.lookupEntry(info.cinf, nullptr, true, false)) { - hecl::ProjectPath cinfPath = pakRouter.getWorking(cinfE); - os.linkArmature(cinfPath.getAbsolutePath(), fmt::format(FMT_STRING("CINF_{}"), info.cinf)); - os << "if obj.name not in bpy.context.scene.objects:\n" - " bpy.context.scene.collection.objects.link(obj)\n"; - } - if (cinfsDone.empty()) { - firstName = ANCSDNA::CINFType::GetCINFArmatureName(info.cinf); - pakRouter.lookupAndReadDNA(info.cinf, firstCinf); - } - cinfsDone.insert(info.cinf); - } - os.format(FMT_STRING("arm_obj = bpy.data.objects['CINF_{}']\n"), info.cinf); - os << "actor_subtype.linked_armature = arm_obj.name\n"; - - /* Link CMDL */ - if (const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, nullptr, true, false)) { - hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); - os.linkMesh(cmdlPath.getAbsolutePath(), pakRouter.getBestEntryName(*cmdlE)); - - /* Attach CMDL to CINF */ - os << "if obj.name not in bpy.context.scene.objects:\n" - " bpy.context.scene.collection.objects.link(obj)\n" - "obj.parent = arm_obj\n" - "obj.parent_type = 'ARMATURE'\n" - "actor_subtype.linked_mesh = obj.name\n\n"; - } - - /* Link overlays */ - for (const auto& overlay : info.overlays) { - os << "overlay = actor_subtype.overlays.add()\n"; - os.format(FMT_STRING("overlay.name = '{}'\n"), overlay.first); - - /* Link CMDL */ - if (const typename PAKRouter::EntryType* cmdlE = - pakRouter.lookupEntry(overlay.second.first, nullptr, true, false)) { - hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); - os.linkMesh(cmdlPath.getAbsolutePath(), pakRouter.getBestEntryName(*cmdlE)); - - /* Attach CMDL to CINF */ - os << "if obj.name not in bpy.context.scene.objects:\n" - " bpy.context.scene.collection.objects.link(obj)\n" - "obj.parent = arm_obj\n" - "obj.parent_type = 'ARMATURE'\n" - "overlay.linked_mesh = obj.name\n\n"; - } - } - } - - /* Link attachments */ - for (auto it = attRange.first; it != attRange.second; ++it) { - os << "attachment = actor_data.attachments.add()\n"; - os.format(FMT_STRING("attachment.name = '{}'\n"), it->second.second); - - auto cinfid = it->second.first.cinf; - auto cmdlid = it->second.first.cmdl; - - if (cinfid.isValid()) { - /* Build CINF if needed */ - if (cinfsDone.find(cinfid) == cinfsDone.end()) { - if (const typename PAKRouter::EntryType* cinfE = pakRouter.lookupEntry(cinfid, nullptr, true, false)) { - hecl::ProjectPath cinfPath = pakRouter.getWorking(cinfE); - os.linkArmature(cinfPath.getAbsolutePath(), fmt::format(FMT_STRING("CINF_{}"), cinfid)); - os << "if obj.name not in bpy.context.scene.objects:\n" - " bpy.context.scene.collection.objects.link(obj)\n"; - } - if (cinfsDone.empty()) { - firstName = ANCSDNA::CINFType::GetCINFArmatureName(cinfid); - pakRouter.lookupAndReadDNA(cinfid, firstCinf); - } - cinfsDone.insert(cinfid); - } - os.format(FMT_STRING("arm_obj = bpy.data.objects['CINF_{}']\n"), cinfid); - os << "attachment.linked_armature = arm_obj.name\n"; - } - - /* Link CMDL */ - if (const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(cmdlid, nullptr, true, false)) { - hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); - os.linkMesh(cmdlPath.getAbsolutePath(), pakRouter.getBestEntryName(*cmdlE)); - - /* Attach CMDL to CINF */ - os << "if obj.name not in bpy.context.scene.objects:\n" - " bpy.context.scene.collection.objects.link(obj)\n" - "obj.parent = arm_obj\n" - "obj.parent_type = 'ARMATURE'\n" - "attachment.linked_mesh = obj.name\n\n"; - } - } - } - - { - hecl::blender::DataStream ds = conn.beginData(); - std::unordered_map matrices = ds.getBoneMatrices(firstName); - ds.close(); - DNAANIM::RigInverter inverter(firstCinf, matrices); - - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os << "import bpy\n" - "actor_data = bpy.context.scene.hecl_sact_data\n"; - - /* Get animation primitives */ - std::map> animResInfo; - ancs.getAnimationResInfo(&pakRouter, animResInfo); - for (const auto& id : animResInfo) { - typename ANCSDNA::ANIMType anim; - if (pakRouter.lookupAndReadDNA(id.second.animId, anim, true)) { - os.format(FMT_STRING("act = bpy.data.actions.new('{}')\n" - "act.use_fake_user = True\n" - "act.anim_id = '{}'\n"), - id.second.name, id.second.animId); - anim.sendANIMToBlender(os, inverter, id.second.additive); - } - - os.format(FMT_STRING("actor_action = actor_data.actions.add()\n" - "actor_action.name = '{}'\n"), - id.second.name); - - /* Extract EVNT if present */ - anim.extractEVNT(id.second, outPath, pakRouter, force); - } - } - conn.saveBlend(); - return true; -} - -template bool -ReadANCSToBlender, DNAMP1::ANCS, DNAMP1::MaterialSet, DNACMDL::SurfaceHeader_1, 2>( - hecl::blender::Token& btok, const DNAMP1::ANCS& ancs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, - const SpecBase& dataspec, std::function fileChanged, bool force); -template bool -ReadANCSToBlender, DNAMP2::ANCS, DNAMP2::MaterialSet, DNACMDL::SurfaceHeader_2, 4>( - hecl::blender::Token& btok, const DNAMP2::ANCS& ancs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, - const SpecBase& dataspec, std::function fileChanged, bool force); -template bool -ReadANCSToBlender, DNAMP3::CHAR, DNAMP3::MaterialSet, DNACMDL::SurfaceHeader_3, 4>( - hecl::blender::Token& btok, const DNAMP3::CHAR& ancs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, - const SpecBase& dataspec, std::function fileChanged, bool force); - -} // namespace DataSpec::DNAANCS diff --git a/DataSpec/DNACommon/ANCS.hpp b/DataSpec/DNACommon/ANCS.hpp deleted file mode 100644 index 48e89b69f..000000000 --- a/DataSpec/DNACommon/ANCS.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "athena/Types.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec { -struct SpecBase; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAANCS { - -using Actor = hecl::blender::Actor; -using Armature = Actor::ActorArmature; -using Action = hecl::blender::Action; - -template -struct CharacterResInfo { - std::string name; - IDTYPE cmdl; - IDTYPE cskr; - IDTYPE cinf; - std::vector>> overlays; -}; - -template -struct AnimationResInfo { - std::string name; - IDTYPE animId; - IDTYPE evntId; - bool additive; -}; - -template -bool ReadANCSToBlender(hecl::blender::Token& btok, const ANCSDNA& ancs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const SpecBase& dataspec, - std::function fileChanged, bool force = false); - -} // namespace DataSpec::DNAANCS diff --git a/DataSpec/DNACommon/ANIM.cpp b/DataSpec/DNACommon/ANIM.cpp deleted file mode 100644 index 42079d125..000000000 --- a/DataSpec/DNACommon/ANIM.cpp +++ /dev/null @@ -1,462 +0,0 @@ -#include "DataSpec/DNACommon/ANIM.hpp" - -#include -#include -#include - -#include -#include -#include - -#define DUMP_KEYS 0 - -#if DUMP_KEYS -#include -#include -#endif - -namespace DataSpec::DNAANIM { - -size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector& channels) { - size_t bitsPerKeyFrame = 0; - for (const Channel& chan : channels) { - switch (chan.type) { - case Channel::Type::Rotation: - bitsPerKeyFrame += 1; - [[fallthrough]]; - case Channel::Type::Translation: - case Channel::Type::Scale: - bitsPerKeyFrame += chan.q[0]; - bitsPerKeyFrame += chan.q[1]; - bitsPerKeyFrame += chan.q[2]; - break; - case Channel::Type::KfHead: - bitsPerKeyFrame += 1; - break; - case Channel::Type::RotationMP3: - bitsPerKeyFrame += chan.q[0]; - bitsPerKeyFrame += chan.q[1]; - bitsPerKeyFrame += chan.q[2]; - bitsPerKeyFrame += chan.q[3]; - break; - default: - break; - } - } - return (bitsPerKeyFrame * keyFrameCount + 31) / 32 * 4; -} - -static QuantizedRot QuantizeRotation(const Value& quat, atUint32 div) { - float q = float(div) / (M_PIF / 2.0f); - zeus::simd_floats f(quat.simd); - assert(std::abs(f[1]) <= 1.f && "Out of range quat X component"); - assert(std::abs(f[2]) <= 1.f && "Out of range quat Y component"); - assert(std::abs(f[3]) <= 1.f && "Out of range quat Z component"); - return {{ - atInt32(std::asin(f[1]) * q), - atInt32(std::asin(f[2]) * q), - atInt32(std::asin(f[3]) * q), - }, - (f[0] < 0.f)}; -} - -static Value DequantizeRotation(const QuantizedRot& v, atUint32 div) { - float q = (M_PIF / 2.0f) / float(div); - athena::simd_floats f = { - 0.0f, - std::sin(v.v[0] * q), - std::sin(v.v[1] * q), - std::sin(v.v[2] * q), - }; - f[0] = std::sqrt(std::max((1.0f - (f[1] * f[1] + f[2] * f[2] + f[3] * f[3])), 0.0f)); - f[0] = v.w ? -f[0] : f[0]; - Value retval; - retval.simd.copy_from(f); - return retval; -} - -static Value DequantizeRotation_3(const QuantizedRot& v, atUint32 div) { - float q = 1.0f / float(div); - athena::simd_floats f = { - 0.0f, - v.v[0] * q, - v.v[1] * q, - v.v[2] * q, - }; - f[0] = std::sqrt(std::max((1.0f - (f[1] * f[1] + f[2] * f[2] + f[3] * f[3])), 0.0f)); - f[0] = v.w ? -f[0] : f[0]; - Value retval; - retval.simd.copy_from(f); - return retval; -} - -bool BitstreamReader::dequantizeBit(const atUint8* data) { - atUint32 byteCur = (m_bitCur / 32) * 4; - atUint32 bitRem = m_bitCur % 32; - - /* Fill 32 bit buffer with region containing bits */ - /* Make them least significant */ - atUint32 tempBuf = hecl::SBig(*reinterpret_cast(data + byteCur)) >> bitRem; - - /* That's it */ - m_bitCur += 1; - return tempBuf & 0x1; -} - -atInt32 BitstreamReader::dequantize(const atUint8* data, atUint8 q) { - atUint32 byteCur = (m_bitCur / 32) * 4; - atUint32 bitRem = m_bitCur % 32; - - /* Fill 32 bit buffer with region containing bits */ - /* Make them least significant */ - atUint32 tempBuf = hecl::SBig(*reinterpret_cast(data + byteCur)) >> bitRem; - - /* If this shift underflows the value, buffer the next 32 bits */ - /* And tack onto shifted buffer */ - if ((bitRem + q) > 32) { - atUint32 tempBuf2 = hecl::SBig(*reinterpret_cast(data + byteCur + 4)); - tempBuf |= (tempBuf2 << (32 - bitRem)); - } - - /* Mask it */ - atUint32 mask = (1 << q) - 1; - tempBuf &= mask; - - /* Sign extend */ - atUint32 sign = (tempBuf >> (q - 1)) & 0x1; - if (sign) - tempBuf |= ~0u << q; - - /* Return delta value */ - m_bitCur += q; - return atInt32(tempBuf); -} - -std::vector> BitstreamReader::read(const atUint8* data, size_t keyFrameCount, - const std::vector& channels, atUint32 rotDiv, - float transMult, float scaleMult) { - m_bitCur = 0; - std::vector> chanKeys; - std::vector chanAccum; - chanKeys.reserve(channels.size()); - chanAccum.reserve(channels.size()); - for (const Channel& chan : channels) { - chanAccum.push_back(chan.i); - - chanKeys.emplace_back(); - std::vector& keys = chanKeys.back(); - keys.reserve(keyFrameCount); - switch (chan.type) { - case Channel::Type::Rotation: { - QuantizedRot qr = {{chan.i[0], chan.i[1], chan.i[2]}, false}; - keys.emplace_back(DequantizeRotation(qr, rotDiv)); - break; - } - case Channel::Type::Translation: { - keys.push_back({chan.i[0] * transMult, chan.i[1] * transMult, chan.i[2] * transMult}); - break; - } - case Channel::Type::Scale: { - keys.push_back({chan.i[0] * scaleMult, chan.i[1] * scaleMult, chan.i[2] * scaleMult}); - break; - } - case Channel::Type::KfHead: { - break; - } - case Channel::Type::RotationMP3: { - QuantizedRot qr = {{chan.i[1], chan.i[2], chan.i[3]}, bool(chan.i[0] & 0x1)}; - keys.emplace_back(DequantizeRotation_3(qr, rotDiv)); - break; - } - default: - break; - } - } - - for (size_t f = 0; f < keyFrameCount; ++f) { -#if DUMP_KEYS - fmt::print(stderr, FMT_STRING("\nFRAME {} {} {}\n"), f, (m_bitCur / 32) * 4, m_bitCur % 32); - int lastId = -1; -#endif - auto kit = chanKeys.begin(); - auto ait = chanAccum.begin(); - for (const Channel& chan : channels) { -#if DUMP_KEYS - if (chan.id != lastId) { - lastId = chan.id; - std::fputc('\n', stderr); - } -#endif - QuantizedValue& p = *ait; - switch (chan.type) { - case Channel::Type::Rotation: { - bool wBit = dequantizeBit(data); - p[0] += dequantize(data, chan.q[0]); - p[1] += dequantize(data, chan.q[1]); - p[2] += dequantize(data, chan.q[2]); - QuantizedRot qr = {{p[0], p[1], p[2]}, wBit}; - kit->emplace_back(DequantizeRotation(qr, rotDiv)); -#if DUMP_KEYS - fmt::print(stderr, FMT_STRING("{} R: {} {} {} {}\t"), chan.id, wBit, p[0], p[1], p[2]); -#endif - break; - } - case Channel::Type::Translation: { - atInt32 val1 = dequantize(data, chan.q[0]); - p[0] += val1; - atInt32 val2 = dequantize(data, chan.q[1]); - p[1] += val2; - atInt32 val3 = dequantize(data, chan.q[2]); - p[2] += val3; - kit->push_back({p[0] * transMult, p[1] * transMult, p[2] * transMult}); -#if DUMP_KEYS - fmt::print(stderr, FMT_STRING("{} T: {} {} {}\t"), chan.id, p[0], p[1], p[2]); -#endif - break; - } - case Channel::Type::Scale: { - p[0] += dequantize(data, chan.q[0]); - p[1] += dequantize(data, chan.q[1]); - p[2] += dequantize(data, chan.q[2]); - kit->push_back({p[0] * scaleMult, p[1] * scaleMult, p[2] * scaleMult}); -#if DUMP_KEYS - fmt::print(stderr, FMT_STRING("{} S: {} {} {}\t"), chan.id, p[0], p[1], p[2]); -#endif - break; - } - case Channel::Type::KfHead: { - dequantizeBit(data); - break; - } - case Channel::Type::RotationMP3: { - atInt32 val1 = dequantize(data, chan.q[0]); - p[0] += val1; - atInt32 val2 = dequantize(data, chan.q[1]); - p[1] += val2; - atInt32 val3 = dequantize(data, chan.q[2]); - p[2] += val3; - atInt32 val4 = dequantize(data, chan.q[3]); - p[3] += val4; - QuantizedRot qr = {{p[1], p[2], p[3]}, bool(p[0] & 0x1)}; - kit->emplace_back(DequantizeRotation_3(qr, rotDiv)); - break; - } - default: - break; - } - ++kit; - ++ait; - } -#if DUMP_KEYS - std::fputc('\n', stderr); -#endif - } - - return chanKeys; -} - -void BitstreamWriter::quantizeBit(atUint8* data, bool val) { - atUint32 byteCur = (m_bitCur / 32) * 4; - atUint32 bitRem = m_bitCur % 32; - - /* Fill 32 bit buffer with region containing bits */ - /* Make them least significant */ - *(atUint32*)(data + byteCur) = hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur)) | (val << bitRem)); - - m_bitCur += 1; -} - -void BitstreamWriter::quantize(atUint8* data, atUint8 q, atInt32 val) { - atUint32 byteCur = (m_bitCur / 32) * 4; - atUint32 bitRem = m_bitCur % 32; - - atUint32 masked = val & ((1 << q) - 1); - assert(((((val >> 31) & 0x1) == 0x1) || (((masked >> (q - 1)) & 0x1) == 0)) && "Twos compliment fail"); - - /* Fill 32 bit buffer with region containing bits */ - /* Make them least significant */ - *(atUint32*)(data + byteCur) = hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur)) | (masked << bitRem)); - - /* If this shift underflows the value, buffer the next 32 bits */ - /* And tack onto shifted buffer */ - if ((bitRem + q) > 32) { - *(atUint32*)(data + byteCur + 4) = - hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur + 4)) | (masked >> (32 - bitRem))); - } - - m_bitCur += q; -} - -std::unique_ptr BitstreamWriter::write(const std::vector>& chanKeys, size_t keyFrameCount, - std::vector& channels, atUint32 quantRange, - atUint32& rotDivOut, float& transMultOut, float& scaleMultOut, - size_t& sizeOut) { - m_bitCur = 0; - rotDivOut = quantRange; /* Normalized range of values */ - float quantRangeF = float(quantRange); - - /* Pre-pass to calculate translation multiplier */ - float maxTransDelta = 0.0f; - float maxScaleDelta = 0.0f; - auto kit = chanKeys.begin(); - for (Channel& chan : channels) { - switch (chan.type) { - case Channel::Type::Translation: { - zeus::simd lastVal = {}; - for (auto it = kit->begin(); it != kit->end(); ++it) { - const Value* key = &*it; - zeus::simd_floats f(key->simd - lastVal); - lastVal = key->simd; - maxTransDelta = std::max(maxTransDelta, std::fabs(f[0])); - maxTransDelta = std::max(maxTransDelta, std::fabs(f[1])); - maxTransDelta = std::max(maxTransDelta, std::fabs(f[2])); - } - break; - } - case Channel::Type::Scale: { - zeus::simd lastVal = {}; - for (auto it = kit->begin(); it != kit->end(); ++it) { - const Value* key = &*it; - zeus::simd_floats f(key->simd - lastVal); - lastVal = key->simd; - maxScaleDelta = std::max(maxScaleDelta, std::fabs(f[0])); - maxScaleDelta = std::max(maxScaleDelta, std::fabs(f[1])); - maxScaleDelta = std::max(maxScaleDelta, std::fabs(f[2])); - } - break; - } - default: - break; - } - ++kit; - } - transMultOut = maxTransDelta / quantRangeF + FLT_EPSILON; - scaleMultOut = maxScaleDelta / quantRangeF + FLT_EPSILON; - - /* Output channel inits */ - std::vector initVals; - initVals.reserve(channels.size()); - kit = chanKeys.begin(); - for (Channel& chan : channels) { - chan.q[0] = 1; - chan.q[1] = 1; - chan.q[2] = 1; - switch (chan.type) { - case Channel::Type::Rotation: { - QuantizedRot qr = QuantizeRotation((*kit)[0], rotDivOut); - chan.i = qr.v; - initVals.push_back(chan.i); - break; - } - case Channel::Type::Translation: { - zeus::simd_floats f((*kit)[0].simd); - chan.i = {atInt32(f[0] / transMultOut), atInt32(f[1] / transMultOut), atInt32(f[2] / transMultOut)}; - initVals.push_back(chan.i); - break; - } - case Channel::Type::Scale: { - zeus::simd_floats f((*kit)[0].simd); - chan.i = {atInt32(f[0] / scaleMultOut), atInt32(f[1] / scaleMultOut), atInt32(f[2] / scaleMultOut)}; - initVals.push_back(chan.i); - break; - } - default: - break; - } - ++kit; - } - - /* Pre-pass to analyze quantization factors for channels */ - std::vector lastVals = initVals; - kit = chanKeys.begin(); - auto vit = lastVals.begin(); - for (Channel& chan : channels) { - QuantizedValue& last = *vit++; - switch (chan.type) { - case Channel::Type::Rotation: { - for (auto it = kit->begin() + 1; it != kit->end(); ++it) { - QuantizedRot qrCur = QuantizeRotation(*it, rotDivOut); - chan.q[0] = std::max(chan.q[0], atUint8(qrCur.v.qFrom(last, 0))); - chan.q[1] = std::max(chan.q[1], atUint8(qrCur.v.qFrom(last, 1))); - chan.q[2] = std::max(chan.q[2], atUint8(qrCur.v.qFrom(last, 2))); - last = qrCur.v; - } - break; - } - case Channel::Type::Translation: { - for (auto it = kit->begin() + 1; it != kit->end(); ++it) { - zeus::simd_floats f(it->simd); - QuantizedValue cur = {atInt32(f[0] / transMultOut), atInt32(f[1] / transMultOut), atInt32(f[2] / transMultOut)}; - chan.q[0] = std::max(chan.q[0], atUint8(cur.qFrom(last, 0))); - chan.q[1] = std::max(chan.q[1], atUint8(cur.qFrom(last, 1))); - chan.q[2] = std::max(chan.q[2], atUint8(cur.qFrom(last, 2))); - last = cur; - } - break; - } - case Channel::Type::Scale: { - for (auto it = kit->begin() + 1; it != kit->end(); ++it) { - zeus::simd_floats f(it->simd); - QuantizedValue cur = {atInt32(f[0] / scaleMultOut), atInt32(f[1] / scaleMultOut), atInt32(f[2] / scaleMultOut)}; - chan.q[0] = std::max(chan.q[0], atUint8(cur.qFrom(last, 0))); - chan.q[1] = std::max(chan.q[1], atUint8(cur.qFrom(last, 1))); - chan.q[2] = std::max(chan.q[2], atUint8(cur.qFrom(last, 2))); - last = cur; - } - break; - } - default: - break; - } - ++kit; - } - - /* Generate Bitstream */ - sizeOut = ComputeBitstreamSize(keyFrameCount, channels); - std::unique_ptr newData(new atUint8[sizeOut]); - memset(newData.get(), 0, sizeOut); - - lastVals = initVals; - for (size_t frame = 0; frame < keyFrameCount; ++frame) { - kit = chanKeys.begin(); - vit = lastVals.begin(); - for (const Channel& chan : channels) { - const Value& val = (*kit++)[frame + 1]; - QuantizedValue& last = *vit++; - switch (chan.type) { - case Channel::Type::Rotation: { - QuantizedRot qrCur = QuantizeRotation(val, rotDivOut); - quantizeBit(newData.get(), qrCur.w); - quantize(newData.get(), chan.q[0], qrCur.v[0] - last.v[0]); - quantize(newData.get(), chan.q[1], qrCur.v[1] - last.v[1]); - quantize(newData.get(), chan.q[2], qrCur.v[2] - last.v[2]); - last = qrCur.v; - break; - } - case Channel::Type::Translation: { - zeus::simd_floats f(val.simd); - QuantizedValue cur = {atInt32(f[0] / transMultOut), atInt32(f[1] / transMultOut), atInt32(f[2] / transMultOut)}; - quantize(newData.get(), chan.q[0], cur[0] - last[0]); - quantize(newData.get(), chan.q[1], cur[1] - last[1]); - quantize(newData.get(), chan.q[2], cur[2] - last[2]); - last = cur; - break; - } - case Channel::Type::Scale: { - zeus::simd_floats f(val.simd); - QuantizedValue cur = {atInt32(f[0] / scaleMultOut), atInt32(f[1] / scaleMultOut), atInt32(f[2] / scaleMultOut)}; - quantize(newData.get(), chan.q[0], cur[0] - last[0]); - quantize(newData.get(), chan.q[1], cur[1] - last[1]); - quantize(newData.get(), chan.q[2], cur[2] - last[2]); - last = cur; - break; - } - default: - break; - } - } - } - return newData; -} - -} // namespace DataSpec::DNAANIM diff --git a/DataSpec/DNACommon/ANIM.hpp b/DataSpec/DNACommon/ANIM.hpp deleted file mode 100644 index 903fda326..000000000 --- a/DataSpec/DNACommon/ANIM.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include - -namespace DataSpec::DNAANIM { - -struct Value { - athena::simd simd; - Value() = default; - Value(const athena::simd& s) : simd(s) {} - Value(const atVec3f& v) : simd(v.simd) {} - Value(const atVec4f& v) : simd(v.simd) {} - Value(float x, float y, float z) : simd(x, y, z, 0.f) {} - Value(float w, float x, float y, float z) : simd(w, x, y, z) {} -}; -struct QuantizedValue { - atInt32 v[4]; - atInt32& operator[](size_t idx) { return v[idx]; } - atInt32 operator[](size_t idx) const { return v[idx]; } - - int qFrom(const QuantizedValue& other, size_t idx) const { - atInt32 delta = v[idx] - other.v[idx]; - atInt32 absDelta = std::abs(delta); - if (absDelta == 0) - return 1; - int ret = int(std::ceil(std::log2(absDelta))) + 1; - if (delta > 0 && (delta >> (ret - 1))) - ++ret; - assert(ret <= 24 && "Bad q value"); - return ret; - } -}; -struct QuantizedRot { - QuantizedValue v; - bool w; -}; -struct Channel { - enum class Type { Rotation, Translation, Scale, KfHead, RotationMP3 } type; - atInt32 id = -1; - QuantizedValue i = {}; - atUint8 q[4] = {}; -}; - -size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector& channels); - -class BitstreamReader { - size_t m_bitCur; - atInt32 dequantize(const atUint8* data, atUint8 q); - bool dequantizeBit(const atUint8* data); - -public: - std::vector> read(const atUint8* data, size_t keyFrameCount, const std::vector& channels, - atUint32 rotDiv, float transMult, float scaleMult); -}; - -class BitstreamWriter { - size_t m_bitCur; - void quantize(atUint8* data, atUint8 q, atInt32 val); - void quantizeBit(atUint8* data, bool val); - -public: - std::unique_ptr write(const std::vector>& chanKeys, size_t keyFrameCount, - std::vector& channels, atUint32 quantRange, atUint32& rotDivOut, - float& transMultOut, float& scaleMultOut, size_t& sizeOut); -}; - -} // namespace DataSpec::DNAANIM diff --git a/DataSpec/DNACommon/AROTBuilder.cpp b/DataSpec/DNACommon/AROTBuilder.cpp deleted file mode 100644 index bd014635e..000000000 --- a/DataSpec/DNACommon/AROTBuilder.cpp +++ /dev/null @@ -1,440 +0,0 @@ -#include "AROTBuilder.hpp" - -#include -#include - -#include "hecl/Blender/Connection.hpp" -#include "PATH.hpp" - -namespace DataSpec { -logvisor::Module Log("AROTBuilder"); - -constexpr s32 AROT_MAX_LEVEL = 10; -constexpr s32 AROT_MIN_MODELS = 8; -constexpr s32 COLLISION_MIN_NODE_TRIANGLES = 8; -constexpr s32 PATH_MIN_NODE_REGIONS = 16; -constexpr float AROT_MIN_SUBDIV = 8.f; - -static zeus::CAABox SplitAABB(const zeus::CAABox& aabb, int i) { - zeus::CAABox pos, neg; - aabb.splitZ(neg, pos); - if (i & 4) { - zeus::CAABox(pos).splitY(neg, pos); - if (i & 2) { - zeus::CAABox(pos).splitX(neg, pos); - if (i & 1) - return pos; - else - return neg; - } else { - zeus::CAABox(neg).splitX(neg, pos); - if (i & 1) - return pos; - else - return neg; - } - } else { - zeus::CAABox(neg).splitY(neg, pos); - if (i & 2) { - zeus::CAABox(pos).splitX(neg, pos); - if (i & 1) - return pos; - else - return neg; - } else { - zeus::CAABox(neg).splitX(neg, pos); - if (i & 1) - return pos; - else - return neg; - } - } -} - -void AROTBuilder::Node::mergeSets(int a, int b) { - childNodes[a].childIndices.insert(childNodes[b].childIndices.cbegin(), childNodes[b].childIndices.cend()); - childNodes[b].childIndices = childNodes[a].childIndices; -} - -bool AROTBuilder::Node::compareSets(int a, int b) const { - return childNodes[a].childIndices != childNodes[b].childIndices; -} - -void AROTBuilder::Node::addChild(int level, int minChildren, const std::vector& triBoxes, - const zeus::CAABox& curAABB, BspNodeType& typeOut) { - /* Gather intersecting faces */ - for (size_t i = 0; i < triBoxes.size(); ++i) - if (triBoxes[i].intersects(curAABB)) - childIndices.insert(i); - - zeus::CVector3f extents = curAABB.extents(); - - /* Return early if empty, triangle intersection below performance threshold, or at max level */ - if (childIndices.empty()) { - typeOut = BspNodeType::Invalid; - return; - } else if (childIndices.size() < minChildren || level == AROT_MAX_LEVEL || - std::max(extents.x(), std::max(extents.y(), extents.z())) < AROT_MIN_SUBDIV) { - typeOut = BspNodeType::Leaf; - return; - } - - /* Subdivide */ - typeOut = BspNodeType::Branch; - childNodes.resize(8); - for (int i = 0; i < 8; ++i) { - BspNodeType chType; - childNodes[i].addChild(level + 1, minChildren, triBoxes, SplitAABB(curAABB, i), chType); - flags |= int(chType) << (i * 2); - } - - /* Unsubdivide minimum axis dimensions */ - if (extents.x() < AROT_MIN_SUBDIV) { - mergeSets(0, 1); - mergeSets(4, 5); - mergeSets(2, 3); - mergeSets(6, 7); - } - if (extents.y() < AROT_MIN_SUBDIV) { - mergeSets(0, 2); - mergeSets(1, 3); - mergeSets(4, 6); - mergeSets(5, 7); - } - if (extents.z() < AROT_MIN_SUBDIV) { - mergeSets(0, 4); - mergeSets(1, 5); - mergeSets(2, 6); - mergeSets(3, 7); - } - - /* Unsubdivide */ - compSubdivs = 0; - if (compareSets(0, 1) || compareSets(4, 5) || compareSets(2, 3) || compareSets(6, 7)) - compSubdivs |= 0x1; - if (compareSets(0, 2) || compareSets(1, 3) || compareSets(4, 6) || compareSets(5, 7)) - compSubdivs |= 0x2; - if (compareSets(0, 4) || compareSets(1, 5) || compareSets(2, 6) || compareSets(3, 7)) - compSubdivs |= 0x4; - - if (!compSubdivs) { - typeOut = BspNodeType::Leaf; - childNodes = std::vector(); - flags = 0; - } -} - -size_t AROTBuilder::BitmapPool::addIndices(const std::set& indices) { - for (size_t i = 0; i < m_pool.size(); ++i) - if (m_pool[i] == indices) - return i; - m_pool.push_back(indices); - return m_pool.size() - 1; -} - -constexpr std::array AROTChildCounts{ - 0, 2, 2, 4, 2, 4, 4, 8, -}; - -void AROTBuilder::Node::nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPool, size_t& curOff) { - sz += 1; - poolIdx = bmpPool.addIndices(childIndices); - if (poolIdx > 65535) - Log.report(logvisor::Fatal, FMT_STRING("AROT bitmap exceeds 16-bit node addressing; area too complex")); - - uint32_t childCount = AROTChildCounts[compSubdivs]; - nodeOff = curOff; - nodeSz = childCount * 2 + 4; - curOff += nodeSz; - if (childNodes.size()) { - for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) { - for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) { - for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) { - int idx = k * 4 + j * 2 + i; - childNodes[idx].nodeCount(sz, idxRefs, bmpPool, curOff); - } - } - } - idxRefs += childCount; - } -} - -void AROTBuilder::Node::writeIndirectionTable(athena::io::MemoryWriter& w) { - w.writeUint32Big(nodeOff); - if (childNodes.size()) { - for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) { - for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) { - for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) { - int idx = k * 4 + j * 2 + i; - childNodes[idx].writeIndirectionTable(w); - } - } - } - } -} - -void AROTBuilder::Node::writeNodes(athena::io::MemoryWriter& w, int nodeIdx) { - w.writeUint16Big(poolIdx); - w.writeUint16Big(compSubdivs); - - if (childNodes.size()) { - int curIdx = nodeIdx + 1; - if (curIdx > 65535) - Log.report(logvisor::Fatal, FMT_STRING("AROT node exceeds 16-bit node addressing; area too complex")); - - std::array childIndices; - - for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) { - for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) { - for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) { - int idx = k * 4 + j * 2 + i; - w.writeUint16Big(curIdx); - childIndices[idx] = curIdx; - childNodes[idx].advanceIndex(curIdx); - } - } - } - - for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) { - for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) { - for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) { - int idx = k * 4 + j * 2 + i; - childNodes[idx].writeNodes(w, childIndices[idx]); - } - } - } - } -} - -void AROTBuilder::Node::advanceIndex(int& nodeIdx) { - ++nodeIdx; - if (childNodes.size()) { - for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) { - for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) { - for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) { - int idx = k * 4 + j * 2 + i; - childNodes[idx].advanceIndex(nodeIdx); - } - } - } - } -} - -void AROTBuilder::Node::colSize(size_t& totalSz) { - if (childIndices.size()) { - nodeOff = totalSz; - if (childNodes.empty()) { - totalSz += 26 + childIndices.size() * 2; - } else { - totalSz += 36; - for (int i = 0; i < 8; ++i) - childNodes[i].colSize(totalSz); - } - } -} - -void AROTBuilder::Node::writeColNodes(uint8_t*& ptr, const zeus::CAABox& curAABB) { - if (childIndices.size()) { - if (childNodes.empty()) { - float* aabbOut = reinterpret_cast(ptr); - aabbOut[0] = hecl::SBig(curAABB.min[0]); - aabbOut[1] = hecl::SBig(curAABB.min[1]); - aabbOut[2] = hecl::SBig(curAABB.min[2]); - aabbOut[3] = hecl::SBig(curAABB.max[0]); - aabbOut[4] = hecl::SBig(curAABB.max[1]); - aabbOut[5] = hecl::SBig(curAABB.max[2]); - athena::io::MemoryWriter w(ptr + 24, INT32_MAX); - w.writeUint16Big(childIndices.size()); - for (int idx : childIndices) - w.writeUint16Big(idx); - ptr += 26 + childIndices.size() * 2; - } else { - uint16_t* pflags = reinterpret_cast(ptr); - uint32_t* offsets = reinterpret_cast(ptr + 4); - memset(pflags, 0, sizeof(uint32_t) * 9); - for (int i = 0; i < 8; ++i) { - const Node& chNode = childNodes[i]; - BspNodeType type = BspNodeType((flags >> (i * 2)) & 0x3); - if (type != BspNodeType::Invalid) - offsets[i] = hecl::SBig(uint32_t(chNode.nodeOff - nodeOff - 36)); - } - - *pflags = hecl::SBig(flags); - ptr += 36; - - for (int i = 0; i < 8; ++i) - childNodes[i].writeColNodes(ptr, SplitAABB(curAABB, i)); - } - } -} - -void AROTBuilder::Node::pathCountNodesAndLookups(size_t& nodeCount, size_t& lookupCount) { - ++nodeCount; - if (childNodes.empty()) { - lookupCount += childIndices.size(); - } else { - for (int i = 0; i < 8; ++i) - childNodes[i].pathCountNodesAndLookups(nodeCount, lookupCount); - } -} - -template -void AROTBuilder::Node::pathWrite(DNAPATH::PATH& path, const zeus::CAABox& curAABB) { - if (childNodes.empty()) { - auto& n = path.octree.emplace_back(); - n.isLeaf = 1; - n.aabb[0] = curAABB.min; - n.aabb[1] = curAABB.max; - n.centroid = curAABB.center(); - std::fill(std::begin(n.children), std::end(n.children), 0xFFFFFFFF); - n.regionCount = childIndices.size(); - n.regionStart = path.octreeRegionLookup.size(); - for (int r : childIndices) - path.octreeRegionLookup.push_back(r); - } else { - std::array children; - for (size_t i = 0; i < children.size(); ++i) { - /* Head recursion (first node will be a leaf) */ - childNodes[i].pathWrite(path, SplitAABB(curAABB, static_cast(i))); - children[i] = path.octree.size() - 1; - } - - auto& n = path.octree.emplace_back(); - n.isLeaf = 0; - n.aabb[0] = curAABB.min; - n.aabb[1] = curAABB.max; - n.centroid = curAABB.center(); - std::copy(children.cbegin(), children.cend(), std::begin(n.children)); - n.regionCount = 0; - n.regionStart = 0; - } -} - -template void AROTBuilder::Node::pathWrite(DNAPATH::PATH& path, const zeus::CAABox& curAABB); -template void AROTBuilder::Node::pathWrite(DNAPATH::PATH& path, const zeus::CAABox& curAABB); -template void AROTBuilder::Node::pathWrite(DNAPATH::PATH& path, const zeus::CAABox& curAABB); - -void AROTBuilder::build(std::vector>& secs, const zeus::CAABox& fullAabb, - const std::vector& meshAabbs, const std::vector& meshes) { - /* Recursively split */ - BspNodeType rootType; - rootNode.addChild(0, AROT_MIN_MODELS, meshAabbs, fullAabb, rootType); - - /* Calculate indexing metrics */ - size_t totalNodeCount = 0; - size_t idxRefCount = 0; - size_t curOff = 0; - rootNode.nodeCount(totalNodeCount, idxRefCount, bmpPool, curOff); - size_t bmpWordCount = ROUND_UP_32(meshes.size()) / 32; - size_t arotSz = 64 + bmpWordCount * bmpPool.m_pool.size() * 4 + totalNodeCount * 8 + idxRefCount * 2; - - /* Write header */ - secs.emplace_back(arotSz, 0); - athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); - w.writeUint32Big('AROT'); - w.writeUint32Big(1); - w.writeUint32Big(bmpPool.m_pool.size()); - w.writeUint32Big(meshes.size()); - w.writeUint32Big(totalNodeCount); - w.writeVec3fBig(fullAabb.min); - w.writeVec3fBig(fullAabb.max); - w.seekAlign32(); - - /* Write bitmap */ - std::vector bmpWords; - bmpWords.reserve(bmpWordCount); - for (const std::set& bmp : bmpPool.m_pool) { - bmpWords.clear(); - bmpWords.resize(bmpWordCount); - - auto bmpIt = bmp.cbegin(); - if (bmpIt != bmp.cend()) { - int curIdx = 0; - for (size_t word = 0; word < bmpWordCount; ++word) { - for (u32 b = 0; b < 32; ++b) { - if (*bmpIt == curIdx) { - bmpWords[word] |= 1U << b; - ++bmpIt; - if (bmpIt == bmp.cend()) { - break; - } - } - ++curIdx; - } - if (bmpIt == bmp.cend()) { - break; - } - } - } - - for (uint32_t word : bmpWords) - w.writeUint32Big(word); - } - - /* Write the rest */ - rootNode.writeIndirectionTable(w); - rootNode.writeNodes(w, 0); -} - -std::pair, uint32_t> AROTBuilder::buildCol(const ColMesh& mesh, BspNodeType& rootOut) { - /* Accumulate total AABB */ - zeus::CAABox fullAABB; - for (const auto& vert : mesh.verts) - fullAABB.accumulateBounds(zeus::CVector3f(vert)); - - /* Predetermine triangle AABBs */ - std::vector triBoxes; - triBoxes.reserve(mesh.trianges.size()); - for (const ColMesh::Triangle& tri : mesh.trianges) { - zeus::CAABox& aabb = triBoxes.emplace_back(); - for (const u32 edgeIdx : tri.edges) { - const ColMesh::Edge& edge = mesh.edges[edgeIdx]; - for (const u32 vertIdx : edge.verts) { - const auto& vert = mesh.verts[vertIdx]; - aabb.accumulateBounds(zeus::CVector3f(vert)); - } - } - } - - /* Recursively split */ - rootNode.addChild(0, COLLISION_MIN_NODE_TRIANGLES, triBoxes, fullAABB, rootOut); - - /* Calculate offsets and write out */ - size_t totalSize = 0; - rootNode.colSize(totalSize); - std::unique_ptr ret(new uint8_t[totalSize]); - uint8_t* ptr = ret.get(); - rootNode.writeColNodes(ptr, fullAABB); - - return {std::move(ret), totalSize}; -} - -template -void AROTBuilder::buildPath(DNAPATH::PATH& path) { - /* Accumulate total AABB and gather region boxes */ - std::vector regionBoxes; - regionBoxes.reserve(path.regions.size()); - zeus::CAABox fullAABB; - for (const auto& r : path.regions) - fullAABB.accumulateBounds(regionBoxes.emplace_back(r.aabb[0], r.aabb[1])); - - /* Recursively split */ - BspNodeType dontCare; - rootNode.addChild(0, PATH_MIN_NODE_REGIONS, regionBoxes, fullAABB, dontCare); - - /* Write out */ - size_t nodeCount = 0; - size_t lookupCount = 0; - rootNode.pathCountNodesAndLookups(nodeCount, lookupCount); - path.octreeNodeCount = nodeCount; - path.octree.reserve(nodeCount); - path.octreeRegionLookupCount = lookupCount; - path.octreeRegionLookup.reserve(lookupCount); - rootNode.pathWrite(path, fullAABB); -} - -template void AROTBuilder::buildPath(DNAPATH::PATH& path); -template void AROTBuilder::buildPath(DNAPATH::PATH& path); -template void AROTBuilder::buildPath(DNAPATH::PATH& path); - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/AROTBuilder.hpp b/DataSpec/DNACommon/AROTBuilder.hpp deleted file mode 100644 index df42876a7..000000000 --- a/DataSpec/DNACommon/AROTBuilder.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include "DNACommon.hpp" -#include "DeafBabe.hpp" -#include "zeus/CAABox.hpp" -#include "CMDL.hpp" -#include -#include - -namespace DataSpec { -namespace DNAPATH { -template -struct PATH; -} - -struct AROTBuilder { - using ColMesh = hecl::blender::ColMesh; - - struct BitmapPool { - std::vector> m_pool; - size_t addIndices(const std::set& indices); - } bmpPool; - - struct Node { - std::vector childNodes; - std::set childIndices; - size_t poolIdx = 0; - uint16_t flags = 0; - uint16_t compSubdivs = 0; - - size_t nodeOff = 0; - size_t nodeSz = 4; - - void addChild(int level, int minChildren, const std::vector& triBoxes, const zeus::CAABox& curAABB, - BspNodeType& typeOut); - void mergeSets(int a, int b); - bool compareSets(int a, int b) const; - void nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPool, size_t& curOff); - void writeIndirectionTable(athena::io::MemoryWriter& w); - void writeNodes(athena::io::MemoryWriter& w, int nodeIdx); - void advanceIndex(int& nodeIdx); - - void colSize(size_t& totalSz); - void writeColNodes(uint8_t*& ptr, const zeus::CAABox& curAABB); - - void pathCountNodesAndLookups(size_t& nodeCount, size_t& lookupCount); - template - void pathWrite(DNAPATH::PATH& path, const zeus::CAABox& curAABB); - } rootNode; - - void build(std::vector>& secs, const zeus::CAABox& fullAabb, - const std::vector& meshAabbs, const std::vector& meshes); - std::pair, uint32_t> buildCol(const ColMesh& mesh, BspNodeType& rootOut); - template - void buildPath(DNAPATH::PATH& path); -}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/ATBL.cpp b/DataSpec/DNACommon/ATBL.cpp deleted file mode 100644 index 38757305e..000000000 --- a/DataSpec/DNACommon/ATBL.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "DataSpec/DNACommon/ATBL.hpp" - -#include -#include -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -#include -#include -#include -#include - -#include - -namespace DataSpec::DNAAudio { - -bool ATBL::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - uint32_t idxCount = rs.readUint32Big(); - athena::io::YAMLDocWriter w("ATBL"); - for (uint32_t i = 0; i < idxCount; ++i) { - uint16_t idx = rs.readUint16Big(); - if (idx == 0xffff) - continue; - w.writeUint16(fmt::format(FMT_STRING("0x{:04X}"), i), idx); - } - - athena::io::FileWriter fw(outPath.getAbsolutePath()); - w.finish(&fw); - - return true; -} - -bool ATBL::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - athena::io::FileReader r(inPath.getAbsolutePath()); - if (r.hasError()) - return false; - - athena::io::YAMLDocReader dr; - if (!dr.parse(&r)) - return false; - - unsigned long maxI = 0; - for (const auto& pair : dr.getRootNode()->m_mapChildren) { - unsigned long i = strtoul(pair.first.c_str(), nullptr, 0); - maxI = std::max(maxI, i); - } - - std::vector vecOut(maxI + 1, 0xffff); - for (const auto& pair : dr.getRootNode()->m_mapChildren) { - unsigned long i = strtoul(pair.first.c_str(), nullptr, 0); - vecOut[i] = hecl::SBig(uint16_t(strtoul(pair.second->m_scalarString.c_str(), nullptr, 0))); - } - - athena::io::FileWriter w(outPath.getAbsolutePath()); - if (w.hasError()) - return false; - w.writeUint32Big(uint32_t(vecOut.size())); - w.writeBytes(vecOut.data(), vecOut.size() * 2); - - return true; -} - -} // namespace DataSpec::DNAAudio diff --git a/DataSpec/DNACommon/ATBL.hpp b/DataSpec/DNACommon/ATBL.hpp deleted file mode 100644 index bcd5abef4..000000000 --- a/DataSpec/DNACommon/ATBL.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAAudio { - -class ATBL { -public: - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); -}; - -} // namespace DataSpec::DNAAudio diff --git a/DataSpec/DNACommon/BabeDead.cpp b/DataSpec/DNACommon/BabeDead.cpp deleted file mode 100644 index ff9b01526..000000000 --- a/DataSpec/DNACommon/BabeDead.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include "DataSpec/DNACommon/BabeDead.hpp" - -#include "DataSpec/DNAMP1/MREA.hpp" -#include "DataSpec/DNAMP3/MREA.hpp" - -#include - -#include -#include -#include - -#include - -namespace DataSpec { - -template -void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, const BabeDeadLight& light, unsigned s, unsigned l) { - switch (light.lightType) { - case BabeDeadLight::LightType::LocalAmbient: - case BabeDeadLight::LightType::LocalAmbient2: - os.format(FMT_STRING("bg_node.inputs[0].default_value = ({},{},{},1.0)\n" - "bg_node.inputs[1].default_value = {}\n"), - light.color.simd[0], light.color.simd[1], light.color.simd[2], light.q / 8.f); - return; - case BabeDeadLight::LightType::Directional: - os.format(FMT_STRING("lamp = bpy.data.lights.new('LAMP_{:01d}_{:03d}', 'SUN')\n" - "lamp.color = ({},{},{})\n" - "lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n" - "lamp_obj.rotation_mode = 'QUATERNION'\n" - "lamp_obj.rotation_quaternion = Vector((0,0,-1)).rotation_difference(Vector(({},{},{})))\n" - "lamp.use_shadow = {}\n" - "\n"), - s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], light.direction.simd[0], - light.direction.simd[1], light.direction.simd[2], light.castShadows ? "True" : "False"); - return; - case BabeDeadLight::LightType::Custom: - os.format(FMT_STRING("lamp = bpy.data.lights.new('LAMP_{:01d}_{:03d}', 'POINT')\n" - "lamp.color = ({},{},{})\n" - "lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n" - "lamp.shadow_soft_size = 1.0\n" - "lamp.use_shadow = {}\n" - "\n"), - s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], - light.castShadows ? "True" : "False"); - break; - case BabeDeadLight::LightType::Spot: - case BabeDeadLight::LightType::Spot2: - os.format(FMT_STRING("lamp = bpy.data.lights.new('LAMP_{:01d}_{:03d}', 'SPOT')\n" - "lamp.color = ({},{},{})\n" - "lamp.spot_size = {:.6g}\n" - "lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n" - "lamp_obj.rotation_mode = 'QUATERNION'\n" - "lamp_obj.rotation_quaternion = Vector((0,0,-1)).rotation_difference(Vector(({},{},{})))\n" - "lamp.shadow_soft_size = 0.5\n" - "lamp.use_shadow = {}\n" - "\n"), - s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], zeus::degToRad(light.spotCutoff), - light.direction.simd[0], light.direction.simd[1], light.direction.simd[2], - light.castShadows ? "True" : "False"); - break; - default: - return; - } - - os.format(FMT_STRING("lamp.retro_layer = {}\n" - "lamp.retro_origtype = {}\n" - "lamp.falloff_type = 'INVERSE_COEFFICIENTS'\n" - "lamp.constant_coefficient = 0\n" - "lamp.use_nodes = True\n" - "falloff_node = lamp.node_tree.nodes.new('ShaderNodeLightFalloff')\n" - "lamp.energy = 0.0\n" - "falloff_node.inputs[0].default_value = {}\n" - "hue_sat_node = lamp.node_tree.nodes.new('ShaderNodeHueSaturation')\n" - "hue_sat_node.inputs[1].default_value = 1.25\n" - "hue_sat_node.inputs[4].default_value = ({},{},{},1.0)\n" - "lamp.node_tree.links.new(hue_sat_node.outputs[0], lamp.node_tree.nodes['Emission'].inputs[0])\n" - "lamp_obj.location = ({},{},{})\n" - "bpy.context.scene.collection.objects.link(lamp_obj)\n" - "\n"), - s, unsigned(light.lightType), light.q / 8.f, light.color.simd[0], light.color.simd[1], light.color.simd[2], - light.position.simd[0], light.position.simd[1], light.position.simd[2]); - - switch (light.falloff) { - case BabeDeadLight::Falloff::Constant: - os << "falloff_node.inputs[0].default_value *= 150.0\n" - "lamp.node_tree.links.new(falloff_node.outputs[2], lamp.node_tree.nodes['Emission'].inputs[1])\n"; - if (light.q > FLT_EPSILON) - os.format(FMT_STRING("lamp.constant_coefficient = 2.0 / {}\n"), light.q); - break; - case BabeDeadLight::Falloff::Linear: - os << "lamp.node_tree.links.new(falloff_node.outputs[1], lamp.node_tree.nodes['Emission'].inputs[1])\n"; - if (light.q > FLT_EPSILON) - os.format(FMT_STRING("lamp.linear_coefficient = 250 / {}\n"), light.q); - break; - case BabeDeadLight::Falloff::Quadratic: - os << "lamp.node_tree.links.new(falloff_node.outputs[0], lamp.node_tree.nodes['Emission'].inputs[1])\n"; - if (light.q > FLT_EPSILON) - os.format(FMT_STRING("lamp.quadratic_coefficient = 25000 / {}\n"), light.q); - break; - default: - break; - } -} - -template void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, - const DNAMP1::MREA::BabeDeadLight& light, - unsigned s, unsigned l); -template void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, - const DNAMP3::MREA::BabeDeadLight& light, - unsigned s, unsigned l); - -template -void WriteBabeDeadLightFromBlender(BabeDeadLight& lightOut, const hecl::blender::Light& lightIn) { - using InterType = hecl::blender::Light::Type; - switch (lightIn.type) { - case InterType::Ambient: - lightOut.lightType = BabeDeadLight::LightType::LocalAmbient; - break; - case InterType::Directional: - lightOut.lightType = BabeDeadLight::LightType::Directional; - break; - case InterType::Custom: - default: - lightOut.lightType = BabeDeadLight::LightType::Custom; - break; - case InterType::Spot: - lightOut.lightType = BabeDeadLight::LightType::Spot; - break; - } - - if (lightIn.type == InterType::Ambient) { - lightOut.falloff = BabeDeadLight::Falloff::Constant; - lightOut.q = lightIn.energy * 8.f; - } else if (lightIn.linear > lightIn.constant && lightIn.linear > lightIn.quadratic) { - lightOut.falloff = BabeDeadLight::Falloff::Linear; - lightOut.q = 250.f / lightIn.linear; - } else if (lightIn.quadratic > lightIn.constant && lightIn.quadratic > lightIn.linear) { - lightOut.falloff = BabeDeadLight::Falloff::Quadratic; - lightOut.q = 25000.f / lightIn.quadratic; - } else { - lightOut.falloff = BabeDeadLight::Falloff::Constant; - lightOut.q = 2.f / lightIn.constant; - } - - lightOut.color = lightIn.color; - lightOut.spotCutoff = zeus::radToDeg(lightIn.spotCutoff); - lightOut.castShadows = lightIn.shadow; - lightOut.position.simd[0] = lightIn.sceneXf[0].simd[3]; - lightOut.position.simd[1] = lightIn.sceneXf[1].simd[3]; - lightOut.position.simd[2] = lightIn.sceneXf[2].simd[3]; - - zeus::CTransform lightXf(&lightIn.sceneXf[0]); - lightOut.direction = (lightXf.basis.transposed() * zeus::CVector3f(0.f, 0.f, -1.f)).normalized(); -} - -template void WriteBabeDeadLightFromBlender(DNAMP1::MREA::BabeDeadLight& lightOut, - const hecl::blender::Light& lightIn); -template void WriteBabeDeadLightFromBlender(DNAMP3::MREA::BabeDeadLight& lightOut, - const hecl::blender::Light& lightIn); - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/BabeDead.hpp b/DataSpec/DNACommon/BabeDead.hpp deleted file mode 100644 index 3c6781c72..000000000 --- a/DataSpec/DNACommon/BabeDead.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -namespace hecl::blender { -struct Light; -class PyOutStream; -} // namespace hecl::blender - -namespace DataSpec { - -template -void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, const BabeDeadLight& light, unsigned s, unsigned l); - -template -void WriteBabeDeadLightFromBlender(BabeDeadLight& lightOut, const hecl::blender::Light& lightIn); - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/CMDL.cpp b/DataSpec/DNACommon/CMDL.cpp deleted file mode 100644 index 1baa4d90b..000000000 --- a/DataSpec/DNACommon/CMDL.cpp +++ /dev/null @@ -1,2273 +0,0 @@ -#include "DataSpec/DNACommon/CMDL.hpp" - -#include - -#include "DataSpec/DNAMP1/CMDLMaterials.hpp" -#include "DataSpec/DNAMP1/CSKR.hpp" -#include "DataSpec/DNAMP1/MREA.hpp" -#include "DataSpec/DNAMP2/CMDLMaterials.hpp" -#include "DataSpec/DNAMP2/CSKR.hpp" -#include "DataSpec/DNAMP3/CMDLMaterials.hpp" -#include "DataSpec/DNAMP3/CSKR.hpp" - -#include -#include -#include -#include -#include - -namespace DataSpec::DNACMDL { - -template -void GetVertexAttributes(const MaterialSet& matSet, std::vector& attributesOut) { - attributesOut.clear(); - attributesOut.reserve(matSet.materials.size()); - - for (const typename MaterialSet::Material& mat : matSet.materials) { - const typename MaterialSet::Material::VAFlags& vaFlags = mat.getVAFlags(); - attributesOut.emplace_back(); - VertexAttributes& va = attributesOut.back(); - - va.pos = vaFlags.position(); - va.norm = vaFlags.normal(); - va.color0 = vaFlags.color0(); - va.color1 = vaFlags.color1(); - - if ((va.uvs[0] = vaFlags.tex0())) - ++va.uvCount; - if ((va.uvs[1] = vaFlags.tex1())) - ++va.uvCount; - if ((va.uvs[2] = vaFlags.tex2())) - ++va.uvCount; - if ((va.uvs[3] = vaFlags.tex3())) - ++va.uvCount; - if ((va.uvs[4] = vaFlags.tex4())) - ++va.uvCount; - if ((va.uvs[5] = vaFlags.tex5())) - ++va.uvCount; - if ((va.uvs[6] = vaFlags.tex6())) - ++va.uvCount; - - va.pnMtxIdx = vaFlags.pnMatIdx(); - - if ((va.texMtxIdx[0] = vaFlags.tex0MatIdx())) - ++va.texMtxIdxCount; - if ((va.texMtxIdx[1] = vaFlags.tex1MatIdx())) - ++va.texMtxIdxCount; - if ((va.texMtxIdx[2] = vaFlags.tex2MatIdx())) - ++va.texMtxIdxCount; - if ((va.texMtxIdx[3] = vaFlags.tex3MatIdx())) - ++va.texMtxIdxCount; - if ((va.texMtxIdx[4] = vaFlags.tex4MatIdx())) - ++va.texMtxIdxCount; - if ((va.texMtxIdx[5] = vaFlags.tex5MatIdx())) - ++va.texMtxIdxCount; - if ((va.texMtxIdx[6] = vaFlags.tex6MatIdx())) - ++va.texMtxIdxCount; - - va.shortUVs = mat.getFlags().lightmapUVArray(); - } -} - -template -void ReadMaterialSetToBlender_1_2(hecl::blender::PyOutStream& os, const MaterialSet& matSet, const PAKRouter& pakRouter, - const typename PAKRouter::EntryType& entry, unsigned setIdx) { - /* Texmaps */ - os << "texmap_list = []\n"; - for (const UniqueID32& tex : matSet.head.textureIDs) { - std::string texName = pakRouter.getBestEntryName(tex); - const nod::Node* node; - const typename PAKRouter::EntryType* texEntry = pakRouter.lookupEntry(tex, &node); - hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry); - if (!txtrPath.isNone()) { - txtrPath.makeDirChain(false); - PAKEntryReadStream rs = texEntry->beginReadStream(*node); - TXTR::Extract(rs, txtrPath); - } - std::string resPath = pakRouter.getResourceRelativePath(entry, tex); - os.format(FMT_STRING("if '{}' in bpy.data.images:\n" - " image = bpy.data.images['{}']\n" - "else:\n" - " image = bpy.data.images.load('''//{}''')\n" - " image.name = '{}'\n" - "texmap_list.append(image)\n" - "\n"), - texName, texName, resPath, texName); - } - - unsigned m = 0; - for (const typename MaterialSet::Material& mat : matSet.materials) { - MaterialSet::ConstructMaterial(os, mat, setIdx, m++); - os << "materials.append(new_material)\n"; - } -} - -template -void ReadMaterialSetToBlender_3(hecl::blender::PyOutStream& os, const MaterialSet& matSet, const PAKRouter& pakRouter, - const typename PAKRouter::EntryType& entry, unsigned setIdx) { - unsigned m = 0; - for (const typename MaterialSet::Material& mat : matSet.materials) { - MaterialSet::ConstructMaterial(os, pakRouter, entry, mat, setIdx, m++); - os << "materials.append(new_material)\n"; - } -} - -template void ReadMaterialSetToBlender_3, DNAMP3::MaterialSet>( - hecl::blender::PyOutStream& os, const DNAMP3::MaterialSet& matSet, const PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, unsigned setIdx); - -class DLReader { -public: - /* Class used for splitting verts with shared positions but different skinning matrices */ - class ExtraVertTracker { - std::map>> m_extraVerts; - atUint16 m_maxBasePos = 0; - atUint16 m_nextOverPos = 1; - - public: - atInt16 addPosSkinPair(atUint16 pos, atInt16 skin) { - m_maxBasePos = std::max(m_maxBasePos, pos); - auto search = m_extraVerts.find(pos); - if (search == m_extraVerts.end()) { - m_extraVerts[pos] = {std::make_pair(skin, 0)}; - return skin; - } - std::vector>& vertTrack = search->second; - for (const std::pair& s : vertTrack) - if (s.first == skin) - return vertTrack.front().first; - vertTrack.push_back(std::make_pair(skin, m_nextOverPos++)); - return vertTrack.front().first; - } - - template - atUint32 sendAdditionalVertsToBlender(hecl::blender::PyOutStream& os, const RigPair& rp, atUint32 baseVert) const { - atUint32 addedVerts = 0; - atUint32 nextVert = 1; - while (nextVert < m_nextOverPos) { - for (const auto& [ev, evVec] : m_extraVerts) { - for (const std::pair& se : evVec) { - if (se.second == nextVert) { - os.format(FMT_STRING("bm.verts.ensure_lookup_table()\n" - "orig_vert = bm.verts[{}]\n" - "vert = bm.verts.new(orig_vert.co)\n"), - ev + baseVert); - rp.first.second->weightVertex(os, *rp.second.second, se.first); - ++nextVert; - ++addedVerts; - } - } - } - } - return addedVerts; - } - - atUint16 lookupVertIdx(atUint16 pos, atInt16 skin) const { - auto search = m_extraVerts.find(pos); - if (search == m_extraVerts.end()) - return -1; - const std::vector>& vertTrack = search->second; - if (vertTrack.front().first == skin) - return pos; - for (auto it = vertTrack.begin() + 1; it != vertTrack.end(); ++it) - if (it->first == skin) - return m_maxBasePos + it->second; - return -1; - } - }; - -private: - const VertexAttributes& m_va; - std::unique_ptr m_dl; - size_t m_dlSize; - ExtraVertTracker& m_evt; - const atInt16* m_bankIn; - atUint8* m_cur; - atUint16 readVal(GX::AttrType type) { - atUint16 retval = 0; - switch (type) { - case GX::DIRECT: - case GX::INDEX8: - if ((m_cur - m_dl.get()) >= intptr_t(m_dlSize)) - return 0; - retval = *m_cur; - ++m_cur; - break; - case GX::INDEX16: - if ((m_cur - m_dl.get() + 1) >= intptr_t(m_dlSize)) - return 0; - retval = hecl::SBig(*(atUint16*)m_cur); - m_cur += 2; - break; - default: - break; - } - return retval; - } - -public: - DLReader(const VertexAttributes& va, std::unique_ptr&& dl, size_t dlSize, ExtraVertTracker& evt, - const atInt16* bankIn = nullptr) - : m_va(va), m_dl(std::move(dl)), m_dlSize(dlSize), m_evt(evt), m_bankIn(bankIn) { - m_cur = m_dl.get(); - } - - explicit operator bool() const { return ((m_cur - m_dl.get()) < intptr_t(m_dlSize)) && *m_cur; } - - GX::Primitive readPrimitive() { return GX::Primitive(*m_cur++ & 0xf8); } - - GX::Primitive readPrimitiveAndVat(unsigned& vatOut) { - atUint8 val = *m_cur++; - vatOut = val & 0x7; - return GX::Primitive(val & 0xf8); - } - - atUint16 readVertCount() { - atUint16 retval = hecl::SBig(*(atUint16*)m_cur); - m_cur += 2; - return retval; - } - - struct DLPrimVert { - atUint16 pos = 0; - atUint16 norm = 0; - atUint16 color[2] = {0}; - atUint16 uvs[7] = {0}; - atUint8 pnMtxIdx = 0; - atUint8 texMtxIdx[7] = {0}; - }; - - DLPrimVert readVert(bool peek = false) { - atUint8* bakCur = m_cur; - DLPrimVert retval; - retval.pnMtxIdx = readVal(m_va.pnMtxIdx); - retval.texMtxIdx[0] = readVal(m_va.texMtxIdx[0]); - retval.texMtxIdx[1] = readVal(m_va.texMtxIdx[1]); - retval.texMtxIdx[2] = readVal(m_va.texMtxIdx[2]); - retval.texMtxIdx[3] = readVal(m_va.texMtxIdx[3]); - retval.texMtxIdx[4] = readVal(m_va.texMtxIdx[4]); - retval.texMtxIdx[5] = readVal(m_va.texMtxIdx[5]); - retval.texMtxIdx[6] = readVal(m_va.texMtxIdx[6]); - if (m_bankIn) { - atUint16 posIdx = readVal(m_va.pos); - atUint8 mtxIdx = retval.pnMtxIdx / 3; - atInt16 skinIdx = -1; - if (mtxIdx < 10) - skinIdx = m_bankIn[mtxIdx]; - retval.pos = m_evt.lookupVertIdx(posIdx, skinIdx); - } else - retval.pos = readVal(m_va.pos); - retval.norm = readVal(m_va.norm); - retval.color[0] = readVal(m_va.color0); - retval.color[1] = readVal(m_va.color1); - retval.uvs[0] = readVal(m_va.uvs[0]); - retval.uvs[1] = readVal(m_va.uvs[1]); - retval.uvs[2] = readVal(m_va.uvs[2]); - retval.uvs[3] = readVal(m_va.uvs[3]); - retval.uvs[4] = readVal(m_va.uvs[4]); - retval.uvs[5] = readVal(m_va.uvs[5]); - retval.uvs[6] = readVal(m_va.uvs[6]); - if (peek) - m_cur = bakCur; - return retval; - } - - void preReadMaxIdxs(DLPrimVert& out) { - atUint8* bakCur = m_cur; - while (*this) { - readPrimitive(); - atUint16 vc = readVertCount(); - for (atUint16 v = 0; v < vc; ++v) { - atUint16 val; - val = readVal(m_va.pnMtxIdx); - out.pnMtxIdx = std::max(out.pnMtxIdx, atUint8(val)); - val = readVal(m_va.texMtxIdx[0]); - out.texMtxIdx[0] = std::max(out.texMtxIdx[0], atUint8(val)); - val = readVal(m_va.texMtxIdx[1]); - out.texMtxIdx[1] = std::max(out.texMtxIdx[1], atUint8(val)); - val = readVal(m_va.texMtxIdx[2]); - out.texMtxIdx[2] = std::max(out.texMtxIdx[2], atUint8(val)); - val = readVal(m_va.texMtxIdx[3]); - out.texMtxIdx[3] = std::max(out.texMtxIdx[3], atUint8(val)); - val = readVal(m_va.texMtxIdx[4]); - out.texMtxIdx[4] = std::max(out.texMtxIdx[4], atUint8(val)); - val = readVal(m_va.texMtxIdx[5]); - out.texMtxIdx[5] = std::max(out.texMtxIdx[5], atUint8(val)); - val = readVal(m_va.texMtxIdx[6]); - out.texMtxIdx[6] = std::max(out.texMtxIdx[6], atUint8(val)); - val = readVal(m_va.pos); - out.pos = std::max(out.pos, val); - val = readVal(m_va.norm); - out.norm = std::max(out.norm, val); - val = readVal(m_va.color0); - out.color[0] = std::max(out.color[0], val); - val = readVal(m_va.color1); - out.color[1] = std::max(out.color[1], val); - val = readVal(m_va.uvs[0]); - out.uvs[0] = std::max(out.uvs[0], val); - val = readVal(m_va.uvs[1]); - out.uvs[1] = std::max(out.uvs[1], val); - val = readVal(m_va.uvs[2]); - out.uvs[2] = std::max(out.uvs[2], val); - val = readVal(m_va.uvs[3]); - out.uvs[3] = std::max(out.uvs[3], val); - val = readVal(m_va.uvs[4]); - out.uvs[4] = std::max(out.uvs[4], val); - val = readVal(m_va.uvs[5]); - out.uvs[5] = std::max(out.uvs[5], val); - val = readVal(m_va.uvs[6]); - out.uvs[6] = std::max(out.uvs[6], val); - } - } - m_cur = bakCur; - } - - void preReadMaxIdxs(DLPrimVert& out, std::vector& skinOut) { - atUint8* bakCur = m_cur; - while (*this) { - readPrimitive(); - atUint16 vc = readVertCount(); - for (atUint16 v = 0; v < vc; ++v) { - atUint16 val; - atUint8 pnMtxVal = readVal(m_va.pnMtxIdx); - out.pnMtxIdx = std::max(out.pnMtxIdx, pnMtxVal); - val = readVal(m_va.texMtxIdx[0]); - out.texMtxIdx[0] = std::max(out.texMtxIdx[0], atUint8(val)); - val = readVal(m_va.texMtxIdx[1]); - out.texMtxIdx[1] = std::max(out.texMtxIdx[1], atUint8(val)); - val = readVal(m_va.texMtxIdx[2]); - out.texMtxIdx[2] = std::max(out.texMtxIdx[2], atUint8(val)); - val = readVal(m_va.texMtxIdx[3]); - out.texMtxIdx[3] = std::max(out.texMtxIdx[3], atUint8(val)); - val = readVal(m_va.texMtxIdx[4]); - out.texMtxIdx[4] = std::max(out.texMtxIdx[4], atUint8(val)); - val = readVal(m_va.texMtxIdx[5]); - out.texMtxIdx[5] = std::max(out.texMtxIdx[5], atUint8(val)); - val = readVal(m_va.texMtxIdx[6]); - out.texMtxIdx[6] = std::max(out.texMtxIdx[6], atUint8(val)); - atUint16 posVal = readVal(m_va.pos); - out.pos = std::max(out.pos, posVal); - val = readVal(m_va.norm); - out.norm = std::max(out.norm, val); - val = readVal(m_va.color0); - out.color[0] = std::max(out.color[0], val); - val = readVal(m_va.color1); - out.color[1] = std::max(out.color[1], val); - val = readVal(m_va.uvs[0]); - out.uvs[0] = std::max(out.uvs[0], val); - val = readVal(m_va.uvs[1]); - out.uvs[1] = std::max(out.uvs[1], val); - val = readVal(m_va.uvs[2]); - out.uvs[2] = std::max(out.uvs[2], val); - val = readVal(m_va.uvs[3]); - out.uvs[3] = std::max(out.uvs[3], val); - val = readVal(m_va.uvs[4]); - out.uvs[4] = std::max(out.uvs[4], val); - val = readVal(m_va.uvs[5]); - out.uvs[5] = std::max(out.uvs[5], val); - val = readVal(m_va.uvs[6]); - out.uvs[6] = std::max(out.uvs[6], val); - - atInt16 skinIdx = m_bankIn[pnMtxVal / 3]; - skinOut[posVal] = m_evt.addPosSkinPair(posVal, skinIdx); - } - } - m_cur = bakCur; - } -}; - -void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath) { - os << "import math\n" - "from mathutils import Vector\n" - "\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "def loop_from_facevert(bm, face, vert_idx):\n" - " for loop in face.loops:\n" - " if loop.vert[bm.verts.layers.int['CMDLOriginalPosIdxs']] == vert_idx:\n" - " return loop\n" - "\n" - "def loops_from_edgevert(bm, edge, vert):\n" - " ret = []\n" - " for face in edge.link_faces:\n" - " for loop in face.loops:\n" - " if loop.vert == vert:\n" - " ret.append(loop)\n" - " return ret\n" - "\n" - "def add_triangle(bm, vert_seq, vert_indices, norm_seq, norm_indices, mat_nr, od_list, two_face_vert):\n" - " if len(set(vert_indices)) != 3:\n" - " return None, None\n" - "\n" - " ret_mesh = bm\n" - " vert_seq.ensure_lookup_table()\n" - " verts = [vert_seq[i] for i in vert_indices]\n" - "\n" - " # Try getting existing face\n" - " face = bm.faces.get(verts)\n" - "\n" - " if face is not None and face.material_index != mat_nr: # Same poly, new material\n" - " # Overdraw detected; track copy\n" - " od_entry = None\n" - " for entry in od_list:\n" - " if entry['material'] == mat_nr:\n" - " od_entry = entry\n" - " if od_entry is None:\n" - " bm_cpy = bm.copy()\n" - " od_entry = {'material':mat_nr, 'bm':bm_cpy}\n" - " bmesh.ops.delete(od_entry['bm'], geom=od_entry['bm'].faces, context='FACES_ONLY')\n" - " od_list.append(od_entry)\n" - " od_entry['bm'].verts.ensure_lookup_table()\n" - " verts = [od_entry['bm'].verts[i] for i in vert_indices]\n" - " face = od_entry['bm'].faces.get(verts)\n" - " if face is None:\n" - " face = od_entry['bm'].faces.new(verts)\n" - " else: # Probably a double-sided surface\n" - " verts = [od_entry['bm'].verts[i + two_face_vert] for i in vert_indices]\n" - " face = od_entry['bm'].faces.get(verts)\n" - " if face is None:\n" - " face = od_entry['bm'].faces.new(verts)\n" - " ret_mesh = od_entry['bm']\n" - "\n" - " elif face is not None: # Same material, probably double-sided\n" - " verts = [vert_seq[i + two_face_vert] for i in vert_indices]\n" - " face = bm.faces.get(verts)\n" - " if face is None:\n" - " face = bm.faces.new(verts)\n" - "\n" - " else: # Make totally new face\n" - " face = bm.faces.new(verts)\n" - "\n" - " for i in range(3):\n" - " face.verts[i][ret_mesh.verts.layers.int['CMDLOriginalPosIdxs']] = vert_indices[i]\n" - " face.loops[i][ret_mesh.loops.layers.int['CMDLOriginalNormIdxs']] = norm_indices[i]\n" - " face.material_index = mat_nr\n" - " face.smooth = True\n" - "\n" - " return face, ret_mesh\n" - "\n" - "def expand_lightmap_triangle(lightmap_tri_tracker, uva, uvb, uvc):\n" - " result = ([uva[0],uva[1]], [uvb[0],uvb[1]], [uvc[0],uvc[1]])\n" - " inst = 0\n" - " if uva in lightmap_tri_tracker:\n" - " inst = lightmap_tri_tracker[uva]\n" - " lightmap_tri_tracker[uva] = inst + 1\n" - " if uva == uvb:\n" - " result[1][0] += 0.005\n" - " if uva == uvc:\n" - " result[2][1] -= 0.005\n" - " if inst & 0x1 and uva == uvb and uva == uvc:\n" - " result[0][0] += 0.005\n" - " result[0][1] -= 0.005\n" - " return result\n" - "\n"; - - /* Link master shader library */ - os.format(FMT_STRING("# Master shader library\n" - "with bpy.data.libraries.load('{}', link=True, relative=True) as (data_from, data_to):\n" - " data_to.node_groups = data_from.node_groups\n" - "\n"), - masterShaderPath.getAbsolutePath()); -} - -void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int meshIdx) { - os << "if 'Render' not in bpy.data.collections:\n" - " coll = bpy.data.collections.new('Render')\n" - " bpy.context.scene.collection.children.link(coll)\n" - "else:\n" - " coll = bpy.data.collections['Render']\n"; - if (meshIdx < 0) { - os << "mesh = bpy.data.meshes.new(bpy.context.scene.name)\n" - "obj = bpy.data.objects.new(mesh.name, mesh)\n" - "obj.show_transparent = True\n" - "coll.objects.link(obj)\n"; - os.format(FMT_STRING("mesh.hecl_material_count = {}\n"), matSetCount); - } else { - os.format(FMT_STRING("mesh = bpy.data.meshes.new(bpy.context.scene.name + '_{:03d}')\n"), meshIdx); - os << "obj = bpy.data.objects.new(mesh.name, mesh)\n" - "obj.show_transparent = True\n" - "coll.objects.link(obj)\n"; - os.format(FMT_STRING("mesh.hecl_material_count = {}\n"), matSetCount); - } - - os << "mesh.use_auto_smooth = True\n" - "mesh.auto_smooth_angle = math.pi\n" - "\n" - "for material in materials:\n" - " mesh.materials.append(material)\n" - "\n" - "# Merge OD meshes\n" - "for od_entry in od_list:\n" - " vert_dict = [{},{}]\n" - "\n" - " for vert in od_entry['bm'].verts:\n" - " if len(vert.link_faces):\n" - " if vert.index >= two_face_vert:\n" - " use_vert_dict = vert_dict[1]\n" - " else:\n" - " use_vert_dict = vert_dict[0]\n" - " copy_vert = bm.verts.new(vert.co, vert)\n" - " use_vert_dict[vert[od_entry['bm'].verts.layers.int['CMDLOriginalPosIdxs']]] = copy_vert\n" - " copy_vert[orig_pidx_lay] = vert[od_entry['bm'].verts.layers.int['CMDLOriginalPosIdxs']]\n" - "\n" - " for face in od_entry['bm'].faces:\n" - " if face.verts[0].index >= two_face_vert:\n" - " use_vert_dict = vert_dict[1]\n" - " else:\n" - " use_vert_dict = vert_dict[0]\n" - " merge_verts = [use_vert_dict[fv[od_entry['bm'].verts.layers.int['CMDLOriginalPosIdxs']]] for fv in " - "face.verts]\n" - " try:\n" - " if bm.faces.get(merge_verts) is not None:\n" - " continue\n" - " except:\n" - " continue\n" - " merge_face = bm.faces.new(merge_verts)\n" - " for i in range(len(face.loops)):\n" - " old = face.loops[i]\n" - " new = merge_face.loops[i]\n" - " for j in range(len(od_entry['bm'].loops.layers.uv)):\n" - " new[bm.loops.layers.uv[j]] = old[od_entry['bm'].loops.layers.uv[j]]\n" - " new[orig_nidx_lay] = old[od_entry['bm'].loops.layers.int['CMDLOriginalNormIdxs']]\n" - " merge_face.smooth = True\n" - " merge_face.material_index = face.material_index\n" - "\n" - " od_entry['bm'].free()\n" - "\n" - "verts_to_del = []\n" - "for v in bm.verts:\n" - " if len(v.link_faces) == 0:\n" - " verts_to_del.append(v)\n" - "bmesh.ops.delete(bm, geom=verts_to_del, context='VERTS')\n" - "\n" - "for edge in bm.edges:\n" - " if edge.is_manifold:\n" - " pass_count = 0\n" - " for vert in edge.verts:\n" - " loops = loops_from_edgevert(bm, edge, vert)\n" - " norm0 = Vector(norm_list[loops[0][orig_nidx_lay]])\n" - " norm1 = Vector(norm_list[loops[1][orig_nidx_lay]])\n" - " if norm0.dot(norm1) < 0.9:\n" - " pass_count += 1\n" - " if pass_count > 0:\n" - " edge.smooth = False\n" - "\n" - "bm.to_mesh(mesh)\n" - "bm.free()\n" - "\n" - "# Remove redundant materials\n" - "present_mats = set()\n" - "for poly in mesh.polygons:\n" - " present_mats.add(poly.material_index)\n" - "for mat_idx in reversed(range(len(mesh.materials))):\n" - " if mat_idx not in present_mats:\n" - " mesh.materials.pop(index=mat_idx)\n" - "\n" - "mesh.update()\n" - "\n"; -} - -template -atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, athena::io::IStreamReader& reader, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const RigPair& rp, - bool shortNormals, bool shortUVs, std::vector& vertAttribs, - int meshIdx, atUint32 secCount, atUint32 matSetCount, const atUint32* secSizes, - atUint32 surfaceCount) { - os << "# Begin bmesh\n" - "bm = bmesh.new()\n" - "\n" - "# Overdraw-tracking\n" - "od_list = []\n" - "\n" - "orig_pidx_lay = bm.verts.layers.int.new('CMDLOriginalPosIdxs')\n" - "orig_nidx_lay = bm.loops.layers.int.new('CMDLOriginalNormIdxs')\n" - "\n" - "lightmap_tri_tracker = {}\n"; - - if (rp.first.second) - os << "dvert_lay = bm.verts.layers.deform.verify()\n"; - - /* Pre-read pass to determine maximum used vert indices */ - atUint32 matSecCount = 0; - if (matSetCount) - matSecCount = MaterialSet::OneSection() ? 1 : matSetCount; - bool visitedDLOffsets = false; - atUint32 lastDlSec = secCount; - atUint64 afterHeaderPos = reader.position(); - DLReader::DLPrimVert maxIdxs; - std::vector skinIndices; - DLReader::ExtraVertTracker extraTracker; - for (atUint32 s = 0; s < lastDlSec; ++s) { - atUint64 secStart = reader.position(); - if (s < matSecCount) { - if (!s) { - MaterialSet matSet; - matSet.read(reader); - matSet.ensureTexturesExtracted(pakRouter); - GetVertexAttributes(matSet, vertAttribs); - } - } else { - switch (s - matSecCount) { - case 0: { - /* Positions */ - if (SurfaceHeader::UseMatrixSkinning() && rp.first.second) - skinIndices.assign(secSizes[s] / 12, -1); - break; - } - case 1: { - /* Normals */ - break; - } - case 2: { - /* Colors */ - break; - } - case 3: { - /* Float UVs */ - break; - } - case 4: { - if (surfaceCount) { - /* MP3 MREA case */ - visitedDLOffsets = true; - lastDlSec = 4 + surfaceCount; - } else { - /* Short UVs */ - if (shortUVs) - break; - - /* DL Offsets (here or next section) */ - visitedDLOffsets = true; - lastDlSec = s + reader.readUint32Big() + 1; - break; - } - [[fallthrough]]; - } - default: { - if (!visitedDLOffsets) { - visitedDLOffsets = true; - lastDlSec = s + reader.readUint32Big() + 1; - break; - } - - /* GX Display List (surface) */ - SurfaceHeader sHead; - sHead.read(reader); - const atInt16* bankIn = nullptr; - if (SurfaceHeader::UseMatrixSkinning() && rp.first.second) - bankIn = rp.first.second->getMatrixBank(sHead.skinMatrixBankIdx()); - - /* Do max index pre-read */ - atUint32 realDlSize = secSizes[s] - (reader.position() - secStart); - DLReader dl(vertAttribs[sHead.matIdx], reader.readUBytes(realDlSize), realDlSize, extraTracker, bankIn); - if (SurfaceHeader::UseMatrixSkinning() && rp.first.second) - dl.preReadMaxIdxs(maxIdxs, skinIndices); - else - dl.preReadMaxIdxs(maxIdxs); - } - } - } - - if (s < secCount - 1) { - reader.seek(secStart + secSizes[s], athena::SeekOrigin::Begin); - } - } - - reader.seek(afterHeaderPos, athena::SeekOrigin::Begin); - - visitedDLOffsets = false; - unsigned createdUVLayers = 0; - unsigned surfIdx = 0; - - for (atUint32 s = 0; s < lastDlSec; ++s) { - atUint64 secStart = reader.position(); - if (s < matSecCount) { - MaterialSet matSet; - matSet.read(reader); - matSet.readToBlender(os, pakRouter, entry, s); - if (!s) - GetVertexAttributes(matSet, vertAttribs); - } else { - switch (s - matSecCount) { - case 0: { - /* Positions */ - atUint32 vertCount = maxIdxs.pos + 1; - std::vector positions; - positions.reserve(vertCount); - for (atUint16 i = 0; i <= maxIdxs.pos; ++i) { - positions.push_back(reader.readVec3fBig()); - const atVec3f& pos = positions.back(); - os.format(FMT_STRING("vert = bm.verts.new(({},{},{}))\n"), pos.simd[0], pos.simd[1], pos.simd[2]); - if (rp.first.second) { - if (SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty()) - rp.first.second->weightVertex(os, *rp.second.second, skinIndices[i]); - else if (!SurfaceHeader::UseMatrixSkinning()) - rp.first.second->weightVertex(os, *rp.second.second, i); - } - } - if (rp.first.second && SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty()) - vertCount += extraTracker.sendAdditionalVertsToBlender(os, rp, 0); - os.format(FMT_STRING("two_face_vert = {}\n"), vertCount); - for (atUint16 i = 0; i <= maxIdxs.pos; ++i) { - const atVec3f& pos = positions[i]; - os.format(FMT_STRING("vert = bm.verts.new(({},{},{}))\n"), pos.simd[0], pos.simd[1], pos.simd[2]); - if (rp.first.second) { - if (SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty()) - rp.first.second->weightVertex(os, *rp.second.second, skinIndices[i]); - else if (!SurfaceHeader::UseMatrixSkinning()) - rp.first.second->weightVertex(os, *rp.second.second, i); - } - } - if (rp.first.second && SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty()) - extraTracker.sendAdditionalVertsToBlender(os, rp, vertCount); - break; - } - case 1: { - /* Normals */ - os << "norm_list = []\n"; - if (shortNormals) { - atUint32 normCount = secSizes[s] / 6; - for (atUint32 i = 0; i < normCount; ++i) { - float x = reader.readInt16Big() / 16384.0f; - float y = reader.readInt16Big() / 16384.0f; - float z = reader.readInt16Big() / 16384.0f; - os.format(FMT_STRING("norm_list.append(({},{},{}))\n"), x, y, z); - } - } else { - atUint32 normCount = secSizes[s] / 12; - for (atUint32 i = 0; i < normCount; ++i) { - const atVec3f norm = reader.readVec3fBig(); - os.format(FMT_STRING("norm_list.append(({},{},{}))\n"), norm.simd[0], norm.simd[1], norm.simd[2]); - } - } - break; - } - case 2: { - /* Colors */ - break; - } - case 3: { - /* Float UVs */ - os << "uv_list = []\n"; - atUint32 uvCount = secSizes[s] / 8; - for (atUint32 i = 0; i < uvCount; ++i) { - const atVec2f uv = reader.readVec2fBig(); - os.format(FMT_STRING("uv_list.append(({},{}))\n"), uv.simd[0], uv.simd[1]); - } - break; - } - case 4: { - if (surfaceCount) { - /* MP3 MREA case */ - visitedDLOffsets = true; - } else { - /* Short UVs */ - os << "suv_list = []\n"; - if (shortUVs) { - atUint32 uvCount = secSizes[s] / 4; - for (atUint32 i = 0; i < uvCount; ++i) { - float x = reader.readInt16Big() / 32768.0f; - float y = reader.readInt16Big() / 32768.0f; - os.format(FMT_STRING("suv_list.append(({},{}))\n"), x, y); - } - break; - } - - /* DL Offsets (here or next section) */ - visitedDLOffsets = true; - break; - } - [[fallthrough]]; - } - default: { - if (!visitedDLOffsets) { - visitedDLOffsets = true; - break; - } - - /* GX Display List (surface) */ - SurfaceHeader sHead; - sHead.read(reader); - VertexAttributes& curVA = vertAttribs[sHead.matIdx]; - unsigned matUVCount = curVA.uvCount; - bool matShortUVs = curVA.shortUVs; - const atInt16* bankIn = nullptr; - if (SurfaceHeader::UseMatrixSkinning() && rp.first.second) - bankIn = rp.first.second->getMatrixBank(sHead.skinMatrixBankIdx()); - - os.format(FMT_STRING("materials[{}].pass_index = {}\n"), sHead.matIdx, surfIdx++); - if (matUVCount > createdUVLayers) { - for (unsigned l = createdUVLayers; l < matUVCount; ++l) - os.format(FMT_STRING("bm.loops.layers.uv.new('UV_{}')\n"), l); - createdUVLayers = matUVCount; - } - - atUint32 realDlSize = secSizes[s] - (reader.position() - secStart); - DLReader dl(vertAttribs[sHead.matIdx], reader.readUBytes(realDlSize), realDlSize, extraTracker, bankIn); - - while (dl) { - GX::Primitive ptype = dl.readPrimitive(); - atUint16 vertCount = dl.readVertCount(); - - /* First vert */ - DLReader::DLPrimVert firstPrimVert = dl.readVert(true); - - /* 3 Prim Verts to start */ - int c = 0; - DLReader::DLPrimVert primVerts[3] = {dl.readVert(), dl.readVert(), dl.readVert()}; - - if (ptype == GX::TRIANGLESTRIP) { - atUint8 flip = 0; - for (int v = 0; v < vertCount - 2; ++v) { - if (flip) { - os.format(FMT_STRING("last_face, last_mesh = add_triangle(bm, bm.verts, ({},{},{}), norm_list, " - "({},{},{}), {}, od_list, " - "two_face_vert)\n"), - primVerts[c % 3].pos, primVerts[(c + 2) % 3].pos, primVerts[(c + 1) % 3].pos, - primVerts[c % 3].norm, primVerts[(c + 2) % 3].norm, primVerts[(c + 1) % 3].norm, - sHead.matIdx); - if (matUVCount) { - os << "if last_face is not None:\n"; - for (unsigned j = 0; j < matUVCount; ++j) { - if (j == 0 && matShortUVs) - os.format( - FMT_STRING( - " uv_tri = expand_lightmap_triangle(lightmap_tri_tracker, suv_list[{}], suv_list[{}], " - "suv_list[{}])\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[0]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[1]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[2]\n"), - primVerts[c % 3].uvs[j], primVerts[(c + 2) % 3].uvs[j], primVerts[(c + 1) % 3].uvs[j], - primVerts[c % 3].pos, j, primVerts[(c + 2) % 3].pos, j, primVerts[(c + 1) % 3].pos, j); - else - os.format( - FMT_STRING( - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n"), - primVerts[c % 3].pos, j, primVerts[c % 3].uvs[j], primVerts[(c + 2) % 3].pos, j, - primVerts[(c + 2) % 3].uvs[j], primVerts[(c + 1) % 3].pos, j, primVerts[(c + 1) % 3].uvs[j]); - } - } - } else { - os.format(FMT_STRING("last_face, last_mesh = add_triangle(bm, bm.verts, ({},{},{}), norm_list, " - "({},{},{}), {}, od_list, " - "two_face_vert)\n"), - primVerts[c % 3].pos, primVerts[(c + 1) % 3].pos, primVerts[(c + 2) % 3].pos, - primVerts[c % 3].norm, primVerts[(c + 1) % 3].norm, primVerts[(c + 2) % 3].norm, - sHead.matIdx); - if (matUVCount) { - os << "if last_face is not None:\n"; - for (unsigned j = 0; j < matUVCount; ++j) { - if (j == 0 && matShortUVs) - os.format( - FMT_STRING( - " uv_tri = expand_lightmap_triangle(lightmap_tri_tracker, suv_list[{}], suv_list[{}], " - "suv_list[{}])\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[0]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[1]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[2]\n"), - primVerts[c % 3].uvs[j], primVerts[(c + 1) % 3].uvs[j], primVerts[(c + 2) % 3].uvs[j], - primVerts[c % 3].pos, j, primVerts[(c + 1) % 3].pos, j, primVerts[(c + 2) % 3].pos, j); - else - os.format( - FMT_STRING( - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n"), - primVerts[c % 3].pos, j, primVerts[c % 3].uvs[j], primVerts[(c + 1) % 3].pos, j, - primVerts[(c + 1) % 3].uvs[j], primVerts[(c + 2) % 3].pos, j, primVerts[(c + 2) % 3].uvs[j]); - } - } - } - flip ^= 1; - - bool peek = (v >= vertCount - 3); - - /* Advance one prim vert */ - primVerts[c % 3] = dl.readVert(peek); - ++c; - } - } else if (ptype == GX::TRIANGLES) { - for (int v = 0; v < vertCount; v += 3) { - - os.format(FMT_STRING("last_face, last_mesh = add_triangle(bm, bm.verts, ({},{},{}), norm_list, " - "({},{},{}), {}, od_list, " - "two_face_vert)\n"), - primVerts[0].pos, primVerts[1].pos, primVerts[2].pos, primVerts[0].norm, primVerts[1].norm, - primVerts[2].norm, sHead.matIdx); - if (matUVCount) { - os << "if last_face is not None:\n"; - for (unsigned j = 0; j < matUVCount; ++j) { - if (j == 0 && matShortUVs) - os.format( - FMT_STRING( - " uv_tri = expand_lightmap_triangle(lightmap_tri_tracker, suv_list[{}], suv_list[{}], " - "suv_list[{}])\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[0]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[1]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[2]\n"), - primVerts[0].uvs[j], primVerts[1].uvs[j], primVerts[2].uvs[j], primVerts[0].pos, j, - primVerts[1].pos, j, primVerts[2].pos, j); - else - os.format( - FMT_STRING( - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n"), - primVerts[0].pos, j, primVerts[0].uvs[j], primVerts[1].pos, j, primVerts[1].uvs[j], - primVerts[2].pos, j, primVerts[2].uvs[j]); - } - } - - /* Break if done */ - if (v + 3 >= vertCount) - break; - - /* Advance 3 Prim Verts */ - for (int pv = 0; pv < 3; ++pv) - primVerts[pv] = dl.readVert(); - } - } else if (ptype == GX::TRIANGLEFAN) { - ++c; - for (int v = 0; v < vertCount - 2; ++v) { - os.format(FMT_STRING("last_face, last_mesh = add_triangle(bm, bm.verts, ({},{},{}), norm_list, " - "({},{},{}), {}, od_list, " - "two_face_vert)\n"), - firstPrimVert.pos, primVerts[c % 3].pos, primVerts[(c + 1) % 3].pos, firstPrimVert.norm, - primVerts[c % 3].norm, primVerts[(c + 1) % 3].norm, sHead.matIdx); - if (matUVCount) { - os << "if last_face is not None:\n"; - for (unsigned j = 0; j < matUVCount; ++j) { - if (j == 0 && matShortUVs) - os.format( - FMT_STRING( - " uv_tri = expand_lightmap_triangle(lightmap_tri_tracker, suv_list[{}], suv_list[{}], " - "suv_list[{}])\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[0]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[1]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[2]\n"), - firstPrimVert.uvs[j], primVerts[c % 3].uvs[j], primVerts[(c + 1) % 3].uvs[j], firstPrimVert.pos, - j, primVerts[c % 3].pos, j, primVerts[(c + 1) % 3].pos, j); - else - os.format( - FMT_STRING( - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n"), - firstPrimVert.pos, j, firstPrimVert.uvs[j], primVerts[c % 3].pos, j, primVerts[c % 3].uvs[j], - primVerts[(c + 1) % 3].pos, j, primVerts[(c + 1) % 3].uvs[j]); - } - } - - /* Break if done */ - if (v + 3 >= vertCount) - break; - - /* Advance one prim vert */ - primVerts[(c + 2) % 3] = dl.readVert(); - ++c; - } - } - os << "\n"; - } - } - } - } - - if (s < secCount - 1) { - reader.seek(secStart + secSizes[s], athena::SeekOrigin::Begin); - } - } - - /* Finish Mesh */ - FinishBlenderMesh(os, matSetCount, meshIdx); - - if (rp.first.second) { - if (entry.id != 0xB333E1D7) { - // This is the beta phazon suit, we want the (incorrect) weight information, but we don't want to keep the CSKR id - os.format(FMT_STRING("mesh.cskr_id = '{}'\n"), rp.first.first); - } - rp.second.second->sendVertexGroupsToBlender(os); - } - - return lastDlSec; -} - -template atUint32 -ReadGeomSectionsToBlender, DNAMP1::MaterialSet, - std::pair, std::pair>, - DNACMDL::SurfaceHeader_1>( - hecl::blender::PyOutStream& os, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - const std::pair, std::pair>& rp, bool shortNormals, - bool shortUVs, std::vector& vertAttribs, int meshIdx, atUint32 secCount, atUint32 matSetCount, - const atUint32* secSizes, atUint32 surfaceCount); - -template atUint32 -ReadGeomSectionsToBlender, DNAMP2::MaterialSet, - std::pair, std::pair>, - DNACMDL::SurfaceHeader_2>( - hecl::blender::PyOutStream& os, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - const std::pair, std::pair>& rp, bool shortNormals, - bool shortUVs, std::vector& vertAttribs, int meshIdx, atUint32 secCount, atUint32 matSetCount, - const atUint32* secSizes, atUint32 surfaceCount); - -template atUint32 -ReadGeomSectionsToBlender, DNAMP3::MaterialSet, - std::pair, std::pair>, - DNACMDL::SurfaceHeader_3>( - hecl::blender::PyOutStream& os, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - const std::pair, std::pair>& rp, bool shortNormals, - bool shortUVs, std::vector& vertAttribs, int meshIdx, atUint32 secCount, atUint32 matSetCount, - const atUint32* secSizes, atUint32 surfaceCount); - -template -bool ReadCMDLToBlender(hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const typename PAKRouter::EntryType& entry, const SpecBase& dataspec, const RigPair& rp) { - Header head; - head.read(reader); - - if (head.magic != 0xDEADBABE) { - LogDNACommon.report(logvisor::Error, FMT_STRING("invalid CMDL magic")); - return false; - } - - if (head.version != Version) { - LogDNACommon.report(logvisor::Error, FMT_STRING("invalid CMDL version")); - return false; - } - - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os.format(FMT_STRING("import bpy\n" - "import bmesh\n" - "\n" - "bpy.context.scene.name = '{}'\n" - "bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n"), - pakRouter.getBestEntryName(entry)); - InitGeomBlenderContext(os, dataspec.getMasterShaderPath()); - MaterialSet::RegisterMaterialProps(os); - - os << "# Materials\n" - "materials = []\n" - "\n"; - - std::vector vertAttribs; - ReadGeomSectionsToBlender( - os, reader, pakRouter, entry, rp, head.flags.shortNormals(), head.flags.shortUVs(), vertAttribs, -1, - head.secCount, head.matSetCount, head.secSizes.data()); - - return true; -} - -template bool ReadCMDLToBlender, DNAMP1::MaterialSet, - std::pair, std::pair>, - DNACMDL::SurfaceHeader_1, 2>( - hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, const SpecBase& dataspec, - const std::pair, std::pair>& rp); - -template bool ReadCMDLToBlender, DNAMP2::MaterialSet, - std::pair, std::pair>, - DNACMDL::SurfaceHeader_2, 4>( - hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, const SpecBase& dataspec, - const std::pair, std::pair>& rp); - -template bool ReadCMDLToBlender, DNAMP3::MaterialSet, - std::pair, std::pair>, - DNACMDL::SurfaceHeader_3, 4>( - hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, const SpecBase& dataspec, - const std::pair, std::pair>& rp); - -template bool ReadCMDLToBlender, DNAMP3::MaterialSet, - std::pair, std::pair>, - DNACMDL::SurfaceHeader_3, 5>( - hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, const SpecBase& dataspec, - const std::pair, std::pair>& rp); - -template -void NameCMDL(athena::io::IStreamReader& reader, PAKRouter& pakRouter, typename PAKRouter::EntryType& entry, - const SpecBase& dataspec) { - Header head; - head.read(reader); - std::string bestName = fmt::format(FMT_STRING("CMDL_{}"), entry.id); - - /* Pre-read pass to determine maximum used vert indices */ - atUint32 matSecCount = 0; - if (head.matSetCount) - matSecCount = MaterialSet::OneSection() ? 1 : head.matSetCount; - atUint32 lastDlSec = head.secCount; - for (atUint32 s = 0; s < lastDlSec; ++s) { - atUint64 secStart = reader.position(); - if (s < matSecCount) { - MaterialSet matSet; - matSet.read(reader); - matSet.nameTextures(pakRouter, bestName.c_str(), s); - } - - if (s < head.secCount - 1) { - reader.seek(secStart + head.secSizes[s], athena::SeekOrigin::Begin); - } - } -} - -template void NameCMDL, DNAMP1::MaterialSet>( - athena::io::IStreamReader& reader, PAKRouter& pakRouter, - PAKRouter::EntryType& entry, const SpecBase& dataspec); - -template -static void WriteDLVal(W& writer, GX::AttrType type, atUint32 val) { - switch (type) { - case GX::DIRECT: - case GX::INDEX8: - writer.writeUByte(atUint8(val)); - break; - case GX::INDEX16: - writer.writeUint16Big(atUint16(val)); - break; - default: - break; - } -} - -template -bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh) { - bool skinned = !mesh.skins.empty(); - - Header head; - head.magic = 0xDEADBABE; - head.version = Version; - head.flags.setSkinned(skinned); - head.flags.setShortNormals(!skinned); - head.flags.setShortUVs(true); /* This just means there's an (empty) short UV section */ - head.aabbMin = mesh.aabbMin.val; - head.aabbMax = mesh.aabbMax.val; - head.matSetCount = mesh.materialSets.size(); - head.secCount = head.matSetCount + 6 + mesh.surfaces.size(); - head.secSizes.reserve(head.secCount); - - /* Lengths of padding to insert while writing */ - std::vector paddingSizes; - paddingSizes.reserve(head.secCount); - - /* Build material sets */ - std::vector matSets; -#if 0 - matSets.reserve(mesh.materialSets.size()); - { - for (const std::vector& mset : mesh.materialSets) { - matSets.emplace_back(); - MaterialSet& targetMSet = matSets.back(); - std::vector texPaths; - std::vector setBackends; - setBackends.reserve(mset.size()); - - size_t endOff = 0; - for (const Material& mat : mset) { - std::string diagName = fmt::format(FMT_STRING("{}:{}"), inPath.getLastComponent(), mat.name); - hecl::Frontend::IR matIR = FE.compileSource(mat.source, diagName); - setBackends.emplace_back(); - hecl::Backend::GX& matGX = setBackends.back(); - matGX.reset(matIR, FE.getDiagnostics()); - - targetMSet.materials.emplace_back(matGX, mat.iprops, mat.texs, texPaths, mesh.colorLayerCount, false, false); - - targetMSet.materials.back().binarySize(endOff); - targetMSet.head.addMaterialEndOff(endOff); - } - - texPaths.reserve(mset.size() * 4); - for (const Material& mat : mset) { - for (const hecl::ProjectPath& path : mat.texs) { - bool found = false; - for (const hecl::ProjectPath& ePath : texPaths) { - if (path == ePath) { - found = true; - break; - } - } - if (!found) - texPaths.push_back(path); - } - } - - for (const hecl::ProjectPath& path : texPaths) - targetMSet.head.addTexture(path); - - size_t secSz = 0; - targetMSet.binarySize(secSz); - size_t secSz32 = ROUND_UP_32(secSz); - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - } - } -#endif - - /* Vertex Positions */ - size_t secSz = mesh.pos.size() * 12; - size_t secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* Vertex Normals */ - secSz = mesh.norm.size() * (skinned ? 12 : 6); - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* Vertex Colors */ - secSz = mesh.color.size() * 4; - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* UV coords */ - secSz = mesh.uv.size() * 8; - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* LUV coords */ - secSz = 0; - secSz32 = ROUND_UP_32(secSz); - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* Surface index */ - std::vector surfEndOffs; - surfEndOffs.reserve(mesh.surfaces.size()); - secSz = mesh.surfaces.size() * 4 + 4; - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* Surfaces */ - size_t endOff = 0; - size_t firstSurfSec = head.secSizes.size(); - for (const Mesh::Surface& surf : mesh.surfaces) { - size_t vertSz = matSets.at(0).materials.at(surf.materialIdx).getVAFlags().vertDLSize(); - if (surf.verts.size() > 65536) - LogDNACommon.report(logvisor::Fatal, FMT_STRING("GX DisplayList overflow")); - size_t secSz = 64; - for (auto it = surf.verts.cbegin(); it != surf.verts.cend();) { - atUint16 vertCount = 0; - auto itEnd = surf.verts.cend(); - for (auto it2 = it; it2 != surf.verts.cend(); ++it2, ++vertCount) - if (it2->iPos == 0xffffffff) { - if (vertCount == 3) { - /* All primitives here on out are triangles */ - vertCount = atUint16((surf.verts.cend() - it + 1) * 3 / 4); - break; - } - itEnd = it2; - break; - } - secSz += 3 + vertCount * vertSz; - if (itEnd == surf.verts.cend()) - break; - it = itEnd + 1; - } - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - endOff += secSz32; - surfEndOffs.push_back(endOff); - } - - /* Write sections */ - athena::io::FileWriter writer(outPath.getAbsolutePath()); - head.write(writer); - std::vector::const_iterator padIt = paddingSizes.cbegin(); - - /* Material Sets */ - for (const MaterialSet& mset : matSets) { - mset.write(writer); - writer.fill(atUint8(0), *padIt); - ++padIt; - } - - /* Vertex Positions */ - for (const atVec3f& pos : mesh.pos) - writer.writeVec3fBig(pos); - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* Vertex Normals */ - for (const atVec3f& norm : mesh.norm) { - if (skinned) { - writer.writeVec3fBig(norm); - } else { - for (int i = 0; i < 3; ++i) { - int tmpV = int(norm.simd[i] * 16384.f); - tmpV = zeus::clamp(-32768, tmpV, 32767); - writer.writeInt16Big(atInt16(tmpV)); - } - } - } - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* Vertex Colors */ - for (const atVec3f& col : mesh.color) { - GX::Color qCol(col); - qCol.write(writer); - } - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* UV coords */ - for (const atVec2f& uv : mesh.uv) - writer.writeVec2fBig(uv); - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* LUV coords */ - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* Surface index */ - writer.writeUint32Big(surfEndOffs.size()); - for (size_t off : surfEndOffs) - writer.writeUint32Big(off); - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* Surfaces */ - GX::Primitive prim = GX::TRIANGLES; - if (mesh.topology == hecl::HMDLTopology::Triangles) - prim = GX::TRIANGLES; - else if (mesh.topology == hecl::HMDLTopology::TriStrips) - prim = GX::TRIANGLESTRIP; - else - LogDNACommon.report(logvisor::Fatal, FMT_STRING("unrecognized mesh output mode")); - auto surfSizeIt = head.secSizes.begin() + firstSurfSec; - for (const Mesh::Surface& surf : mesh.surfaces) { - const typename MaterialSet::Material::VAFlags& vaFlags = matSets.at(0).materials.at(surf.materialIdx).getVAFlags(); - - SurfaceHeader header; - header.centroid = surf.centroid; - header.matIdx = surf.materialIdx; - header.dlSize = (*surfSizeIt++ - 64) | 0x80000000; - header.reflectionNormal = surf.reflectionNormal; - header.write(writer); - - GX::Primitive usePrim = prim; - for (auto it = surf.verts.cbegin(); it != surf.verts.cend();) { - atUint16 vertCount = 0; - auto itEnd = surf.verts.cend(); - for (auto it2 = it; it2 != surf.verts.cend(); ++it2, ++vertCount) - if (it2->iPos == 0xffffffff) { - if (vertCount == 3) { - /* All primitives here on out are triangles */ - usePrim = GX::TRIANGLES; - vertCount = atUint16((surf.verts.cend() - it + 1) * 3 / 4); - break; - } - itEnd = it2; - break; - } - - /* VAT0 = float normals, float UVs - * VAT1 = short normals, float UVs */ - writer.writeUByte(usePrim | (skinned ? 0x0 : 0x1)); - writer.writeUint16Big(vertCount); - - for (auto it2 = it; it2 != itEnd; ++it2) { - const Mesh::Surface::Vert& vert = *it2; - if (vert.iPos == 0xffffffff) - continue; - atUint32 skinIdx = vert.iBankSkin * 3; - WriteDLVal(writer, vaFlags.pnMatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.tex0MatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.tex1MatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.tex2MatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.tex3MatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.tex4MatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.tex5MatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.tex6MatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.position(), vert.iPos); - WriteDLVal(writer, vaFlags.normal(), vert.iNorm); - WriteDLVal(writer, vaFlags.color0(), vert.iColor[0]); - WriteDLVal(writer, vaFlags.color1(), vert.iColor[1]); - WriteDLVal(writer, vaFlags.tex0(), vert.iUv[0]); - WriteDLVal(writer, vaFlags.tex1(), vert.iUv[1]); - WriteDLVal(writer, vaFlags.tex2(), vert.iUv[2]); - WriteDLVal(writer, vaFlags.tex3(), vert.iUv[3]); - WriteDLVal(writer, vaFlags.tex4(), vert.iUv[4]); - WriteDLVal(writer, vaFlags.tex5(), vert.iUv[5]); - WriteDLVal(writer, vaFlags.tex6(), vert.iUv[6]); - } - - if (itEnd == surf.verts.cend()) - break; - it = itEnd + 1; - } - - writer.fill(atUint8(0), *padIt); - ++padIt; - } - - writer.close(); - return true; -} - -template bool WriteCMDL(const hecl::ProjectPath& outPath, - const hecl::ProjectPath& inPath, - const Mesh& mesh); - -template -bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh, - hecl::blender::PoolSkinIndex& poolSkinIndex) { - Header head; - head.magic = 0xDEADBABE; - head.version = 0x10000 | Version; - head.aabbMin = mesh.aabbMin.val; - head.aabbMax = mesh.aabbMax.val; - head.matSetCount = mesh.materialSets.size(); - head.secCount = head.matSetCount + 4 + mesh.surfaces.size(); - head.secSizes.reserve(head.secCount); - - /* Lengths of padding to insert while writing */ - std::vector paddingSizes; - paddingSizes.reserve(head.secCount); - - /* Build material sets */ - std::vector matSets; - matSets.reserve(mesh.materialSets.size()); - - for (const std::vector& mset : mesh.materialSets) { - matSets.emplace_back(); - MaterialSet& targetMSet = matSets.back(); - - size_t endOff = 0; - for (const Material& mat : mset) { - ++targetMSet.materialCount; - targetMSet.materials.emplace_back(mat); - targetMSet.materials.back().binarySize(endOff); - targetMSet.materialEndOffs.push_back(endOff); - } - - size_t secSz = 0; - targetMSet.binarySize(secSz); - size_t secSz32 = ROUND_UP_32(secSz); - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - } - - hecl::blender::HMDLBuffers bufs = mesh.getHMDLBuffers(false, poolSkinIndex); - - /* Metadata */ - size_t secSz = 0; - bufs.m_meta.binarySize(secSz); - size_t secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* VBO */ - secSz = bufs.m_vboSz; - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* IBO */ - secSz = bufs.m_iboSz; - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* Surface index */ - std::vector surfEndOffs; - surfEndOffs.reserve(bufs.m_surfaces.size()); - secSz = bufs.m_surfaces.size() * 4 + 4; - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* Surfaces */ - size_t endOff = 0; - for (const hecl::blender::HMDLBuffers::Surface& surf : bufs.m_surfaces) { - (void)surf; - head.secSizes.push_back(64); - paddingSizes.push_back(0); - endOff += 64; - surfEndOffs.push_back(endOff); - } - - /* Write sections */ - athena::io::FileWriter writer(outPath.getAbsolutePath()); - head.write(writer); - std::vector::const_iterator padIt = paddingSizes.cbegin(); - - /* Material Sets */ - for (const MaterialSet& mset : matSets) { - mset.write(writer); - writer.fill(atUint8(0), *padIt); - ++padIt; - } - - /* Metadata */ - bufs.m_meta.write(writer); - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* VBO */ - writer.writeUBytes(bufs.m_vboData.get(), bufs.m_vboSz); - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* IBO */ - writer.writeUBytes(bufs.m_iboData.get(), bufs.m_iboSz); - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* Surface index */ - writer.writeUint32Big(surfEndOffs.size()); - for (size_t off : surfEndOffs) - writer.writeUint32Big(off); - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* Surfaces */ - for (const hecl::blender::HMDLBuffers::Surface& surf : bufs.m_surfaces) { - const Mesh::Surface& osurf = surf.m_origSurf; - - SurfaceHeader header; - header.centroid = osurf.centroid; - header.matIdx = osurf.materialIdx; - header.reflectionNormal = osurf.reflectionNormal; - header.idxStart = surf.m_start; - header.idxCount = surf.m_count; - header.skinMtxBankIdx = osurf.skinBankIdx; - header.write(writer); - - writer.fill(atUint8(0), *padIt); - ++padIt; - } - - /* Ensure final surface's alignment writes zeros */ - writer.seek(-1, athena::SeekOrigin::Current); - writer.writeUByte(0); - writer.close(); - return true; -} - -template bool -WriteHMDLCMDL(const hecl::ProjectPath& outPath, - const hecl::ProjectPath& inPath, const Mesh& mesh, - hecl::blender::PoolSkinIndex& poolSkinIndex); - -struct MaterialPool { - std::vector materials; - size_t addMaterial(const Material& mat, bool& newMat) { - size_t ret = 0; - newMat = false; - for (const Material* testMat : materials) { - if (mat == *testMat) - return ret; - ++ret; - } - materials.push_back(&mat); - newMat = true; - return ret; - } -}; - -template -bool WriteMREASecs(std::vector>& secsOut, const hecl::ProjectPath& inPath, - const std::vector& meshes, zeus::CAABox& fullAABB, std::vector& meshAABBs) { - /* Build material set */ - std::vector surfToGlobalMats; - MaterialSet matSet; - { - MaterialPool matPool; - - size_t surfCount = 0; - for (const Mesh& mesh : meshes) - surfCount += mesh.surfaces.size(); - surfToGlobalMats.reserve(surfCount); - - size_t endOff = 0; - std::vector texPaths; - for (const Mesh& mesh : meshes) { - if (mesh.materialSets.size()) { - std::vector meshToGlobalMats; - meshToGlobalMats.reserve(mesh.materialSets[0].size()); - - for (const Material& mat : mesh.materialSets[0]) { - bool newMat; - size_t idx = matPool.addMaterial(mat, newMat); - meshToGlobalMats.push_back(idx); - if (!newMat) - continue; - - for (const auto& chunk : mat.chunks) { - if (auto pass = chunk.get_if()) { - bool found = false; - for (const hecl::ProjectPath& ePath : texPaths) { - if (pass->tex == ePath) { - found = true; - break; - } - } - if (!found) - texPaths.push_back(pass->tex); - } - } - - auto lightmapped = mat.iprops.find("retro_lightmapped"); - bool lm = lightmapped != mat.iprops.cend() && lightmapped->second != 0; - - matSet.materials.emplace_back(mat, texPaths, mesh.colorLayerCount, lm, false); - - matSet.materials.back().binarySize(endOff); - matSet.head.addMaterialEndOff(endOff); - } - - for (const Mesh::Surface& surf : mesh.surfaces) - surfToGlobalMats.push_back(meshToGlobalMats[surf.materialIdx]); - } - } - for (const hecl::ProjectPath& path : texPaths) - matSet.head.addTexture(path); - - size_t secSz = 0; - matSet.binarySize(secSz); - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - matSet.write(w); - } - - /* Iterate meshes */ - auto matIt = surfToGlobalMats.cbegin(); - for (const Mesh& mesh : meshes) { - zeus::CTransform meshXf(mesh.sceneXf.val.data()); - meshXf.basis.transpose(); - - /* Header */ - { - MeshHeader meshHeader = {}; - meshHeader.visorFlags.setFromBlenderProps(mesh.customProps); - memmove(meshHeader.xfMtx, mesh.sceneXf.val.data(), 48); - - zeus::CAABox aabb(zeus::CVector3f(mesh.aabbMin), zeus::CVector3f(mesh.aabbMax)); - aabb = aabb.getTransformedAABox(meshXf); - meshAABBs.push_back(aabb); - fullAABB.accumulateBounds(aabb); - meshHeader.aabb[0] = aabb.min; - meshHeader.aabb[1] = aabb.max; - - size_t secSz = 0; - meshHeader.binarySize(secSz); - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - meshHeader.write(w); - } - - std::vector surfEndOffs; - surfEndOffs.reserve(mesh.surfaces.size()); - size_t endOff = 0; - auto smatIt = matIt; - for (const Mesh::Surface& surf : mesh.surfaces) { - const typename MaterialSet::Material::VAFlags& vaFlags = matSet.materials.at(*smatIt++).getVAFlags(); - size_t vertSz = vaFlags.vertDLSize(); - - endOff += 96; - for (auto it = surf.verts.cbegin(); it != surf.verts.cend();) { - atUint16 vertCount = 0; - auto itEnd = surf.verts.cend(); - for (auto it2 = it; it2 != surf.verts.cend(); ++it2, ++vertCount) - if (it2->iPos == 0xffffffff) { - if (vertCount == 3) { - /* All primitives here on out are triangles */ - vertCount = atUint16((surf.verts.cend() - it + 1) * 3 / 4); - break; - } - itEnd = it2; - break; - } - endOff += 3 + vertSz * vertCount; - if (itEnd == surf.verts.cend()) - break; - it = itEnd + 1; - } - endOff = ROUND_UP_32(endOff); - surfEndOffs.push_back(endOff); - } - - /* Positions */ - { - size_t secSz = ROUND_UP_32(mesh.pos.size() * 12); - if (secSz == 0) - secSz = 32; - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - for (const hecl::blender::Vector3f& v : mesh.pos) { - zeus::CVector3f preXfPos = meshXf * zeus::CVector3f(v); - w.writeVec3fBig(preXfPos); - } - } - - /* Normals */ - { - size_t secSz = ROUND_UP_32(mesh.norm.size() * 6); - if (secSz == 0) - secSz = 32; - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - for (const hecl::blender::Vector3f& v : mesh.norm) { - zeus::CVector3f preXfNorm = (meshXf.basis * zeus::CVector3f(v)).normalized(); - for (int i = 0; i < 3; ++i) { - int tmpV = int(preXfNorm[i] * 16384.f); - tmpV = zeus::clamp(-32768, tmpV, 32767); - w.writeInt16Big(atInt16(tmpV)); - } - } - } - - /* Colors */ - { - size_t secSz = ROUND_UP_32(mesh.color.size() * 4); - if (secSz == 0) - secSz = 32; - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - for (const hecl::blender::Vector3f& v : mesh.color) { - zeus::CColor col((zeus::CVector4f(zeus::CVector3f(v)))); - col.writeRGBA8(w); - } - } - - /* UVs */ - { - size_t secSz = ROUND_UP_32(mesh.uv.size() * 8); - if (secSz == 0) - secSz = 32; - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - for (const hecl::blender::Vector2f& v : mesh.uv) - w.writeVec2fBig(v.val); - } - - /* LUVs */ - { - size_t secSz = ROUND_UP_32(mesh.luv.size() * 4); - if (secSz == 0) - secSz = 32; - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - for (const hecl::blender::Vector2f& v : mesh.luv) { - for (int i = 0; i < 2; ++i) { - int tmpV = int(v.val.simd[i] * 32768.f); - tmpV = zeus::clamp(-32768, tmpV, 32767); - w.writeInt16Big(atInt16(tmpV)); - } - } - } - - /* Surface index */ - { - secsOut.emplace_back((surfEndOffs.size() + 1) * 4, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - w.writeUint32Big(surfEndOffs.size()); - for (size_t off : surfEndOffs) - w.writeUint32Big(off); - } - - /* Surfaces */ - GX::Primitive prim = GX::TRIANGLES; - if (mesh.topology == hecl::HMDLTopology::Triangles) - prim = GX::TRIANGLES; - else if (mesh.topology == hecl::HMDLTopology::TriStrips) - prim = GX::TRIANGLESTRIP; - else - LogDNACommon.report(logvisor::Fatal, FMT_STRING("unrecognized mesh output mode")); - auto surfEndOffIt = surfEndOffs.begin(); - size_t lastEndOff = 0; - for (const Mesh::Surface& surf : mesh.surfaces) { - size_t matIdx = *matIt++; - const typename MaterialSet::Material& mat = matSet.materials.at(matIdx); - const typename MaterialSet::Material::VAFlags& vaFlags = mat.getVAFlags(); - - SurfaceHeader header; - header.centroid = meshXf * zeus::CVector3f(surf.centroid); - header.matIdx = matIdx; - uint32_t dlSize = uint32_t(*surfEndOffIt - lastEndOff - 96); - header.dlSize = dlSize | 0x80000000; - lastEndOff = *surfEndOffIt++; - header.reflectionNormal = (meshXf.basis * zeus::CVector3f(surf.reflectionNormal)).normalized(); - header.aabbSz = 24; - zeus::CAABox aabb(zeus::CVector3f(surf.aabbMin), zeus::CVector3f(surf.aabbMax)); - aabb = aabb.getTransformedAABox(meshXf); - header.aabb[0] = aabb.min; - header.aabb[1] = aabb.max; - - size_t secSz = 0; - header.binarySize(secSz); - secSz += dlSize; - secSz = ROUND_UP_32(secSz); - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - header.write(w); - - GX::Primitive usePrim = prim; - for (auto it = surf.verts.cbegin(); it != surf.verts.cend();) { - atUint16 vertCount = 0; - auto itEnd = surf.verts.cend(); - for (auto it2 = it; it2 != surf.verts.cend(); ++it2, ++vertCount) - if (it2->iPos == 0xffffffff) { - if (vertCount == 3) { - /* All primitives here on out are triangles */ - usePrim = GX::TRIANGLES; - vertCount = atUint16((surf.verts.cend() - it + 1) * 3 / 4); - break; - } - itEnd = it2; - break; - } - - /* VAT1 = short normals, float UVs - * VAT2 = short normals, short UVs */ - w.writeUByte(usePrim | (mat.flags.lightmapUVArray() ? 0x2 : 0x1)); - w.writeUint16Big(vertCount); - - for (auto it2 = it; it2 != itEnd; ++it2) { - const Mesh::Surface::Vert& vert = *it2; - if (vert.iPos == 0xffffffff) - continue; - atUint32 skinIdx = vert.iBankSkin * 3; - WriteDLVal(w, vaFlags.pnMatIdx(), skinIdx); - WriteDLVal(w, vaFlags.tex0MatIdx(), skinIdx); - WriteDLVal(w, vaFlags.tex1MatIdx(), skinIdx); - WriteDLVal(w, vaFlags.tex2MatIdx(), skinIdx); - WriteDLVal(w, vaFlags.tex3MatIdx(), skinIdx); - WriteDLVal(w, vaFlags.tex4MatIdx(), skinIdx); - WriteDLVal(w, vaFlags.tex5MatIdx(), skinIdx); - WriteDLVal(w, vaFlags.tex6MatIdx(), skinIdx); - WriteDLVal(w, vaFlags.position(), vert.iPos); - WriteDLVal(w, vaFlags.normal(), vert.iNorm); - WriteDLVal(w, vaFlags.color0(), vert.iColor[0]); - WriteDLVal(w, vaFlags.color1(), vert.iColor[1]); - WriteDLVal(w, vaFlags.tex0(), vert.iUv[0]); - WriteDLVal(w, vaFlags.tex1(), vert.iUv[1]); - WriteDLVal(w, vaFlags.tex2(), vert.iUv[2]); - WriteDLVal(w, vaFlags.tex3(), vert.iUv[3]); - WriteDLVal(w, vaFlags.tex4(), vert.iUv[4]); - WriteDLVal(w, vaFlags.tex5(), vert.iUv[5]); - WriteDLVal(w, vaFlags.tex6(), vert.iUv[6]); - } - - if (itEnd == surf.verts.cend()) - break; - it = itEnd + 1; - } - } - } - - return true; -} - -template bool WriteMREASecs( - std::vector>& secsOut, const hecl::ProjectPath& inPath, const std::vector& meshes, - zeus::CAABox& fullAABB, std::vector& meshAABBs); - -template -bool WriteHMDLMREASecs(std::vector>& secsOut, const hecl::ProjectPath& inPath, - const std::vector& meshes, zeus::CAABox& fullAABB, std::vector& meshAABBs) { - /* Build material set */ - std::vector surfToGlobalMats; - { - MaterialPool matPool; - - size_t surfCount = 0; - for (const Mesh& mesh : meshes) - surfCount += mesh.surfaces.size(); - surfToGlobalMats.reserve(surfCount); - - MaterialSet matSet = {}; - size_t endOff = 0; - for (const Mesh& mesh : meshes) { - if (mesh.materialSets.size()) { - std::vector meshToGlobalMats; - meshToGlobalMats.reserve(mesh.materialSets[0].size()); - - for (const Material& mat : mesh.materialSets[0]) { - bool newMat; - size_t idx = matPool.addMaterial(mat, newMat); - meshToGlobalMats.push_back(idx); - if (!newMat) - continue; - - ++matSet.materialCount; - matSet.materials.emplace_back(mat); - matSet.materials.back().binarySize(endOff); - matSet.materialEndOffs.push_back(endOff); - } - - for (const Mesh::Surface& surf : mesh.surfaces) - surfToGlobalMats.push_back(meshToGlobalMats[surf.materialIdx]); - } - } - - size_t secSz = 0; - matSet.binarySize(secSz); - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - matSet.write(w); - } - - /* Iterate meshes */ - auto matIt = surfToGlobalMats.cbegin(); - for (const Mesh& mesh : meshes) { - zeus::CTransform meshXf(mesh.sceneXf.val.data()); - meshXf.basis.transpose(); - - /* Header */ - { - MeshHeader meshHeader = {}; - meshHeader.visorFlags.setFromBlenderProps(mesh.customProps); - memmove(meshHeader.xfMtx, mesh.sceneXf.val.data(), 48); - - zeus::CAABox aabb(zeus::CVector3f(mesh.aabbMin), zeus::CVector3f(mesh.aabbMax)); - aabb = aabb.getTransformedAABox(meshXf); - meshAABBs.push_back(aabb); - fullAABB.accumulateBounds(aabb); - meshHeader.aabb[0] = aabb.min; - meshHeader.aabb[1] = aabb.max; - - size_t secSz = 0; - meshHeader.binarySize(secSz); - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - meshHeader.write(w); - } - - hecl::blender::PoolSkinIndex poolSkinIndex; - hecl::blender::HMDLBuffers bufs = mesh.getHMDLBuffers(true, poolSkinIndex); - - std::vector surfEndOffs; - surfEndOffs.reserve(bufs.m_surfaces.size()); - size_t endOff = 0; - for (const hecl::blender::HMDLBuffers::Surface& surf : bufs.m_surfaces) { - (void)surf; - endOff += 96; - surfEndOffs.push_back(endOff); - } - - /* Metadata */ - { - size_t secSz = 0; - bufs.m_meta.binarySize(secSz); - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - bufs.m_meta.write(w); - } - - /* VBO */ - { - secsOut.emplace_back(bufs.m_vboSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - w.writeUBytes(bufs.m_vboData.get(), bufs.m_vboSz); - } - - /* IBO */ - { - secsOut.emplace_back(bufs.m_iboSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - w.writeUBytes(bufs.m_iboData.get(), bufs.m_iboSz); - } - - /* Surface index */ - { - secsOut.emplace_back((surfEndOffs.size() + 1) * 4, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - w.writeUint32Big(surfEndOffs.size()); - for (size_t off : surfEndOffs) - w.writeUint32Big(off); - } - - /* Surfaces */ - for (const hecl::blender::HMDLBuffers::Surface& surf : bufs.m_surfaces) { - const Mesh::Surface& osurf = surf.m_origSurf; - - SurfaceHeader header; - header.centroid = meshXf * zeus::CVector3f(osurf.centroid); - header.matIdx = *matIt++; - header.reflectionNormal = (meshXf.basis * zeus::CVector3f(osurf.reflectionNormal)).normalized(); - header.idxStart = surf.m_start; - header.idxCount = surf.m_count; - header.skinMtxBankIdx = osurf.skinBankIdx; - - header.aabbSz = 24; - zeus::CAABox aabb(zeus::CVector3f(surf.m_origSurf.aabbMin), zeus::CVector3f(surf.m_origSurf.aabbMax)); - aabb = aabb.getTransformedAABox(meshXf); - header.aabb[0] = aabb.min; - header.aabb[1] = aabb.max; - - size_t secSz = 0; - header.binarySize(secSz); - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - header.write(w); - } - } - - return true; -} - -template bool WriteHMDLMREASecs( - std::vector>& secsOut, const hecl::ProjectPath& inPath, const std::vector& meshes, - zeus::CAABox& fullAABB, std::vector& meshAABBs); - -template <> -void SurfaceHeader_1::Enumerate(typename Read::StreamT& reader) { - /* centroid */ - centroid = reader.readVec3fBig(); - /* matIdx */ - matIdx = reader.readUint32Big(); - /* dlSize */ - dlSize = reader.readUint32Big(); - /* idxStart */ - idxStart = reader.readUint32Big(); - /* idxCount */ - idxCount = reader.readUint32Big(); - /* aabbSz */ - aabbSz = reader.readUint32Big(); - /* reflectionNormal */ - reflectionNormal = reader.readVec3fBig(); - /* aabb */ - size_t remAABB = aabbSz; - if (remAABB >= 24) { - aabb[0] = reader.readVec3fBig(); - aabb[1] = reader.readVec3fBig(); - remAABB -= 24; - } - reader.seek(remAABB, athena::SeekOrigin::Current); - /* align */ - reader.seekAlign32(); -} - -template <> -void SurfaceHeader_1::Enumerate(typename Write::StreamT& writer) { - /* centroid */ - writer.writeVec3fBig(centroid); - /* matIdx */ - writer.writeUint32Big(matIdx); - /* dlSize */ - writer.writeUint32Big(dlSize); - /* idxStart */ - writer.writeUint32Big(idxStart); - /* idxCount */ - writer.writeUint32Big(idxCount); - /* aabbSz */ - writer.writeUint32Big(aabbSz ? 24 : 0); - /* reflectionNormal */ - writer.writeVec3fBig(reflectionNormal); - /* aabb */ - if (aabbSz) { - writer.writeVec3fBig(aabb[0]); - writer.writeVec3fBig(aabb[1]); - } - /* align */ - writer.seekAlign32(); -} - -template <> -void SurfaceHeader_1::Enumerate(typename BinarySize::StreamT& s) { - s += (aabbSz ? 24 : 0); - s += 44; - s = (s + 31) & ~31; -} - -template <> -void SurfaceHeader_2::Enumerate(typename Read::StreamT& reader) { - /* centroid */ - centroid = reader.readVec3fBig(); - /* matIdx */ - matIdx = reader.readUint32Big(); - /* dlSize */ - dlSize = reader.readUint32Big(); - /* idxStart */ - idxStart = reader.readUint32Big(); - /* idxCount */ - idxCount = reader.readUint32Big(); - /* aabbSz */ - aabbSz = reader.readUint32Big(); - /* reflectionNormal */ - reflectionNormal = reader.readVec3fBig(); - /* skinMtxBankIdx */ - skinMtxBankIdx = reader.readInt16Big(); - /* surfaceGroup */ - surfaceGroup = reader.readUint16Big(); - /* aabb */ - size_t remAABB = aabbSz; - if (remAABB >= 24) { - aabb[0] = reader.readVec3fBig(); - aabb[1] = reader.readVec3fBig(); - remAABB -= 24; - } - reader.seek(remAABB, athena::SeekOrigin::Current); - /* align */ - reader.seekAlign32(); -} - -template <> -void SurfaceHeader_2::Enumerate(typename Write::StreamT& writer) { - /* centroid */ - writer.writeVec3fBig(centroid); - /* matIdx */ - writer.writeUint32Big(matIdx); - /* dlSize */ - writer.writeUint32Big(dlSize); - /* idxStart */ - writer.writeUint32Big(idxStart); - /* idxCount */ - writer.writeUint32Big(idxCount); - /* aabbSz */ - writer.writeUint32Big(aabbSz ? 24 : 0); - /* reflectionNormal */ - writer.writeVec3fBig(reflectionNormal); - /* skinMtxBankIdx */ - writer.writeInt16Big(skinMtxBankIdx); - /* surfaceGroup */ - writer.writeUint16Big(surfaceGroup); - /* aabb */ - if (aabbSz) { - writer.writeVec3fBig(aabb[0]); - writer.writeVec3fBig(aabb[1]); - } - /* align */ - writer.seekAlign32(); -} - -template <> -void SurfaceHeader_2::Enumerate(typename BinarySize::StreamT& s) { - s += (aabbSz ? 24 : 0); - s += 48; - s = (s + 31) & ~31; -} - -template <> -void SurfaceHeader_3::Enumerate(typename Read::StreamT& reader) { - /* centroid */ - centroid = reader.readVec3fBig(); - /* matIdx */ - matIdx = reader.readUint32Big(); - /* dlSize */ - dlSize = reader.readUint32Big(); - /* idxStart */ - idxStart = reader.readUint32Big(); - /* idxCount */ - idxCount = reader.readUint32Big(); - /* aabbSz */ - aabbSz = reader.readUint32Big(); - /* reflectionNormal */ - reflectionNormal = reader.readVec3fBig(); - /* skinMtxBankIdx */ - skinMtxBankIdx = reader.readInt16Big(); - /* surfaceGroup */ - surfaceGroup = reader.readUint16Big(); - /* aabb */ - size_t remAABB = aabbSz; - if (remAABB >= 24) { - aabb[0] = reader.readVec3fBig(); - aabb[1] = reader.readVec3fBig(); - remAABB -= 24; - } - reader.seek(remAABB, athena::SeekOrigin::Current); - /* unk3 */ - unk3 = reader.readUByte(); - /* align */ - reader.seekAlign32(); -} - -template <> -void SurfaceHeader_3::Enumerate(typename Write::StreamT& writer) { - /* centroid */ - writer.writeVec3fBig(centroid); - /* matIdx */ - writer.writeUint32Big(matIdx); - /* dlSize */ - writer.writeUint32Big(dlSize); - /* idxStart */ - writer.writeUint32Big(idxStart); - /* idxCount */ - writer.writeUint32Big(idxCount); - /* aabbSz */ - writer.writeUint32Big(aabbSz ? 24 : 0); - /* reflectionNormal */ - writer.writeVec3fBig(reflectionNormal); - /* skinMtxBankIdx */ - writer.writeInt16Big(skinMtxBankIdx); - /* surfaceGroup */ - writer.writeUint16Big(surfaceGroup); - /* aabb */ - if (aabbSz) { - writer.writeVec3fBig(aabb[0]); - writer.writeVec3fBig(aabb[1]); - } - /* unk3 */ - writer.writeUByte(unk3); - /* align */ - writer.seekAlign32(); -} - -template <> -void SurfaceHeader_3::Enumerate(typename BinarySize::StreamT& s) { - s += (aabbSz ? 24 : 0); - s += 49; - s = (s + 31) & ~31; -} - -} // namespace DataSpec::DNACMDL diff --git a/DataSpec/DNACommon/CMDL.hpp b/DataSpec/DNACommon/CMDL.hpp deleted file mode 100644 index 3b305e8be..000000000 --- a/DataSpec/DNACommon/CMDL.hpp +++ /dev/null @@ -1,168 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "DataSpec/DNACommon/GX.hpp" -#include "DataSpec/DNACommon/TXTR.hpp" - -#include -#include -#include - -namespace hecl { -class ProjectPath; -} - -namespace zeus { -class CAABox; -} - -namespace DataSpec::DNACMDL { - -using Mesh = hecl::blender::Mesh; -using Material = hecl::blender::Material; - -struct Header : BigDNA { - AT_DECL_DNA - Value magic; - Value version; - struct Flags : BigDNA { - AT_DECL_DNA - Value flags = 0; - bool skinned() const { return (flags & 0x1) != 0; } - void setSkinned(bool val) { - flags &= ~0x1; - flags |= val; - } - bool shortNormals() const { return (flags & 0x2) != 0; } - void setShortNormals(bool val) { - flags &= ~0x2; - flags |= val << 1; - } - bool shortUVs() const { return (flags & 0x4) != 0; } - void setShortUVs(bool val) { - flags &= ~0x4; - flags |= val << 2; - } - } flags; - Value aabbMin; - Value aabbMax; - Value secCount; - Value matSetCount; - Vector secSizes; - Align<32> align; -}; - -struct SurfaceHeader_1 : BigDNA { - AT_DECL_EXPLICIT_DNA - Value centroid; - Value matIdx = 0; - Value dlSize = 0; - Value idxStart = 0; /* Actually used by game to stash CCubeModel pointer */ - Value idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */ - Value aabbSz = 0; - Value reflectionNormal; - Value aabb[2]; - Align<32> align; - - static constexpr bool UseMatrixSkinning() { return false; } - static constexpr atInt16 skinMatrixBankIdx() { return -1; } -}; - -struct SurfaceHeader_2 : BigDNA { - AT_DECL_EXPLICIT_DNA - Value centroid; - Value matIdx = 0; - Value dlSize = 0; - Value idxStart = 0; /* Actually used by game to stash CCubeModel pointer */ - Value idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */ - Value aabbSz = 0; - Value reflectionNormal; - Value skinMtxBankIdx; - Value surfaceGroup; - Value aabb[2]; - Align<32> align; - - static constexpr bool UseMatrixSkinning() { return false; } - atInt16 skinMatrixBankIdx() const { return skinMtxBankIdx; } -}; - -struct SurfaceHeader_3 : BigDNA { - AT_DECL_EXPLICIT_DNA - Value centroid; - Value matIdx = 0; - Value dlSize = 0; - Value idxStart = 0; /* Actually used by game to stash CCubeModel pointer */ - Value idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */ - Value aabbSz = 0; - Value reflectionNormal; - Value skinMtxBankIdx; - Value surfaceGroup; - Value aabb[2]; - Value unk3; - Align<32> align; - - static constexpr bool UseMatrixSkinning() { return true; } - atInt16 skinMatrixBankIdx() const { return skinMtxBankIdx; } -}; - -struct VertexAttributes { - GX::AttrType pos = GX::NONE; - GX::AttrType norm = GX::NONE; - GX::AttrType color0 = GX::NONE; - GX::AttrType color1 = GX::NONE; - unsigned uvCount = 0; - GX::AttrType uvs[7] = {GX::NONE}; - GX::AttrType pnMtxIdx = GX::NONE; - unsigned texMtxIdxCount = 0; - GX::AttrType texMtxIdx[7] = {GX::NONE}; - bool shortUVs; -}; - -template -void GetVertexAttributes(const MaterialSet& matSet, std::vector& attributesOut); - -template -void ReadMaterialSetToBlender_1_2(hecl::blender::PyOutStream& os, const MaterialSet& matSet, const PAKRouter& pakRouter, - const typename PAKRouter::EntryType& entry, unsigned setIdx); - -template -void ReadMaterialSetToBlender_3(hecl::blender::PyOutStream& os, const MaterialSet& matSet, const PAKRouter& pakRouter, - const typename PAKRouter::EntryType& entry, unsigned setIdx); - -void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath); -void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int meshIdx); - -template -atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, athena::io::IStreamReader& reader, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const RigPair& rp, - bool shortNormals, bool shortUVs, std::vector& vertAttribs, - int meshIdx, atUint32 secCount, atUint32 matSetCount, const atUint32* secSizes, - atUint32 surfaceCount = 0); - -template -bool ReadCMDLToBlender(hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const typename PAKRouter::EntryType& entry, const SpecBase& dataspec, const RigPair& rp); - -template -void NameCMDL(athena::io::IStreamReader& reader, PAKRouter& pakRouter, typename PAKRouter::EntryType& entry, - const SpecBase& dataspec); - -template -bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh); - -template -bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh, - hecl::blender::PoolSkinIndex& poolSkinIndex); - -template -bool WriteMREASecs(std::vector>& secsOut, const hecl::ProjectPath& inPath, - const std::vector& meshes, zeus::CAABox& fullAABB, std::vector& meshAABBs); - -template -bool WriteHMDLMREASecs(std::vector>& secsOut, const hecl::ProjectPath& inPath, - const std::vector& meshes, zeus::CAABox& fullAABB, std::vector& meshAABBs); - -} // namespace DataSpec::DNACMDL diff --git a/DataSpec/DNACommon/CMakeLists.txt b/DataSpec/DNACommon/CMakeLists.txt deleted file mode 100644 index d2211d761..000000000 --- a/DataSpec/DNACommon/CMakeLists.txt +++ /dev/null @@ -1,60 +0,0 @@ -make_dnalist(CMDL - FONT - DGRP - FSM2 - MAPA - MAPU - PATH - MayaSpline - EGMC - SAVWCommon - ParticleCommon - MetaforceVersionInfo - Tweaks/ITweakPlayerGun) - -set(DNACOMMON_SOURCES - DNACommon.hpp DNACommon.cpp - PAK.hpp PAK.cpp - GX.hpp GX.cpp - FSM2.hpp FSM2.cpp - MLVL.hpp MLVL.cpp - CMDL.cpp - MAPA.cpp - MAPU.cpp - PATH.hpp PATH.cpp - STRG.hpp STRG.cpp - TXTR.hpp TXTR.cpp - ANCS.hpp ANCS.cpp - ANIM.hpp ANIM.cpp - PART.hpp PART.cpp - SWHC.hpp SWHC.cpp - CRSC.hpp CRSC.cpp - ELSC.hpp ELSC.cpp - WPSC.hpp WPSC.cpp - DPSC.hpp DPSC.cpp - ParticleCommon.cpp - FONT.cpp - DGRP.cpp - ATBL.hpp ATBL.cpp - DeafBabe.hpp DeafBabe.cpp - BabeDead.hpp BabeDead.cpp - RigInverter.hpp RigInverter.cpp - AROTBuilder.hpp AROTBuilder.cpp - OBBTreeBuilder.hpp OBBTreeBuilder.cpp - MetaforceVersionInfo.hpp - Tweaks/ITweak.hpp - Tweaks/TweakWriter.hpp - Tweaks/ITweakGame.hpp - Tweaks/ITweakParticle.hpp - Tweaks/ITweakPlayer.hpp - Tweaks/ITweakPlayerControl.hpp - Tweaks/ITweakGunRes.hpp - Tweaks/ITweakPlayerRes.hpp - Tweaks/ITweakGui.hpp - Tweaks/ITweakSlideShow.hpp - Tweaks/ITweakTargeting.hpp - Tweaks/ITweakAutoMapper.hpp - Tweaks/ITweakBall.hpp - Tweaks/ITweakGuiColors.hpp) - -dataspec_add_list(DNACommon DNACOMMON_SOURCES) diff --git a/DataSpec/DNACommon/CRSC.cpp b/DataSpec/DNACommon/CRSC.cpp deleted file mode 100644 index a66b912f0..000000000 --- a/DataSpec/DNACommon/CRSC.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "DataSpec/DNACommon/CRSC.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAParticle { - -template struct PPImpl<_CRSM>; -template struct PPImpl<_CRSM>; - -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_CRSM>) -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_CRSM>) - -template <> -std::string_view PPImpl<_CRSM>::DNAType() { - return "CRSM"sv; -} - -template <> -std::string_view PPImpl<_CRSM>::DNAType() { - return "CRSM"sv; -} - -template -bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - CRSM crsm; - crsm.read(rs); - athena::io::ToYAMLStream(crsm, writer); - return true; - } - return false; -} -template bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteCRSM(const CRSM& crsm, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - crsm.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteCRSM(const CRSM& crsm, const hecl::ProjectPath& outPath); -template bool WriteCRSM(const CRSM& crsm, const hecl::ProjectPath& outPath); -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/CRSC.def b/DataSpec/DNACommon/CRSC.def deleted file mode 100644 index 6fe2e2b7e..000000000 --- a/DataSpec/DNACommon/CRSC.def +++ /dev/null @@ -1,222 +0,0 @@ -#ifndef ENTRY -#define ENTRY(name, identifier) -#endif - -#ifndef RES_ENTRY -#define RES_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef U32_ENTRY -#define U32_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef FLOAT_ENTRY -#define FLOAT_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -RES_ENTRY('NODP', NODP) -RES_ENTRY('DEFS', DEFS) -RES_ENTRY('CRTS', CRTS) -RES_ENTRY('MTLS', MTLS) -RES_ENTRY('GRAS', GRAS) -RES_ENTRY('ICEE', ICEE) -RES_ENTRY('GOOO', GOOO) -RES_ENTRY('WODS', WODS) -RES_ENTRY('WATR', WATR) -RES_ENTRY('1MUD', _1MUD) -RES_ENTRY('1LAV', _1LAV) -RES_ENTRY('1SAN', _1SAN) -RES_ENTRY('1PRJ', _1PRJ) -RES_ENTRY('DCHR', DCHR) -RES_ENTRY('DCHS', DCHS) -RES_ENTRY('DCSH', DCSH) -RES_ENTRY('DENM', DENM) -RES_ENTRY('DESP', DESP) -RES_ENTRY('DESH', DESH) -RES_ENTRY('BTLE', BTLE) -RES_ENTRY('WASP', WASP) -RES_ENTRY('TALP', TALP) -RES_ENTRY('PTGM', PTGM) -RES_ENTRY('SPIR', SPIR) -RES_ENTRY('FPIR', FPIR) -RES_ENTRY('FFLE', FFLE) -RES_ENTRY('PARA', PARA) -RES_ENTRY('BMON', BMON) -RES_ENTRY('BFLR', BFLR) -RES_ENTRY('PBOS', PBOS) -RES_ENTRY('IBOS', IBOS) -RES_ENTRY('1SVA', _1SVA) -RES_ENTRY('1RPR', _1RPR) -RES_ENTRY('1MTR', _1MTR) -RES_ENTRY('1PDS', _1PDS) -RES_ENTRY('1FLB', _1FLB) -RES_ENTRY('1DRN', _1DRN) -RES_ENTRY('1MRE', _1MRE) -RES_ENTRY('CHOZ', CHOZ) -RES_ENTRY('JZAP', JZAP) -RES_ENTRY('1ISE', _1ISE) -RES_ENTRY('1BSE', _1BSE) -RES_ENTRY('1ATB', _1ATB) -RES_ENTRY('1ATA', _1ATA) -RES_ENTRY('BTSP', BTSP) -RES_ENTRY('WWSP', WWSP) -RES_ENTRY('TASP', TASP) -RES_ENTRY('TGSP', TGSP) -RES_ENTRY('SPSP', SPSP) -RES_ENTRY('FPSP', FPSP) -RES_ENTRY('FFSP', FFSP) -RES_ENTRY('PSSP', PSSP) -RES_ENTRY('BMSP', BMSP) -RES_ENTRY('BFSP', BFSP) -RES_ENTRY('PBSP', PBSP) -RES_ENTRY('IBSP', IBSP) -RES_ENTRY('2SVA', _2SVA) -RES_ENTRY('2RPR', _2RPR) -RES_ENTRY('2MTR', _2MTR) -RES_ENTRY('2PDS', _2PDS) -RES_ENTRY('2FLB', _2FLB) -RES_ENTRY('2DRN', _2DRN) -RES_ENTRY('2MRE', _2MRE) -RES_ENTRY('CHSP', CHSP) -RES_ENTRY('JZSP', JZSP) -RES_ENTRY('3ISE', _3ISE) -RES_ENTRY('3BSE', _3BSE) -RES_ENTRY('3ATB', _3ATB) -RES_ENTRY('3ATA', _3ATA) -RES_ENTRY('BTSH', BTSH) -RES_ENTRY('WWSH', WWSH) -RES_ENTRY('TASH', TASH) -RES_ENTRY('TGSH', TGSH) -RES_ENTRY('SPSH', SPSH) -RES_ENTRY('FPSH', FPSH) -RES_ENTRY('FFSH', FFSH) -RES_ENTRY('PSSH', PSSH) -RES_ENTRY('BMSH', BMSH) -RES_ENTRY('BFSH', BFSH) -RES_ENTRY('PBSH', PBSH) -RES_ENTRY('IBSH', IBSH) -RES_ENTRY('3SVA', _3SVA) -RES_ENTRY('3RPR', _3RPR) -RES_ENTRY('3MTR', _3MTR) -RES_ENTRY('3PDS', _3PDS) -RES_ENTRY('3FLB', _3FLB) -RES_ENTRY('3DRN', _3DRN) -RES_ENTRY('3MRE', _3MRE) -RES_ENTRY('CHSH', CHSH) -RES_ENTRY('JZSH', JZSH) -RES_ENTRY('5ISE', _5ISE) -RES_ENTRY('5BSE', _5BSE) -RES_ENTRY('5ATB', _5ATB) -RES_ENTRY('5ATA', _5ATA) -RES_ENTRY('NCDL', NCDL) -RES_ENTRY('DDCL', DDCL) -RES_ENTRY('CODL', CODL) -RES_ENTRY('MEDL', MEDL) -RES_ENTRY('GRDL', GRDL) -RES_ENTRY('ICDL', ICDL) -RES_ENTRY('GODL', GODL) -RES_ENTRY('WODL', WODL) -RES_ENTRY('WTDL', WTDL) -RES_ENTRY('3MUD', _3MUD) -RES_ENTRY('3LAV', _3LAV) -RES_ENTRY('3SAN', _3SAN) -RES_ENTRY('CHDL', CHDL) -RES_ENTRY('ENDL', ENDL) - -U32_ENTRY('NSFX', NSFX) -U32_ENTRY('DSFX', DSFX) -U32_ENTRY('CSFX', CSFX) -U32_ENTRY('MSFX', MSFX) -U32_ENTRY('GRFX', GRFX) -U32_ENTRY('ICFX', ICFX) -U32_ENTRY('GOFX', GOFX) -U32_ENTRY('WSFX', WSFX) -U32_ENTRY('WTFX', WTFX) -U32_ENTRY('2MUD', _2MUD) -U32_ENTRY('2LAV', _2LAV) -U32_ENTRY('2SAN', _2SAN) -U32_ENTRY('2PRJ', _2PRJ) -U32_ENTRY('DCFX', DCFX) -U32_ENTRY('DSHX', DSHX) -U32_ENTRY('DEFX', DEFX) -U32_ENTRY('ESFX', ESFX) -U32_ENTRY('SHFX', SHFX) -U32_ENTRY('BEFX', BEFX) -U32_ENTRY('WWFX', WWFX) -U32_ENTRY('TAFX', TAFX) -U32_ENTRY('GTFX', GTFX) -U32_ENTRY('SPFX', SPFX) -U32_ENTRY('FPFX', FPFX) -U32_ENTRY('FFFX', FFFX) -U32_ENTRY('PAFX', PAFX) -U32_ENTRY('BMFX', BMFX) -U32_ENTRY('BFFX', BFFX) -U32_ENTRY('PBFX', PBFX) -U32_ENTRY('IBFX', IBFX) -U32_ENTRY('4SVA', _4SVA) -U32_ENTRY('4RPR', _4RPR) -U32_ENTRY('4MTR', _4MTR) -U32_ENTRY('4PDS', _4PDS) -U32_ENTRY('4FLB', _4FLB) -U32_ENTRY('4DRN', _4DRN) -U32_ENTRY('4MRE', _4MRE) -U32_ENTRY('CZFX', CZFX) -U32_ENTRY('JZAS', JZAS) -U32_ENTRY('2ISE', _2ISE) -U32_ENTRY('2BSE', _2BSE) -U32_ENTRY('2ATB', _2ATB) -U32_ENTRY('2ATA', _2ATA) -U32_ENTRY('BSFX', BSFX) -U32_ENTRY('TSFX', TSFX) -U32_ENTRY('GSFX', GSFX) -U32_ENTRY('SSFX', SSFX) -U32_ENTRY('FSFX', FSFX) -U32_ENTRY('SFFX', SFFX) -U32_ENTRY('PSFX', PSFX) -U32_ENTRY('SBFX', SBFX) -U32_ENTRY('PBSX', PBSX) -U32_ENTRY('IBSX', IBSX) -U32_ENTRY('5SVA', _5SVA) -U32_ENTRY('5RPR', _5RPR) -U32_ENTRY('5MTR', _5MTR) -U32_ENTRY('5PDS', _5PDS) -U32_ENTRY('5FLB', _5FLB) -U32_ENTRY('5DRN', _5DRN) -U32_ENTRY('5MRE', _5MRE) -U32_ENTRY('JZPS', JZPS) -U32_ENTRY('4ISE', _4ISE) -U32_ENTRY('4BSE', _4BSE) -U32_ENTRY('4ATB', _4ATB) -U32_ENTRY('4ATA', _4ATA) -U32_ENTRY('BHFX', BHFX) -U32_ENTRY('WHFX', WHFX) -U32_ENTRY('THFX', THFX) -U32_ENTRY('GHFX', GHFX) -U32_ENTRY('FHFX', FHFX) -U32_ENTRY('HFFX', HFFX) -U32_ENTRY('PHFX', PHFX) -U32_ENTRY('MHFX', MHFX) -U32_ENTRY('HBFX', HBFX) -U32_ENTRY('PBHX', PBHX) -U32_ENTRY('IBHX', IBHX) -U32_ENTRY('6SVA', _6SVA) -U32_ENTRY('6RPR', _6RPR) -U32_ENTRY('6MTR', _6MTR) -U32_ENTRY('6PDS', _6PDS) -U32_ENTRY('6FLB', _6FLB) -U32_ENTRY('6DRN', _6DRN) -U32_ENTRY('6MRE', _6MRE) -U32_ENTRY('CHFX', CHFX) -U32_ENTRY('JZHS', JZHS) -U32_ENTRY('6ISE', _6ISE) -U32_ENTRY('6BSE', _6BSE) -U32_ENTRY('6ATB', _6ATB) -U32_ENTRY('6ATA', _6ATA) - -FLOAT_ENTRY('RNGE', x30_RNGE) -FLOAT_ENTRY('FOFF', x34_FOFF) - -#undef ENTRY -#undef RES_ENTRY -#undef U32_ENTRY -#undef FLOAT_ENTRY diff --git a/DataSpec/DNACommon/CRSC.hpp b/DataSpec/DNACommon/CRSC.hpp deleted file mode 100644 index 94ba917ed..000000000 --- a/DataSpec/DNACommon/CRSC.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ParticleCommon.hpp" - -#include - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAParticle { - -template -struct _CRSM { - static constexpr ParticleType Type = ParticleType::CRSM; -#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; -#define U32_ENTRY(name, identifier) uint32_t identifier = ~0; -#define FLOAT_ENTRY(name, identifier) float identifier = 0.f; -#include "CRSC.def" - - template - void constexpr Enumerate(_Func f) { -#define ENTRY(name, identifier) f(FOURCC(name), identifier); -#include "CRSC.def" - } - - template - bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { -#define ENTRY(name, identifier) \ - case SBIG(name): \ - f(identifier); \ - return true; -#include "CRSC.def" - default: - return false; - } - } -}; -template -using CRSM = PPImpl<_CRSM>; - -template -bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteCRSM(const CRSM& crsm, const hecl::ProjectPath& outPath); -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/DGRP.cpp b/DataSpec/DNACommon/DGRP.cpp deleted file mode 100644 index d39427e1b..000000000 --- a/DataSpec/DNACommon/DGRP.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "DataSpec/DNACommon/DGRP.hpp" - -#include -#include -#include - -#include - -namespace DataSpec::DNADGRP { - -template -bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - DGRP dgrp; - dgrp.read(rs); - athena::io::ToYAMLStream(dgrp, writer); - return true; - } - return false; -} -template bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteDGRP(const DGRP& dgrp, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - dgrp.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteDGRP(const DGRP& dgrp, const hecl::ProjectPath& outPath); -template bool WriteDGRP(const DGRP& dgrp, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNADGRP diff --git a/DataSpec/DNACommon/DGRP.hpp b/DataSpec/DNACommon/DGRP.hpp deleted file mode 100644 index 37850ee6f..000000000 --- a/DataSpec/DNACommon/DGRP.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNADGRP { - -template -struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) DGRP : BigDNA { - AT_DECL_DNA_YAML - Value dependCount; - struct ObjectTag : BigDNA { - AT_DECL_DNA_YAML - DNAFourCC type; - Value id; - - bool validate() const { - if (!id.isValid()) - return false; - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id); - return path && !path.isNone(); - } - }; - - Vector depends; - - void validateDeps() { - std::vector newDeps; - newDeps.reserve(depends.size()); - for (const ObjectTag& tag : depends) - if (tag.validate()) - newDeps.push_back(tag); - depends = std::move(newDeps); - dependCount = atUint32(depends.size()); - } -}; - -template -bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template -bool WriteDGRP(const DGRP& dgrp, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNADGRP diff --git a/DataSpec/DNACommon/DNACommon.cpp b/DataSpec/DNACommon/DNACommon.cpp deleted file mode 100644 index 1ef8ba3f0..000000000 --- a/DataSpec/DNACommon/DNACommon.cpp +++ /dev/null @@ -1,199 +0,0 @@ -#include "DNACommon.hpp" -#include "PAK.hpp" -#include "boo/ThreadLocalPtr.hpp" - -namespace DataSpec { - -logvisor::Module LogDNACommon("DataSpec::DNACommon"); -ThreadLocalPtr g_curSpec; -ThreadLocalPtr g_PakRouter; -ThreadLocalPtr g_ThreadBlenderToken; -ThreadLocalPtr UniqueIDBridge::s_Project; -UniqueID32 UniqueID32::kInvalidId; - -template -hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const IDType& id, bool silenceWarnings) { - /* Try PAKRouter first (only available at extract) */ - PAKRouterBase* pakRouter = g_PakRouter.get(); - if (pakRouter) { - hecl::ProjectPath path = pakRouter->getWorking(id, silenceWarnings); - if (path) - return path; - } - - /* Try project cache second (populated with paths read from YAML resources) */ - hecl::Database::Project* project = s_Project.get(); - if (!project) { - if (pakRouter) { - if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id.isValid()) - LogDNACommon.report(logvisor::Warning, FMT_STRING("unable to translate {} to path"), id); - return {}; - } - LogDNACommon.report(logvisor::Fatal, FMT_STRING("g_PakRouter or s_Project must be set to non-null before " - "calling UniqueIDBridge::TranslatePakIdToPath")); - return {}; - } - - const hecl::ProjectPath* search = project->lookupBridgePath(id.toUint64()); - if (!search) { - if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id.isValid()) - LogDNACommon.report(logvisor::Warning, FMT_STRING("unable to translate {} to path"), id); - return {}; - } - return *search; -} -template hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID32& id, bool silenceWarnings); -template hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID64& id, bool silenceWarnings); -template hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID128& id, bool silenceWarnings); - -template -hecl::ProjectPath UniqueIDBridge::MakePathFromString(std::string_view str) { - if (str.empty()) - return {}; - hecl::Database::Project* project = s_Project.get(); - if (!project) - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("UniqueIDBridge::setGlobalProject must be called before MakePathFromString")); - hecl::ProjectPath path = hecl::ProjectPath(*project, str); - project->addBridgePathToCache(IDType(path).toUint64(), path); - return path; -} -template hecl::ProjectPath UniqueIDBridge::MakePathFromString(std::string_view str); -template hecl::ProjectPath UniqueIDBridge::MakePathFromString(std::string_view str); - -void UniqueIDBridge::SetThreadProject(hecl::Database::Project& project) { s_Project.reset(&project); } - -/** PAK 32-bit Unique ID */ -template <> -void UniqueID32::Enumerate(typename Read::StreamT& reader) { - assign(reader.readUint32Big()); -} -template <> -void UniqueID32::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(m_id); -} -template <> -void UniqueID32::Enumerate(typename ReadYaml::StreamT& reader) { - *this = UniqueIDBridge::MakePathFromString(reader.readString()); -} -template <> -void UniqueID32::Enumerate(typename WriteYaml::StreamT& writer) { - if (!isValid()) - return; - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this); - if (!path) - return; - writer.writeString(path.getEncodableString()); -} -template <> -void UniqueID32::Enumerate(typename BinarySize::StreamT& s) { - s += 4; -} - -std::string UniqueID32::toString() const { return fmt::format(FMT_STRING("{}"), *this); } - -template <> -void UniqueID32Zero::Enumerate(typename Read::StreamT& reader) { - UniqueID32::Enumerate(reader); -} -template <> -void UniqueID32Zero::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(isValid() ? m_id : 0); -} -template <> -void UniqueID32Zero::Enumerate(typename ReadYaml::StreamT& reader) { - UniqueID32::Enumerate(reader); -} -template <> -void UniqueID32Zero::Enumerate(typename WriteYaml::StreamT& writer) { - UniqueID32::Enumerate(writer); -} -template <> -void UniqueID32Zero::Enumerate(typename BinarySize::StreamT& s) { - UniqueID32::Enumerate(s); -} - -/** PAK 64-bit Unique ID */ -template <> -void UniqueID64::Enumerate(typename Read::StreamT& reader) { - assign(reader.readUint64Big()); -} -template <> -void UniqueID64::Enumerate(typename Write::StreamT& writer) { - writer.writeUint64Big(m_id); -} -template <> -void UniqueID64::Enumerate(typename ReadYaml::StreamT& reader) { - *this = UniqueIDBridge::MakePathFromString(reader.readString()); -} -template <> -void UniqueID64::Enumerate(typename WriteYaml::StreamT& writer) { - if (!isValid()) - return; - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this); - if (!path) - return; - writer.writeString(path.getEncodableString()); -} -template <> -void UniqueID64::Enumerate(typename BinarySize::StreamT& s) { - s += 8; -} - -std::string UniqueID64::toString() const { return fmt::format(FMT_STRING("{}"), *this); } - -/** PAK 128-bit Unique ID */ -template <> -void UniqueID128::Enumerate(typename Read::StreamT& reader) { - m_id.id[0] = reader.readUint64Big(); - m_id.id[1] = reader.readUint64Big(); -} -template <> -void UniqueID128::Enumerate(typename Write::StreamT& writer) { - writer.writeUint64Big(m_id.id[0]); - writer.writeUint64Big(m_id.id[1]); -} -template <> -void UniqueID128::Enumerate(typename ReadYaml::StreamT& reader) { - *this = UniqueIDBridge::MakePathFromString(reader.readString()); -} -template <> -void UniqueID128::Enumerate(typename WriteYaml::StreamT& writer) { - if (!isValid()) - return; - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this); - if (!path) - return; - writer.writeString(path.getEncodableString()); -} -template <> -void UniqueID128::Enumerate(typename BinarySize::StreamT& s) { - s += 16; -} - -std::string UniqueID128::toString() const { return fmt::format(FMT_STRING("{}"), *this); } - -/** Word Bitmap reader/writer */ -void WordBitmap::read(athena::io::IStreamReader& reader, size_t bitCount) { - m_bitCount = bitCount; - size_t wordCount = (bitCount + 31) / 32; - m_words.clear(); - m_words.reserve(wordCount); - for (size_t w = 0; w < wordCount; ++w) - m_words.push_back(reader.readUint32Big()); -} -void WordBitmap::write(athena::io::IStreamWriter& writer) const { - for (atUint32 word : m_words) - writer.writeUint32Big(word); -} -void WordBitmap::binarySize(size_t& __isz) const { __isz += m_words.size() * 4; } - -hecl::ProjectPath GetPathBeginsWith(const hecl::DirectoryEnumerator& dEnum, const hecl::ProjectPath& parentPath, - std::string_view test) { - for (const auto& ent : dEnum) - if (hecl::StringUtils::BeginsWith(ent.m_name, test)) - return hecl::ProjectPath(parentPath, ent.m_name); - return {}; -} - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/DNACommon.hpp b/DataSpec/DNACommon/DNACommon.hpp deleted file mode 100644 index ed9e856bb..000000000 --- a/DataSpec/DNACommon/DNACommon.hpp +++ /dev/null @@ -1,394 +0,0 @@ -#pragma once - -#include -#include "logvisor/logvisor.hpp" -#include "athena/DNAYaml.hpp" -#include "hecl/Database.hpp" -#include "../SpecBase.hpp" -#include "boo/ThreadLocalPtr.hpp" -#include "zeus/CColor.hpp" - -namespace DataSpec { -struct SpecBase; - -extern logvisor::Module LogDNACommon; -extern ThreadLocalPtr g_curSpec; -extern ThreadLocalPtr g_PakRouter; -extern ThreadLocalPtr g_ThreadBlenderToken; - -/* This comes up a great deal */ -using BigDNA = athena::io::DNA; -using BigDNAV = athena::io::DNAV; -using BigDNAVYaml = athena::io::DNAVYaml; - -/** FourCC with DNA read/write */ -using DNAFourCC = hecl::DNAFourCC; - -class DNAColor final : public BigDNA, public zeus::CColor { -public: - DNAColor() = default; - DNAColor(const zeus::CColor& color) : zeus::CColor(color) {} - AT_DECL_EXPLICIT_DNA_YAML -}; -template <> -inline void DNAColor::Enumerate(typename Read::StreamT& _r) { - zeus::CColor::readRGBABig(_r); -} -template <> -inline void DNAColor::Enumerate(typename Write::StreamT& _w) { - zeus::CColor::writeRGBABig(_w); -} -template <> -inline void DNAColor::Enumerate(typename ReadYaml::StreamT& _r) { - size_t count; - if (auto v = _r.enterSubVector(count)) { - zeus::simd_floats f; - f[0] = (count >= 1) ? _r.readFloat() : 0.f; - f[1] = (count >= 2) ? _r.readFloat() : 0.f; - f[2] = (count >= 3) ? _r.readFloat() : 0.f; - f[3] = (count >= 4) ? _r.readFloat() : 0.f; - mSimd.copy_from(f); - } -} -template <> -inline void DNAColor::Enumerate(typename WriteYaml::StreamT& _w) { - if (auto v = _w.enterSubVector()) { - zeus::simd_floats f(mSimd); - _w.writeFloat(f[0]); - _w.writeFloat(f[1]); - _w.writeFloat(f[2]); - _w.writeFloat(f[3]); - } -} -template <> -inline void DNAColor::Enumerate(typename BinarySize::StreamT& _s) { - _s += 16; -} - -using FourCC = hecl::FourCC; -class UniqueID32; -class UniqueID64; -class UniqueID128; - -/** Common virtual interface for runtime ambiguity resolution */ -class PAKRouterBase { -protected: - const SpecBase& m_dataSpec; - -public: - PAKRouterBase(const SpecBase& dataSpec) : m_dataSpec(dataSpec) {} - hecl::Database::Project& getProject() const { return m_dataSpec.getProject(); } - virtual hecl::ProjectPath getWorking(const UniqueID32&, bool silenceWarnings = false) const { - LogDNACommon.report(logvisor::Fatal, FMT_STRING("PAKRouter IDType mismatch; expected UniqueID32 specialization")); - return hecl::ProjectPath(); - } - virtual hecl::ProjectPath getWorking(const UniqueID64&, bool silenceWarnings = false) const { - LogDNACommon.report(logvisor::Fatal, FMT_STRING("PAKRouter IDType mismatch; expected UniqueID64 specialization")); - return hecl::ProjectPath(); - } - virtual hecl::ProjectPath getWorking(const UniqueID128&, bool silenceWarnings = false) const { - LogDNACommon.report(logvisor::Fatal, FMT_STRING("PAKRouter IDType mismatch; expected UniqueID128 specialization")); - return hecl::ProjectPath(); - } -}; - -/** Globally-accessed manager allowing UniqueID* classes to directly - * lookup destination paths of resources */ -class UniqueIDBridge { - friend class UniqueID32; - friend class UniqueID64; - - static ThreadLocalPtr s_Project; - -public: - template - static hecl::ProjectPath TranslatePakIdToPath(const IDType& id, bool silenceWarnings = false); - template - static hecl::ProjectPath MakePathFromString(std::string_view str); - - static void SetThreadProject(hecl::Database::Project& project); -}; - -/** PAK 32-bit Unique ID */ -class UniqueID32 : public BigDNA { -protected: - uint32_t m_id = 0xffffffff; - -public: - using value_type = uint32_t; - static UniqueID32 kInvalidId; - AT_DECL_EXPLICIT_DNA_YAML - bool isValid() const noexcept { return m_id != 0xffffffff && m_id != 0; } - void assign(uint32_t id) noexcept { m_id = id ? id : 0xffffffff; } - - UniqueID32& operator=(const hecl::ProjectPath& path) noexcept { - assign(path.parsedHash32()); - return *this; - } - - bool operator!=(const UniqueID32& other) const noexcept { return m_id != other.m_id; } - bool operator==(const UniqueID32& other) const noexcept { return m_id == other.m_id; } - bool operator<(const UniqueID32& other) const noexcept { return m_id < other.m_id; } - uint32_t toUint32() const noexcept { return m_id; } - uint64_t toUint64() const noexcept { return m_id; } - std::string toString() const; - void clear() noexcept { m_id = 0xffffffff; } - - UniqueID32() noexcept = default; - UniqueID32(uint32_t idin) noexcept { assign(idin); } - UniqueID32(athena::io::IStreamReader& reader) { read(reader); } - UniqueID32(const hecl::ProjectPath& path) noexcept { *this = path; } - UniqueID32(const char* hexStr) noexcept { - char copy[9]; - strncpy(copy, hexStr, 8); - copy[8] = '\0'; - assign(strtoul(copy, nullptr, 16)); - } - - static constexpr size_t BinarySize() noexcept { return 4; } -}; - -/** PAK 32-bit Unique ID - writes zero when invalid */ -class UniqueID32Zero : public UniqueID32 { -public: - AT_DECL_DNA_YAML - Delete __d2; - using UniqueID32::UniqueID32; -}; - -/** PAK 64-bit Unique ID */ -class UniqueID64 : public BigDNA { - uint64_t m_id = 0xffffffffffffffff; - -public: - using value_type = uint64_t; - AT_DECL_EXPLICIT_DNA_YAML - bool isValid() const noexcept { return m_id != 0xffffffffffffffff && m_id != 0; } - void assign(uint64_t id) noexcept { m_id = id ? id : 0xffffffffffffffff; } - - UniqueID64& operator=(const hecl::ProjectPath& path) noexcept { - assign(path.hash().val64()); - return *this; - } - - bool operator!=(const UniqueID64& other) const noexcept { return m_id != other.m_id; } - bool operator==(const UniqueID64& other) const noexcept { return m_id == other.m_id; } - bool operator<(const UniqueID64& other) const noexcept { return m_id < other.m_id; } - uint64_t toUint64() const noexcept { return m_id; } - std::string toString() const; - void clear() noexcept { m_id = 0xffffffffffffffff; } - - UniqueID64() noexcept = default; - UniqueID64(uint64_t idin) noexcept { assign(idin); } - UniqueID64(athena::io::IStreamReader& reader) { read(reader); } - UniqueID64(const hecl::ProjectPath& path) noexcept { *this = path; } - UniqueID64(const char* hexStr) noexcept { - char copy[17]; - std::strncpy(copy, hexStr, 16); - copy[16] = '\0'; - assign(std::strtoull(copy, nullptr, 16)); - } - - static constexpr size_t BinarySize() noexcept { return 8; } -}; - -/** PAK 128-bit Unique ID */ -class UniqueID128 : public BigDNA { -public: - union Value { - uint64_t id[2]; -#if __SSE__ - __m128i id128; -#endif - }; - -private: - Value m_id; - -public: - using value_type = uint64_t; - AT_DECL_EXPLICIT_DNA_YAML - UniqueID128() noexcept { - m_id.id[0] = 0xffffffffffffffff; - m_id.id[1] = 0xffffffffffffffff; - } - UniqueID128(uint64_t idin) noexcept { - m_id.id[0] = idin; - m_id.id[1] = 0; - } - bool isValid() const noexcept { - return m_id.id[0] != 0xffffffffffffffff && m_id.id[0] != 0 && m_id.id[1] != 0xffffffffffffffff && m_id.id[1] != 0; - } - - UniqueID128& operator=(const hecl::ProjectPath& path) noexcept { - m_id.id[0] = path.hash().val64(); - m_id.id[1] = 0; - return *this; - } - UniqueID128(const hecl::ProjectPath& path) noexcept { *this = path; } - - bool operator!=(const UniqueID128& other) const noexcept { -#if __SSE__ - __m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128); - int vmask = _mm_movemask_epi8(vcmp); - return vmask != 0xffff; -#else - return (m_id.id[0] != other.m_id.id[0]) || (m_id.id[1] != other.m_id.id[1]); -#endif - } - bool operator==(const UniqueID128& other) const noexcept { -#if __SSE__ - __m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128); - int vmask = _mm_movemask_epi8(vcmp); - return vmask == 0xffff; -#else - return (m_id.id[0] == other.m_id.id[0]) && (m_id.id[1] == other.m_id.id[1]); -#endif - } - bool operator<(const UniqueID128& other) const noexcept { - return m_id.id[0] < other.m_id.id[0] || (m_id.id[0] == other.m_id.id[0] && m_id.id[1] < other.m_id.id[1]); - } - void clear() noexcept { - m_id.id[0] = 0xffffffffffffffff; - m_id.id[1] = 0xffffffffffffffff; - } - uint64_t toUint64() const noexcept { return m_id.id[0]; } - uint64_t toHighUint64() const noexcept { return m_id.id[0]; } - uint64_t toLowUint64() const noexcept { return m_id.id[1]; } - std::string toString() const; - - static constexpr size_t BinarySize() noexcept { return 16; } -}; - -/** Casts ID type to its null-zero equivalent */ -template -using CastIDToZero = typename std::conditional_t, UniqueID32Zero, T>; - -/** Word Bitmap reader/writer */ -class WordBitmap { - std::vector m_words; - size_t m_bitCount = 0; - -public: - void read(athena::io::IStreamReader& reader, size_t bitCount); - void write(athena::io::IStreamWriter& writer) const; - void reserve(size_t bitCount) { m_words.reserve((bitCount + 31) / 32); } - void binarySize(size_t& __isz) const; - size_t getBitCount() const { return m_bitCount; } - bool getBit(size_t idx) const { - size_t wordIdx = idx / 32; - if (wordIdx >= m_words.size()) - return false; - size_t wordCur = idx % 32; - return (m_words[wordIdx] >> wordCur) & 0x1; - } - void setBit(size_t idx) { - size_t wordIdx = idx / 32; - while (wordIdx >= m_words.size()) - m_words.push_back(0); - size_t wordCur = idx % 32; - m_words[wordIdx] |= (1 << wordCur); - m_bitCount = std::max(m_bitCount, idx + 1); - } - void unsetBit(size_t idx) { - size_t wordIdx = idx / 32; - while (wordIdx >= m_words.size()) - m_words.push_back(0); - size_t wordCur = idx % 32; - m_words[wordIdx] &= ~(1 << wordCur); - m_bitCount = std::max(m_bitCount, idx + 1); - } - void clear() { - m_words.clear(); - m_bitCount = 0; - } - - class Iterator { - friend class WordBitmap; - const WordBitmap& m_bmp; - size_t m_idx = 0; - Iterator(const WordBitmap& bmp, size_t idx) : m_bmp(bmp), m_idx(idx) {} - - public: - using iterator_category = std::forward_iterator_tag; - using value_type = bool; - using difference_type = std::ptrdiff_t; - using pointer = bool*; - using reference = bool&; - - Iterator& operator++() { - ++m_idx; - return *this; - } - bool operator*() const { return m_bmp.getBit(m_idx); } - bool operator!=(const Iterator& other) const { return m_idx != other.m_idx; } - }; - Iterator begin() const { return Iterator(*this, 0); } - Iterator end() const { return Iterator(*this, m_bitCount); } -}; - -/** Resource cooker function */ -using ResCooker = std::function; - -/** Mappings of resources involved in extracting characters */ -template -struct CharacterAssociations { - struct RigPair { - IDType cskr, cinf; - }; - struct ModelRigPair { - IDType cinf, cmdl; - }; - /* CMDL -> (CSKR, CINF) */ - std::unordered_map m_cmdlRigs; - /* CSKR -> ANCS */ - std::unordered_map> m_cskrToCharacter; - /* ANCS -> (CINF, CMDL) */ - std::unordered_multimap> m_characterToAttachmentRigs; - using MultimapIteratorPair = - std::pair>::const_iterator, - typename std::unordered_multimap>::const_iterator>; - void addAttachmentRig(IDType character, IDType cinf, IDType cmdl, const char* name) { - auto range = m_characterToAttachmentRigs.equal_range(character); - for (auto it = range.first; it != range.second; ++it) - if (it->second.second == name) - return; - m_characterToAttachmentRigs.insert(std::make_pair(character, std::make_pair(ModelRigPair{cinf, cmdl}, name))); - } -}; - -hecl::ProjectPath GetPathBeginsWith(const hecl::DirectoryEnumerator& dEnum, const hecl::ProjectPath& parentPath, - std::string_view test); -inline hecl::ProjectPath GetPathBeginsWith(const hecl::ProjectPath& parentPath, std::string_view test) { - return GetPathBeginsWith(hecl::DirectoryEnumerator(parentPath.getAbsolutePath()), parentPath, test); -} - -} // namespace DataSpec - -/* Hash template-specializations for UniqueID types */ -namespace std { -template <> -struct hash { - size_t operator()(const DataSpec::DNAFourCC& fcc) const noexcept { return fcc.toUint32(); } -}; - -template <> -struct hash { - size_t operator()(const DataSpec::UniqueID32& id) const noexcept { return id.toUint32(); } -}; - -template <> -struct hash { - size_t operator()(const DataSpec::UniqueID64& id) const noexcept { return id.toUint64(); } -}; - -template <> -struct hash { - size_t operator()(const DataSpec::UniqueID128& id) const noexcept { return id.toHighUint64() ^ id.toLowUint64(); } -}; -} // namespace std - -FMT_CUSTOM_FORMATTER(DataSpec::UniqueID32, "{:08X}", obj.toUint32()) -FMT_CUSTOM_FORMATTER(DataSpec::UniqueID32Zero, "{:08X}", obj.toUint32()) -FMT_CUSTOM_FORMATTER(DataSpec::UniqueID64, "{:016X}", obj.toUint64()) -FMT_CUSTOM_FORMATTER(DataSpec::UniqueID128, "{:016X}{:016X}", obj.toHighUint64(), obj.toLowUint64()) diff --git a/DataSpec/DNACommon/DPSC.cpp b/DataSpec/DNACommon/DPSC.cpp deleted file mode 100644 index 4b88eda08..000000000 --- a/DataSpec/DNACommon/DPSC.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "DataSpec/DNACommon/DPSC.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAParticle { - -template struct PPImpl<_DPSM>; -template struct PPImpl<_DPSM>; - -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_DPSM>) -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_DPSM>) - -template <> -std::string_view PPImpl<_DPSM>::DNAType() { - return "DPSM"sv; -} - -template <> -std::string_view PPImpl<_DPSM>::DNAType() { - return "DPSM"sv; -} - -template -bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - DPSM dpsm; - dpsm.read(rs); - athena::io::ToYAMLStream(dpsm, writer); - return true; - } - return false; -} -template bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteDPSM(const DPSM& dpsm, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - dpsm.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteDPSM(const DPSM& dpsm, const hecl::ProjectPath& outPath); -template bool WriteDPSM(const DPSM& dpsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/DPSC.def b/DataSpec/DNACommon/DPSC.def deleted file mode 100644 index ac61eb49f..000000000 --- a/DataSpec/DNACommon/DPSC.def +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef ENTRY -#define ENTRY(name, identifier) -#endif - -ENTRY('1LFT', x0_quad.x0_LFT) -ENTRY('1SZE', x0_quad.x4_SZE) -ENTRY('1ROT', x0_quad.x8_ROT) -ENTRY('1OFF', x0_quad.xc_OFF) -ENTRY('1CLR', x0_quad.x10_CLR) -ENTRY('1TEX', x0_quad.x14_TEX) -ENTRY('1ADD', x0_quad.x18_ADD) -ENTRY('2LFT', x1c_quad.x0_LFT) -ENTRY('2SZE', x1c_quad.x4_SZE) -ENTRY('2ROT', x1c_quad.x8_ROT) -ENTRY('2OFF', x1c_quad.xc_OFF) -ENTRY('2CLR', x1c_quad.x10_CLR) -ENTRY('2TEX', x1c_quad.x14_TEX) -ENTRY('2ADD', x1c_quad.x18_ADD) -ENTRY('DMDL', x38_DMDL) -ENTRY('DLFT', x48_DLFT) -ENTRY('DMOP', x4c_DMOP) -ENTRY('DMRT', x50_DMRT) -ENTRY('DMSC', x54_DMSC) -ENTRY('DMCL', x58_DMCL) -ENTRY('DMAB', x5c_24_DMAB) -ENTRY('DMOO', x5c_25_DMOO) - -#undef ENTRY diff --git a/DataSpec/DNACommon/DPSC.hpp b/DataSpec/DNACommon/DPSC.hpp deleted file mode 100644 index 56de7d9e6..000000000 --- a/DataSpec/DNACommon/DPSC.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ParticleCommon.hpp" - -#include - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAParticle { - -template -struct _DPSM { - static constexpr ParticleType Type = ParticleType::DPSM; - - struct SQuadDescr { - IntElementFactory x0_LFT; - RealElementFactory x4_SZE; - RealElementFactory x8_ROT; - VectorElementFactory xc_OFF; - ColorElementFactory x10_CLR; - UVElementFactory x14_TEX; - bool x18_ADD = false; - }; - - SQuadDescr x0_quad; - SQuadDescr x1c_quad; - ChildResourceFactory x38_DMDL; - IntElementFactory x48_DLFT; - VectorElementFactory x4c_DMOP; - VectorElementFactory x50_DMRT; - VectorElementFactory x54_DMSC; - ColorElementFactory x58_DMCL; - - bool x5c_24_DMAB = false; - bool x5c_25_DMOO = false; - - template - void constexpr Enumerate(_Func f) { -#define ENTRY(name, identifier) f(FOURCC(name), identifier); -#include "DPSC.def" - } - - template - bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { -#define ENTRY(name, identifier) \ - case SBIG(name): \ - f(identifier); \ - return true; -#include "DPSC.def" - default: - return false; - } - } -}; -template -using DPSM = PPImpl<_DPSM>; - -template -bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteDPSM(const DPSM& dpsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/DeafBabe.cpp b/DataSpec/DNACommon/DeafBabe.cpp deleted file mode 100644 index 51aa1bd4e..000000000 --- a/DataSpec/DNACommon/DeafBabe.cpp +++ /dev/null @@ -1,258 +0,0 @@ -#include "DataSpec/DNACommon/DeafBabe.hpp" - -#include -#include -#include -#include - -#include "DataSpec/DNACommon/AROTBuilder.hpp" -#include "DataSpec/DNAMP1/DeafBabe.hpp" -#include "DataSpec/DNAMP1/DCLN.hpp" -#include "DataSpec/DNAMP2/DeafBabe.hpp" - -#include -#include -#include - -namespace DataSpec { - -template -void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, bool isDcln, atInt32 idx) { - os << "material_index = []\n" - "col_bm = bmesh.new()\n"; - for (const atVec3f& vert : db.verts) { - zeus::simd_floats f(vert.simd); - os.format(FMT_STRING("col_bm.verts.new(({},{},{}))\n"), f[0], f[1], f[2]); - } - - os << "col_bm.verts.ensure_lookup_table()\n"; - - int triIdx = 0; - for (const typename DEAFBABE::Triangle& tri : db.triangleEdgeConnections) { - const typename DEAFBABE::Material& triMat = db.materials[db.triMats[triIdx++]]; - const typename DEAFBABE::Edge& edge0 = db.edgeVertConnections[tri.edges[0]]; - const typename DEAFBABE::Edge& edge1 = db.edgeVertConnections[tri.edges[1]]; - const typename DEAFBABE::Edge& edge2 = db.edgeVertConnections[tri.edges[2]]; - if (!edge0.verts[0] && !edge1.verts[0] && !edge2.verts[0]) - break; - - int vindices[3]; - vindices[2] = - (edge1.verts[0] != edge0.verts[0] && edge1.verts[0] != edge0.verts[1]) ? edge1.verts[0] : edge1.verts[1]; - - if (triMat.flipFace()) { - vindices[0] = edge0.verts[1]; - vindices[1] = edge0.verts[0]; - } else { - vindices[0] = edge0.verts[0]; - vindices[1] = edge0.verts[1]; - } - - os << "tri_verts = []\n"; - os.format(FMT_STRING("tri_verts.append(col_bm.verts[{}])\n"), vindices[0]); - os.format(FMT_STRING("tri_verts.append(col_bm.verts[{}])\n"), vindices[1]); - os.format(FMT_STRING("tri_verts.append(col_bm.verts[{}])\n"), vindices[2]); - - os.format(FMT_STRING("face = col_bm.faces.get(tri_verts)\n" - "if face is None:\n" - " face = col_bm.faces.new(tri_verts)\n" - "else:\n" - " face = face.copy()\n" - " for i in range(3):\n" - " face.verts[i].co = tri_verts[i].co\n" - " col_bm.verts.ensure_lookup_table()\n" - "face.material_index = select_material(0x{:016X}" - ")\n" - "face.smooth = False\n" - "\n"), - atUint64(triMat.material)); - } - - db.insertNoClimb(os); - - if (isDcln) - os.format(FMT_STRING("col_mesh = bpy.data.meshes.new('CMESH_{}')\n"), idx); - else - os << "col_mesh = bpy.data.meshes.new('CMESH')\n"; - - os << "col_bm.to_mesh(col_mesh)\n" - "col_mesh_obj = bpy.data.objects.new(col_mesh.name, col_mesh)\n" - "\n" - "for mat_name in material_index:\n" - " mat = material_dict[mat_name]\n" - " col_mesh.materials.append(mat)\n" - "\n" - "if 'Collision' not in bpy.data.collections:\n" - " coll = bpy.data.collections.new('Collision')\n" - " bpy.context.scene.collection.children.link(coll)\n" - "else:\n" - " coll = bpy.data.collections['Collision']\n" - "coll.objects.link(col_mesh_obj)\n" - "bpy.context.view_layer.objects.active = col_mesh_obj\n" - "bpy.ops.object.mode_set(mode='EDIT')\n" - "bpy.ops.mesh.tris_convert_to_quads()\n" - "bpy.ops.object.mode_set(mode='OBJECT')\n" - "bpy.context.view_layer.objects.active = None\n" - "col_mesh_obj.display_type = 'SOLID'\n" - "\n"; -} - -template void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DNAMP1::DeafBabe& db, - bool isDcln, atInt32 idx); -template void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DNAMP2::DeafBabe& db, - bool isDcln, atInt32 idx); -template void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, - const DNAMP1::DCLN::Collision& db, bool isDcln, - atInt32 idx); - -template -static void PopulateAreaFields( - DEAFBABE& db, const hecl::blender::ColMesh& colMesh, const zeus::CAABox& fullAABB, - std::enable_if_t::value || std::is_same::value, - int>* = 0) { - AROTBuilder builder; - auto octree = builder.buildCol(colMesh, db.rootNodeType); - static_cast&>(db.bspTree) = std::move(octree.first); - db.bspSize = octree.second; - - db.unk1 = 0x1000000; - size_t dbSize = 0; - db.binarySize(dbSize); - db.length = dbSize - 8; - db.magic = 0xDEAFBABE; - db.version = 3; - db.aabb[0] = fullAABB.min; - db.aabb[1] = fullAABB.max; -} - -template -static void PopulateAreaFields(DEAFBABE& db, const hecl::blender::ColMesh& colMesh, const zeus::CAABox& fullAABB, - std::enable_if_t::value, int>* = 0) { - db.magic = 0xDEAFBABE; - db.version = 2; - db.memSize = 0; -} - -class MaterialPool { - std::unordered_map m_materials; - -public: - template - int AddOrLookup(const M& mat, V& vec) { - auto search = m_materials.find(mat.material); - if (search != m_materials.end()) - return search->second; - auto idx = int(vec.size()); - vec.push_back(mat); - m_materials[mat.material] = idx; - return idx; - } -}; - -template -void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMesh) { - using BlendMat = hecl::blender::ColMesh::Material; - - auto MakeMat = [](const BlendMat& mat, bool flipFace) -> typename DEAFBABE::Material { - typename DEAFBABE::Material dbMat = {}; - dbMat.setUnknown(mat.unknown); - dbMat.setSurfaceStone(mat.surfaceStone); - dbMat.setSurfaceMetal(mat.surfaceMetal); - dbMat.setSurfaceGrass(mat.surfaceGrass); - dbMat.setSurfaceIce(mat.surfaceIce); - dbMat.setPillar(mat.pillar); - dbMat.setSurfaceMetalGrating(mat.surfaceMetalGrating); - dbMat.setSurfacePhazon(mat.surfacePhazon); - dbMat.setSurfaceDirt(mat.surfaceDirt); - dbMat.setSurfaceLava(mat.surfaceLava); - dbMat.setSurfaceSPMetal(mat.surfaceSPMetal); - dbMat.setSurfaceLavaStone(mat.surfaceLavaStone); - dbMat.setSurfaceSnow(mat.surfaceSnow); - dbMat.setSurfaceMudSlow(mat.surfaceMudSlow); - dbMat.setSurfaceFabric(mat.surfaceFabric); - dbMat.setHalfPipe(mat.halfPipe); - dbMat.setSurfaceMud(mat.surfaceMud); - dbMat.setSurfaceGlass(mat.surfaceGlass); - dbMat.setUnused3(mat.unused3); - dbMat.setUnused4(mat.unused4); - dbMat.setSurfaceShield(mat.surfaceShield); - dbMat.setSurfaceSand(mat.surfaceSand); - dbMat.setSurfaceMothOrSeedOrganics(mat.surfaceMothOrSeedOrganics); - dbMat.setSurfaceWeb(mat.surfaceWeb); - dbMat.setProjectilePassthrough(mat.projPassthrough); - dbMat.setSolid(mat.solid); - dbMat.setNoPlatformCollision(mat.noPlatformCollision); - dbMat.setCameraPassthrough(mat.camPassthrough); - dbMat.setSurfaceWood(mat.surfaceWood); - dbMat.setSurfaceOrganic(mat.surfaceOrganic); - dbMat.setNoEdgeCollision(mat.noEdgeCollision); - dbMat.setSurfaceRubber(mat.surfaceRubber); - dbMat.setSeeThrough(mat.seeThrough); - dbMat.setScanPassthrough(mat.scanPassthrough); - dbMat.setAiPassthrough(mat.aiPassthrough); - dbMat.setCeiling(mat.ceiling); - dbMat.setWall(mat.wall); - dbMat.setFloor(mat.floor); - dbMat.setAiBlock(mat.aiBlock); - dbMat.setJumpNotAllowed(mat.jumpNotAllowed); - dbMat.setSpiderBall(mat.spiderBall); - dbMat.setScrewAttackWallJump(mat.screwAttackWallJump); - dbMat.setFlipFace(flipFace); - return dbMat; - }; - - MaterialPool matPool; - db.materials.reserve(colMesh.materials.size() * 2); - - zeus::CAABox fullAABB; - - db.verts.reserve(colMesh.verts.size()); - db.vertMats.resize(colMesh.verts.size()); - for (const auto& vert : colMesh.verts) { - fullAABB.accumulateBounds(zeus::CVector3f(vert)); - db.verts.push_back(vert); - } - db.vertMatsCount = colMesh.verts.size(); - db.vertCount = colMesh.verts.size(); - - db.edgeVertConnections.reserve(colMesh.edges.size()); - db.edgeMats.resize(colMesh.edges.size()); - for (const auto& edge : colMesh.edges) { - db.edgeVertConnections.emplace_back(); - db.edgeVertConnections.back().verts[0] = edge.verts[0]; - db.edgeVertConnections.back().verts[1] = edge.verts[1]; - } - db.edgeMatsCount = colMesh.edges.size(); - db.edgeVertsCount = colMesh.edges.size(); - - db.triMats.reserve(colMesh.trianges.size()); - db.triangleEdgeConnections.reserve(colMesh.trianges.size()); - for (const auto& tri : colMesh.trianges) { - int triMatIdx = matPool.AddOrLookup(MakeMat(colMesh.materials[tri.matIdx], tri.flip), db.materials); - db.triMats.push_back(triMatIdx); - - db.triangleEdgeConnections.emplace_back(); - db.triangleEdgeConnections.back().edges[0] = tri.edges[0]; - db.triangleEdgeConnections.back().edges[1] = tri.edges[1]; - db.triangleEdgeConnections.back().edges[2] = tri.edges[2]; - - for (int e = 0; e < 3; ++e) { - db.edgeMats[tri.edges[e]] = triMatIdx; - for (int v = 0; v < 2; ++v) - db.vertMats[colMesh.edges[e].verts[v]] = triMatIdx; - } - } - db.triMatsCount = colMesh.trianges.size(); - db.triangleEdgesCount = colMesh.trianges.size() * 3; - - db.materialCount = db.materials.size(); - - PopulateAreaFields(db, colMesh, fullAABB); -} - -template void DeafBabeBuildFromBlender(DNAMP1::DeafBabe& db, const hecl::blender::ColMesh& colMesh); -template void DeafBabeBuildFromBlender(DNAMP2::DeafBabe& db, const hecl::blender::ColMesh& colMesh); -template void DeafBabeBuildFromBlender(DNAMP1::DCLN::Collision& db, - const hecl::blender::ColMesh& colMesh); - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/DeafBabe.hpp b/DataSpec/DNACommon/DeafBabe.hpp deleted file mode 100644 index 230df7a77..000000000 --- a/DataSpec/DNACommon/DeafBabe.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include - -namespace hecl::blender { -class PyOutStream; -struct ColMesh; -} // namespace hecl::blender - -namespace DataSpec { - -enum class BspNodeType : atUint32 { Invalid, Branch, Leaf }; - -template -void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, bool isDcln = false, atInt32 idx = -1); - -template -void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMesh); - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/EGMC.hpp b/DataSpec/DNACommon/EGMC.hpp deleted file mode 100644 index 54f7b717b..000000000 --- a/DataSpec/DNACommon/EGMC.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace DataSpec::DNACommon { -struct EGMC : public BigDNA { - AT_DECL_DNA - Value count; - - struct Object : BigDNA { - AT_DECL_DNA - Value mesh; - Value instanceId; - }; - - Vector objects; -}; -} // namespace DataSpec::DNACommon diff --git a/DataSpec/DNACommon/ELSC.cpp b/DataSpec/DNACommon/ELSC.cpp deleted file mode 100644 index 32d3d3cac..000000000 --- a/DataSpec/DNACommon/ELSC.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "DataSpec/DNACommon/ELSC.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAParticle { - -template struct PPImpl<_ELSM>; -template struct PPImpl<_ELSM>; - -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_ELSM>) -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_ELSM>) - -template <> -std::string_view ELSM::DNAType() { - return "ELSM"sv; -} - -template <> -std::string_view ELSM::DNAType() { - return "ELSM"sv; -} - -template -bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - ELSM elsm; - elsm.read(rs); - athena::io::ToYAMLStream(elsm, writer); - return true; - } - return false; -} -template bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteELSM(const ELSM& elsm, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - elsm.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteELSM(const ELSM& gpsm, const hecl::ProjectPath& outPath); -template bool WriteELSM(const ELSM& gpsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/ELSC.def b/DataSpec/DNACommon/ELSC.def deleted file mode 100644 index b8498ab1a..000000000 --- a/DataSpec/DNACommon/ELSC.def +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef ENTRY -#define ENTRY(name, identifier) -#endif - -#ifndef INT_ENTRY -#define INT_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef REAL_ENTRY -#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef COLOR_ENTRY -#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef EMITTER_ENTRY -#define EMITTER_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef RES_ENTRY -#define RES_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef BOOL_ENTRY -#define BOOL_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -INT_ENTRY('LIFE', x0_LIFE) -INT_ENTRY('SLIF', x4_SLIF) -REAL_ENTRY('GRAT', x8_GRAT) -INT_ENTRY('SCNT', xc_SCNT) -INT_ENTRY('SSEG', x10_SSEG) -COLOR_ENTRY('COLR', x14_COLR) -EMITTER_ENTRY('IEMT', x18_IEMT) -EMITTER_ENTRY('FEMT', x1c_FEMT) -REAL_ENTRY('AMPL', x20_AMPL) -REAL_ENTRY('AMPD', x24_AMPD) -REAL_ENTRY('LWD1', x28_LWD1) -REAL_ENTRY('LWD2', x2c_LWD2) -REAL_ENTRY('LWD3', x30_LWD3) -COLOR_ENTRY('LCL1', x34_LCL1) -COLOR_ENTRY('LCL2', x38_LCL2) -COLOR_ENTRY('LCL3', x3c_LCL3) -RES_ENTRY('SSWH', x40_SSWH) -RES_ENTRY('GPSM', x50_GPSM) -RES_ENTRY('EPSM', x60_EPSM) -BOOL_ENTRY('ZERY', x70_ZERY) - -#undef ENTRY -#undef INT_ENTRY -#undef REAL_ENTRY -#undef COLOR_ENTRY -#undef EMITTER_ENTRY -#undef RES_ENTRY -#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/ELSC.hpp b/DataSpec/DNACommon/ELSC.hpp deleted file mode 100644 index e6881d9c0..000000000 --- a/DataSpec/DNACommon/ELSC.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/ParticleCommon.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -#include - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAParticle { - -template -struct _ELSM { - static constexpr ParticleType Type = ParticleType::ELSM; - -#define INT_ENTRY(name, identifier) IntElementFactory identifier; -#define REAL_ENTRY(name, identifier) RealElementFactory identifier; -#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; -#define EMITTER_ENTRY(name, identifier) EmitterElementFactory identifier; -#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; -#define BOOL_ENTRY(name, identifier) bool identifier = false; -#include "ELSC.def" - - template - void constexpr Enumerate(_Func f) { -#define ENTRY(name, identifier) f(FOURCC(name), identifier); -#include "ELSC.def" - } - - template - bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { -#define ENTRY(name, identifier) \ - case SBIG(name): \ - f(identifier); \ - return true; -#include "ELSC.def" - default: - return false; - } - } -}; -template -using ELSM = PPImpl<_ELSM>; - -template -bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteELSM(const ELSM& elsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/FONT.cpp b/DataSpec/DNACommon/FONT.cpp deleted file mode 100644 index 2c5a7c2a6..000000000 --- a/DataSpec/DNACommon/FONT.cpp +++ /dev/null @@ -1,235 +0,0 @@ -#include "DataSpec/DNACommon/FONT.hpp" - -#include "DataSpec/DNACommon/PAK.hpp" - -#include - -namespace DataSpec::DNAFont { -logvisor::Module LogModule("DataSpec::DNAFont"); - -template -void FONT::_read(athena::io::IStreamReader& __dna_reader) { - /* magic */ - DNAFourCC magic; - magic.read(__dna_reader); - if (magic != SBIG('FONT')) { - LogModule.report(logvisor::Fatal, FMT_STRING("Invalid FONT magic '{}'"), magic); - return; - } - /* version */ - version = __dna_reader.readUint32Big(); - /* unknown1 */ - unknown1 = __dna_reader.readUint32Big(); - /* lineHeight */ - lineHeight = __dna_reader.readInt32Big(); - /* verticalOffset */ - verticalOffset = __dna_reader.readInt32Big(); - /* lineMargin */ - lineMargin = __dna_reader.readInt32Big(); - /* unknown2 */ - unknown2 = __dna_reader.readBool(); - /* unknown3 */ - unknown3 = __dna_reader.readBool(); - /* unknown4 */ - unknown4 = __dna_reader.readUint32Big(); - /* fontSize */ - fontSize = __dna_reader.readUint32Big(); - /* name */ - name = __dna_reader.readString(-1); - /* textureId */ - textureId.read(__dna_reader); - /* textureFormat */ - textureFormat = __dna_reader.readUint32Big(); - /* glyphCount */ - glyphCount = __dna_reader.readUint32Big(); - /* glyphs */ - for (atUint32 i = 0; i < glyphCount; i++) { - if (version < 4) - glyphs.emplace_back(new GlyphMP1); - else - glyphs.emplace_back(new GlyphMP2); - glyphs.back()->read(__dna_reader); - } - /* kerningInfoCount */ - kerningInfoCount = __dna_reader.readUint32Big(); - /* kerningInfo */ - __dna_reader.enumerate(kerningInfo, kerningInfoCount); -} - -template -void FONT::_write(athena::io::IStreamWriter& __dna_writer) const { - /* magic */ - __dna_writer.writeBytes((atInt8*)"FONT", 4); - /* version */ - __dna_writer.writeUint32Big(version); - /* unknown1 */ - __dna_writer.writeUint32Big(unknown1); - /* lineHeight */ - __dna_writer.writeInt32Big(lineHeight); - /* verticalOffset */ - __dna_writer.writeInt32Big(verticalOffset); - /* lineMargin */ - __dna_writer.writeInt32Big(lineMargin); - /* unknown2 */ - __dna_writer.writeBool(unknown2); - /* unknown3 */ - __dna_writer.writeBool(unknown3); - /* unknown4 */ - __dna_writer.writeUint32Big(unknown4); - /* fontSize */ - __dna_writer.writeUint32Big(fontSize); - /* name */ - __dna_writer.writeString(name, -1); - /* textureId */ - textureId.write(__dna_writer); - /* textureFormat */ - __dna_writer.writeUint32Big(textureFormat); - /* glyphCount */ - __dna_writer.writeUint32Big(glyphCount); - /* glyphs */ - for (const std::unique_ptr& glyph : glyphs) - glyph->write(__dna_writer); - /* kerningInfoCount */ - __dna_writer.writeUint32Big(kerningInfoCount); - /* kerningInfo */ - __dna_writer.enumerate(kerningInfo); -} - -template -void FONT::_read(athena::io::YAMLDocReader& __dna_docin) { - /* version */ - version = __dna_docin.readUint32("version"); - /* unknown1 */ - unknown1 = __dna_docin.readUint32("unknown1"); - /* lineHeight */ - lineHeight = __dna_docin.readInt32("lineHeight"); - /* verticalOffset */ - verticalOffset = __dna_docin.readInt32("verticalOffset"); - /* lineMargin */ - lineMargin = __dna_docin.readInt32("lineMargin"); - /* unknown2 */ - unknown2 = __dna_docin.readBool("unknown2"); - /* unknown3 */ - unknown3 = __dna_docin.readBool("unknown3"); - /* unknown4 */ - unknown4 = __dna_docin.readUint32("unknown4"); - /* fontSize */ - fontSize = __dna_docin.readUint32("fontSize"); - /* name */ - name = __dna_docin.readString("name"); - /* textureId */ - __dna_docin.enumerate("textureId", textureId); - /* textureFormat */ - textureFormat = __dna_docin.readUint32("textureFormat"); - /* glyphCount */ - /* glyphs */ - size_t count; - if (auto v = __dna_docin.enterSubVector("glyphs", count)) { - glyphCount = count; - for (atUint32 i = 0; i < glyphCount; i++) { - if (version < 4) - glyphs.emplace_back(new GlyphMP1); - else - glyphs.emplace_back(new GlyphMP2); - - if (auto rec = __dna_docin.enterSubRecord()) - glyphs.back()->read(__dna_docin); - } - } - /* kerningInfoCount squelched */ - /* kerningInfo */ - kerningInfoCount = __dna_docin.enumerate("kerningInfo", kerningInfo); -} - -template -void FONT::_write(athena::io::YAMLDocWriter& __dna_docout) const { - /* version */ - __dna_docout.writeUint32("version", version); - /* unknown1 */ - __dna_docout.writeUint32("unknown1", unknown1); - /* lineHeight */ - __dna_docout.writeInt32("lineHeight", lineHeight); - /* verticalOffset */ - __dna_docout.writeInt32("verticalOffset", verticalOffset); - /* lineMargin */ - __dna_docout.writeInt32("lineMargin", lineMargin); - /* unknown2 */ - __dna_docout.writeBool("unknown2", unknown2); - /* unknown3 */ - __dna_docout.writeBool("unknown3", unknown3); - /* unknown4 */ - __dna_docout.writeUint32("unknown4", unknown4); - /* fontSize */ - __dna_docout.writeUint32("fontSize", fontSize); - /* name */ - __dna_docout.writeString("name", name); - /* textureId */ - __dna_docout.enumerate("textureId", textureId); - /* textureFormat */ - __dna_docout.writeUint32("textureFormat", textureFormat); - /* glyphCount squelched */ - /* glyphs */ - if (auto v = __dna_docout.enterSubVector("glyphs")) - for (const std::unique_ptr& glyph : glyphs) - if (auto rec = __dna_docout.enterSubRecord()) - glyph->write(__dna_docout); - /* kerningInfoCount squelched */ - /* kerningInfo */ - __dna_docout.enumerate("kerningInfo", kerningInfo); -} - -template <> -std::string_view FONT::DNAType() { - return "FONT"sv; -} - -template <> -std::string_view FONT::DNAType() { - return "FONT"sv; -} - -template -void FONT::_binarySize(size_t& __isz) const { - __isz += name.size() + 1; - textureId.binarySize(__isz); - for (const std::unique_ptr& glyph : glyphs) - glyph->binarySize(__isz); - for (const KerningInfo& k : kerningInfo) - k.binarySize(__isz); - __isz += 46; -} - -AT_SUBSPECIALIZE_DNA_YAML(FONT) -AT_SUBSPECIALIZE_DNA_YAML(FONT) - -template -bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - FONT font; - font.read(rs); - athena::io::ToYAMLStream(font, writer); - return true; - } - return false; -} - -template bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteFONT(const FONT& font, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - font.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteFONT(const FONT& font, const hecl::ProjectPath& outPath); -template bool WriteFONT(const FONT& font, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAFont diff --git a/DataSpec/DNACommon/FONT.hpp b/DataSpec/DNACommon/FONT.hpp deleted file mode 100644 index 0ebdef68d..000000000 --- a/DataSpec/DNACommon/FONT.hpp +++ /dev/null @@ -1,127 +0,0 @@ -#pragma once - -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -#include - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAFont { -struct GlyphRect : BigDNA { - AT_DECL_DNA_YAML - Value left; - Value top; - Value right; - Value bottom; -}; -struct IGlyph : BigDNAVYaml { - AT_DECL_DNA_YAMLV - Value m_character; - GlyphRect m_glyphRect; - - atUint16 character() const { return m_character; } - float left() const { return m_glyphRect.left; } - float top() const { return m_glyphRect.top; } - float right() const { return m_glyphRect.right; } - float bottom() const { return m_glyphRect.bottom; } - GlyphRect rect() const { return m_glyphRect; } - - virtual atInt32 layer() const { return 0; } - virtual atInt32 leftPadding() const = 0; - virtual atInt32 advance() const = 0; - virtual atInt32 rightPadding() const = 0; - virtual atInt32 width() const = 0; - virtual atInt32 height() const = 0; - virtual atInt32 baseline() const = 0; - virtual atInt32 kerningIndex() const = 0; -}; - -struct GlyphMP1 : IGlyph { - AT_DECL_DNA_YAMLV - Value m_leftPadding; - Value m_advance; - Value m_rightPadding; - Value m_width; - Value m_height; - Value m_baseline; - Value m_kerningIndex; - - atInt32 leftPadding() const override { return m_leftPadding; } - atInt32 advance() const override { return m_advance; } - atInt32 rightPadding() const override { return m_rightPadding; } - atInt32 width() const override { return m_width; } - atInt32 height() const override { return m_height; } - atInt32 baseline() const override { return m_baseline; } - atInt32 kerningIndex() const override { return m_kerningIndex; } -}; - -struct GlyphMP2 : IGlyph { - AT_DECL_DNA_YAMLV - Value m_layer; - Value m_leftPadding; - Value m_advance; - Value m_rightPadding; - Value m_width; - Value m_height; - Value m_baseline; - Value m_kerningIndex; - - atInt32 layer() const override { return m_layer; } - atInt32 leftPadding() const override { return m_leftPadding; } - atInt32 advance() const override { return m_advance; } - atInt32 rightPadding() const override { return m_rightPadding; } - atInt32 width() const override { return m_width; } - atInt32 height() const override { return m_height; } - atInt32 baseline() const override { return m_baseline; } - atInt32 kerningIndex() const override { return m_kerningIndex; } -}; - -struct KerningInfo : BigDNA { - AT_DECL_DNA_YAML - Value thisChar; - Value nextChar; - Value adjust; -}; - -template -struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FONT : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - Value version; - Value unknown1; - Value lineHeight; - Value verticalOffset; - Value lineMargin; - Value unknown2; - Value unknown3; - Value unknown4; - Value fontSize; // in points - String<-1> name; - Value textureId; - Value textureFormat; - Value glyphCount; - std::vector> glyphs; - Value kerningInfoCount; - Vector kerningInfo; - - void gatherDependencies(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(textureId, pathsOut); - } -}; - -template -bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteFONT(const FONT& font, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAFont diff --git a/DataSpec/DNACommon/FSM2.cpp b/DataSpec/DNACommon/FSM2.cpp deleted file mode 100644 index 535c2dc1b..000000000 --- a/DataSpec/DNACommon/FSM2.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "DataSpec/DNACommon/FSM2.hpp" - -#include "DataSpec/DNACommon/PAK.hpp" - -#include -#include -#include - -#include - -namespace DataSpec::DNAFSM2 { -logvisor::Module LogDNAFSM2("DataSpec::DNAFSM2"); - -template -template -void FSM2::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"header"}, header, s); - if (header.magic != SBIG('FSM2')) { - LogDNAFSM2.report(logvisor::Fatal, FMT_STRING("Invalid FSM2 magic '{}' expected 'FSM2'"), header.magic); - return; - } - - if (header.version == 1) { - if (!detail) - detail.reset(new FSMV1); - Do(athena::io::PropId{"detail"}, static_cast(*detail), s); - } else if (header.version == 2) { - if (!detail) - detail.reset(new FSMV2); - Do(athena::io::PropId{"detail"}, static_cast(*detail), s); - } else { - LogDNAFSM2.report(logvisor::Fatal, FMT_STRING("Invalid FSM2 version '{}'"), header.version); - return; - } -} - -AT_SPECIALIZE_DNA(FSM2) -AT_SPECIALIZE_DNA(FSM2) - -template <> -std::string_view FSM2::DNAType() { - return "FSM2"sv; -} - -template <> -std::string_view FSM2::DNAType() { - return "FSM2"sv; -} - -template struct FSM2; -template struct FSM2; - -template -bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - FSM2 fsm2; - fsm2.read(rs); - athena::io::ToYAMLStream(fsm2, writer); - return true; - } - return false; -} -template bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteFSM2(const FSM2& fsm2, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - fsm2.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteFSM2(const FSM2& fsm2, const hecl::ProjectPath& outPath); -template bool WriteFSM2(const FSM2& fsm2, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAFSM2 diff --git a/DataSpec/DNACommon/FSM2.hpp b/DataSpec/DNACommon/FSM2.hpp deleted file mode 100644 index 163e22243..000000000 --- a/DataSpec/DNACommon/FSM2.hpp +++ /dev/null @@ -1,147 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -#include - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAFSM2 { -struct IFSM : BigDNAVYaml { - Delete _d; -}; - -template -struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FSM2 : BigDNA { - struct Header : BigDNA { - AT_DECL_DNA_YAML - DNAFourCC magic = FOURCC('FSM2'); - Value version; - } header; - - struct CommonStruct : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknown; - }; - - struct FSMV1 : IFSM { - AT_DECL_DNA_YAMLV - Value stateCount; - Value unknown1Count; - Value unknown2Count; - Value unknown3Count; - struct State : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknownCount; - Vector unknown; - }; - - struct Unknown1 : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknown1; - Value unknown2Count; - Vector unknown2; - Value unknown3; - }; - - struct Unknown2 : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknownCount; - Vector unknown; - }; - - struct Unknown3 : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknownCount; - Vector unknown; - Value fsmId; - }; - - Vector states; - Vector unknown1; - Vector unknown2; - Vector unknown3; - }; - - struct FSMV2 : IFSM { - AT_DECL_DNA_YAMLV - Value stateCount; - Value unknown1Count; - Value unknown2Count; - Value unknown3Count; - struct State : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5Count; - Vector unknown5; - }; - - struct Unknown1 : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6Count; - Vector unknown6; - Value unknown7; - }; - - struct Unknown2 : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5Count; - Vector unknown5; - }; - - struct Unknown3 : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5Count; - Vector unknown5; - Value fsmId; - }; - - Vector states; - Vector unknown1; - Vector unknown2; - Vector unknown3; - }; - - std::unique_ptr detail; - AT_DECL_EXPLICIT_DNA_YAML -}; - -template -bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template -bool WriteFSM2(const FSM2& fsm2, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAFSM2 diff --git a/DataSpec/DNACommon/GX.cpp b/DataSpec/DNACommon/GX.cpp deleted file mode 100644 index 88a3809ab..000000000 --- a/DataSpec/DNACommon/GX.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "GX.hpp" - -namespace GX { - -template <> -void Color::Enumerate::Read>(Read::StreamT& reader) { - reader.readUBytesToBuf(&num, 4); -} -template <> -void Color::Enumerate::Write>(Write::StreamT& writer) { - writer.writeUBytes(reinterpret_cast(&num), 4); -} -template <> -void Color::Enumerate::BinarySize>(BinarySize::StreamT& s) { - s += 4; -} - -} // namespace GX \ No newline at end of file diff --git a/DataSpec/DNACommon/GX.hpp b/DataSpec/DNACommon/GX.hpp deleted file mode 100644 index dc56be6ed..000000000 --- a/DataSpec/DNACommon/GX.hpp +++ /dev/null @@ -1,298 +0,0 @@ -#pragma once - -#include - -#include - -namespace GX { -enum AttrType { NONE, DIRECT, INDEX8, INDEX16 }; - -enum TevColorArg { - CC_CPREV = 0, - CC_APREV = 1, - CC_C0 = 2, - CC_A0 = 3, - CC_C1 = 4, - CC_A1 = 5, - CC_C2 = 6, - CC_A2 = 7, - CC_TEXC = 8, - CC_TEXA = 9, - CC_RASC = 10, - CC_RASA = 11, - CC_ONE = 12, - CC_HALF = 13, - CC_KONST = 14, - CC_ZERO = 15, -}; - -enum TevAlphaArg { - CA_APREV = 0, - CA_A0 = 1, - CA_A1 = 2, - CA_A2 = 3, - CA_TEXA = 4, - CA_RASA = 5, - CA_KONST = 6, - CA_ZERO = 7, -}; - -enum TevKColorSel { - TEV_KCSEL_8_8 = 0x00, - TEV_KCSEL_7_8 = 0x01, - TEV_KCSEL_6_8 = 0x02, - TEV_KCSEL_5_8 = 0x03, - TEV_KCSEL_4_8 = 0x04, - TEV_KCSEL_3_8 = 0x05, - TEV_KCSEL_2_8 = 0x06, - TEV_KCSEL_1_8 = 0x07, - - TEV_KCSEL_1 = TEV_KCSEL_8_8, - TEV_KCSEL_3_4 = TEV_KCSEL_6_8, - TEV_KCSEL_1_2 = TEV_KCSEL_4_8, - TEV_KCSEL_1_4 = TEV_KCSEL_2_8, - - TEV_KCSEL_K0 = 0x0C, - TEV_KCSEL_K1 = 0x0D, - TEV_KCSEL_K2 = 0x0E, - TEV_KCSEL_K3 = 0x0F, - TEV_KCSEL_K0_R = 0x10, - TEV_KCSEL_K1_R = 0x11, - TEV_KCSEL_K2_R = 0x12, - TEV_KCSEL_K3_R = 0x13, - TEV_KCSEL_K0_G = 0x14, - TEV_KCSEL_K1_G = 0x15, - TEV_KCSEL_K2_G = 0x16, - TEV_KCSEL_K3_G = 0x17, - TEV_KCSEL_K0_B = 0x18, - TEV_KCSEL_K1_B = 0x19, - TEV_KCSEL_K2_B = 0x1A, - TEV_KCSEL_K3_B = 0x1B, - TEV_KCSEL_K0_A = 0x1C, - TEV_KCSEL_K1_A = 0x1D, - TEV_KCSEL_K2_A = 0x1E, - TEV_KCSEL_K3_A = 0x1F -}; - -enum TevKAlphaSel { - TEV_KASEL_8_8 = 0x00, - TEV_KASEL_7_8 = 0x01, - TEV_KASEL_6_8 = 0x02, - TEV_KASEL_5_8 = 0x03, - TEV_KASEL_4_8 = 0x04, - TEV_KASEL_3_8 = 0x05, - TEV_KASEL_2_8 = 0x06, - TEV_KASEL_1_8 = 0x07, - - TEV_KASEL_1 = TEV_KASEL_8_8, - TEV_KASEL_3_4 = TEV_KASEL_6_8, - TEV_KASEL_1_2 = TEV_KASEL_4_8, - TEV_KASEL_1_4 = TEV_KASEL_2_8, - - TEV_KASEL_K0_R = 0x10, - TEV_KASEL_K1_R = 0x11, - TEV_KASEL_K2_R = 0x12, - TEV_KASEL_K3_R = 0x13, - TEV_KASEL_K0_G = 0x14, - TEV_KASEL_K1_G = 0x15, - TEV_KASEL_K2_G = 0x16, - TEV_KASEL_K3_G = 0x17, - TEV_KASEL_K0_B = 0x18, - TEV_KASEL_K1_B = 0x19, - TEV_KASEL_K2_B = 0x1A, - TEV_KASEL_K3_B = 0x1B, - TEV_KASEL_K0_A = 0x1C, - TEV_KASEL_K1_A = 0x1D, - TEV_KASEL_K2_A = 0x1E, - TEV_KASEL_K3_A = 0x1F -}; - -enum TevOp { - TEV_ADD = 0, - TEV_SUB = 1, - TEV_COMP_R8_GT = 8, - TEV_COMP_R8_EQ = 9, - TEV_COMP_GR16_GT = 10, - TEV_COMP_GR16_EQ = 11, - TEV_COMP_BGR24_GT = 12, - TEV_COMP_BGR24_EQ = 13, - TEV_COMP_RGB8_GT = 14, - TEV_COMP_RGB8_EQ = 15, - TEV_COMP_A8_GT = TEV_COMP_RGB8_GT, - TEV_COMP_A8_EQ = TEV_COMP_RGB8_EQ -}; - -enum TevBias { - TB_ZERO = 0, - TB_ADDHALF = 1, - TB_SUBHALF = 2, -}; - -enum TevScale { CS_SCALE_1 = 0, CS_SCALE_2 = 1, CS_SCALE_4 = 2, CS_DIVIDE_2 = 3 }; - -enum TexGenType { - TG_MTX3x4 = 0, - TG_MTX2x4, - TG_BUMP0, - TG_BUMP1, - TG_BUMP2, - TG_BUMP3, - TG_BUMP4, - TG_BUMP5, - TG_BUMP6, - TG_BUMP7, - TG_SRTG -}; - -enum TexGenSrc { - TG_POS = 0, - TG_NRM, - TG_BINRM, - TG_TANGENT, - TG_TEX0, - TG_TEX1, - TG_TEX2, - TG_TEX3, - TG_TEX4, - TG_TEX5, - TG_TEX6, - TG_TEX7, - TG_TEXCOORD0, - TG_TEXCOORD1, - TG_TEXCOORD2, - TG_TEXCOORD3, - TG_TEXCOORD4, - TG_TEXCOORD5, - TG_TEXCOORD6, - TG_COLOR0, - TG_COLOR1 -}; - -enum TexMtx { - TEXMTX0 = 30, - TEXMTX1 = 33, - TEXMTX2 = 36, - TEXMTX3 = 39, - TEXMTX4 = 42, - TEXMTX5 = 45, - TEXMTX6 = 48, - TEXMTX7 = 51, - TEXMTX8 = 54, - TEXMTX9 = 57, - IDENTITY = 60 -}; - -enum PTTexMtx { - PTTEXMTX0 = 64, - PTTEXMTX1 = 67, - PTTEXMTX2 = 70, - PTTEXMTX3 = 73, - PTTEXMTX4 = 76, - PTTEXMTX5 = 79, - PTTEXMTX6 = 82, - PTTEXMTX7 = 85, - PTTEXMTX8 = 88, - PTTEXMTX9 = 91, - PTTEXMTX10 = 94, - PTTEXMTX11 = 97, - PTTEXMTX12 = 100, - PTTEXMTX13 = 103, - PTTEXMTX14 = 106, - PTTEXMTX15 = 109, - PTTEXMTX16 = 112, - PTTEXMTX17 = 115, - PTTEXMTX18 = 118, - PTTEXMTX19 = 121, - PTIDENTITY = 125 -}; - -enum TevRegID { TEVPREV = 0, TEVREG0 = 1, TEVREG1 = 2, TEVREG2 = 3, TEVLAZY = 5 }; - -enum DiffuseFn { DF_NONE = 0, DF_SIGN, DF_CLAMP }; - -enum AttnFn { AF_SPEC = 0, AF_SPOT = 1, AF_NONE }; - -enum Primitive { - POINTS = 0xb8, - LINES = 0xa8, - LINESTRIP = 0xb0, - TRIANGLES = 0x90, - TRIANGLESTRIP = 0x98, - TRIANGLEFAN = 0xa0, - QUADS = 0x80 -}; - -enum ChannelID { - GX_COLOR0, - GX_COLOR1, - GX_ALPHA0, - GX_ALPHA1, - GX_COLOR0A0, - GX_COLOR1A1, - GX_COLOR_ZERO, - GX_ALPHA_BUMP, - GX_ALPHA_BUMPN, - GX_COLOR_NULL = 0xff -}; - -enum BlendFactor : uint16_t { - BL_ZERO, - BL_ONE, - BL_SRCCLR, - BL_INVSRCCLR, - BL_SRCALPHA, - BL_INVSRCALPHA, - BL_DSTALPHA, - BL_INVDSTALPHA -}; - -struct Color : athena::io::DNA { - union { - uint8_t color[4]; - uint32_t num = 0; - }; - Color() = default; - Color& operator=(const atVec4f& vec) { - athena::simd_floats f(vec.simd); - color[0] = uint8_t(std::min(std::max(f[0] * 255.f, 0.f), 255.f)); - color[1] = uint8_t(std::min(std::max(f[1] * 255.f, 0.f), 255.f)); - color[2] = uint8_t(std::min(std::max(f[2] * 255.f, 0.f), 255.f)); - color[3] = uint8_t(std::min(std::max(f[3] * 255.f, 0.f), 255.f)); - return *this; - } - Color& operator=(const atVec3f& vec) { - athena::simd_floats f(vec.simd); - color[0] = uint8_t(std::min(std::max(f[0] * 255.f, 0.f), 255.f)); - color[1] = uint8_t(std::min(std::max(f[1] * 255.f, 0.f), 255.f)); - color[2] = uint8_t(std::min(std::max(f[2] * 255.f, 0.f), 255.f)); - color[3] = 0xff; - return *this; - } - Color& operator=(uint8_t val) { - color[0] = val; - color[1] = val; - color[2] = val; - color[3] = val; - return *this; - } - atVec4f toVec4f() const { - atVec4f out; - athena::simd_floats f; - f[0] = color[0] / 255.f; - f[1] = color[1] / 255.f; - f[2] = color[2] / 255.f; - f[3] = color[3] / 255.f; - out.simd.copy_from(f); - return out; - } - Color(const atVec4f& vec) { *this = vec; } - Color(const atVec3f& vec) { *this = vec; } - Color(uint8_t val) { *this = val; } - bool operator==(const Color& other) const { return num == other.num; } - bool operator!=(const Color& other) const { return num != other.num; } - uint8_t operator[](size_t idx) const { return color[idx]; } - uint8_t& operator[](size_t idx) { return color[idx]; } - AT_DECL_EXPLICIT_DNA -}; - -} // namespace GX diff --git a/DataSpec/DNACommon/MAPA.cpp b/DataSpec/DNACommon/MAPA.cpp deleted file mode 100644 index 8a14db344..000000000 --- a/DataSpec/DNACommon/MAPA.cpp +++ /dev/null @@ -1,426 +0,0 @@ -#include "DataSpec/DNACommon/MAPA.hpp" - -#include "DataSpec/DNACommon/GX.hpp" -#include "DataSpec/DNAMP1/DNAMP1.hpp" -#include "DataSpec/DNAMP2/DNAMP2.hpp" -#include "DataSpec/DNAMP3/DNAMP3.hpp" -#include "DataSpec/DNAMP1/MAPA.hpp" -#include "DataSpec/DNAMP2/MAPA.hpp" -#include "DataSpec/DNAMP3/MAPA.hpp" - -#include -#include -#include - -namespace DataSpec::DNAMAPA { - -static logvisor::Module Log("DNAMAPA"); - -template <> -void MAPA::Enumerate(typename Read::StreamT& __dna_reader) { - /* magic */ - magic = __dna_reader.readUint32Big(); - if (magic != 0xDEADD00D) { - LogDNACommon.report(logvisor::Error, FMT_STRING("invalid MAPA magic")); - return; - } - /* version */ - version = __dna_reader.readUint32Big(); - if (version == 2) - header = std::make_unique(); - else if (version == 3) - header = std::make_unique(); - else if (version == 5) - header = std::make_unique(); - else { - LogDNACommon.report(logvisor::Error, FMT_STRING("invalid MAPA version")); - return; - } - - header->read(__dna_reader); - - for (atUint32 i = 0; i < header->mappableObjectCount(); i++) { - std::unique_ptr mo = nullptr; - if (version != 5) { - mo = std::make_unique(); - } else { - mo = std::make_unique(); - } - mo->read(__dna_reader); - mappableObjects.push_back(std::move(mo)); - } - - /* vertices */ - __dna_reader.enumerateBig(vertices, header->vertexCount()); - /* surfaceHeaders */ - __dna_reader.enumerate(surfaceHeaders, header->surfaceCount()); - /* surfaces */ - __dna_reader.enumerate(surfaces, header->surfaceCount()); -} - -template <> -void MAPA::Enumerate(typename Write::StreamT& __dna_writer) { - /* magic */ - __dna_writer.writeUint32Big(magic); - /* version */ - __dna_writer.writeUint32Big(version); - header->write(__dna_writer); - - /* mappableObjects */ - for (const std::unique_ptr& mo : mappableObjects) - mo->write(__dna_writer); - /* vertices */ - __dna_writer.enumerateBig(vertices); - /* surfaceHeaders */ - __dna_writer.enumerate(surfaceHeaders); - /* surfaces */ - __dna_writer.enumerate(surfaces); -} - -template <> -void MAPA::Enumerate(typename BinarySize::StreamT& s) { - header->binarySize(s); - - for (const std::unique_ptr& mo : mappableObjects) - mo->binarySize(s); - - s += vertices.size() * 12; - for (const SurfaceHeader& sh : surfaceHeaders) - sh.binarySize(s); - for (const Surface& su : surfaces) - su.binarySize(s); - s += 8; -} - -static const char* RetroMapVisModes[] = {"ALWAYS", "MAPSTATIONORVISIT", "VISIT", "NEVER"}; - -static const char* RetroMapObjVisModes[] = {"ALWAYS", "MAPSTATIONORVISIT", "VISIT", "NEVER", "MAPSTATIONORVISIT2"}; - -template -bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force) { - if (!force && outPath.isFile()) - return true; - - if (!conn.createBlend(outPath, hecl::blender::BlendType::MapArea)) - return false; - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - - os << "import bpy, bmesh\n" - "from mathutils import Matrix\n" - "\n" - "bpy.types.Object.retro_mappable_type = bpy.props.IntProperty(name='Retro: MAPA object type', default=-1)\n" - "bpy.types.Object.retro_mappable_sclyid = bpy.props.StringProperty(name='Retro: MAPA object SCLY ID')\n" - "bpy.types.Scene.retro_map_vis_mode = bpy.props.EnumProperty(items=[('ALWAYS', 'Always', 'Always Visible', 0)," - "('MAPSTATIONORVISIT', 'Map Station or Visit', 'Visible after Map Station or Visit', 1)," - "('VISIT', 'Visit', 'Visible after Visit', 2)," - "('NEVER', 'Never', 'Never Visible', 3)]," - "name='Retro: Map Visibility Mode')\n" - "bpy.types.Object.retro_mapobj_vis_mode = bpy.props.EnumProperty(items=[('ALWAYS', 'Always', 'Always Visible', " - "0)," - "('MAPSTATIONORVISIT', 'Map Station or Visit', 'Visible after Map Station or Visit', 1)," - "('VISIT', 'Visit', 'Visible after Door Visit', 2)," - "('NEVER', 'Never', 'Never Visible', 3)," - "('MAPSTATIONORVISIT2', 'Map Station or Visit 2', 'Visible after Map Station or Visit', 4)]," - "name='Retro: Map Object Visibility Mode')\n" - "\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "def add_triangle(bm, verts):\n" - " verts = [bm.verts[vi] for vi in verts]\n" - " face = bm.faces.get(verts)\n" - " if face:\n" - " face = face.copy()\n" - " bm.verts.ensure_lookup_table()\n" - " face.normal_flip()\n" - " else:\n" - " bm.faces.new(verts)\n" - "\n" - "def add_border(bm, verts):\n" - " verts = [bm.verts[vi] for vi in verts]\n" - " edge = bm.edges.get(verts)\n" - " if not edge:\n" - " edge = bm.edges.new(verts)\n" - " edge.seam = True\n" - "\n"; - - os.format(FMT_STRING("bpy.context.scene.name = 'MAPA_{}'\n" - "bpy.context.scene.retro_map_vis_mode = '{}'\n"), - entry.id, RetroMapVisModes[mapa.header->visMode()]); - - /* Add empties representing MappableObjects */ - int moIdx = 0; - for (const std::unique_ptr& mo : mapa.mappableObjects) { - if (mapa.version < 5) { - const MAPA::MappableObjectMP1_2* moMP12 = static_cast(mo.get()); - zeus::simd_floats mtxF[3]; - for (int i = 0; i < 3; ++i) - moMP12->transformMtx[i].simd.copy_to(mtxF[i]); - os.format(FMT_STRING("obj = bpy.data.objects.new('MAPOBJ_{:02d}', None)\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "obj.retro_mappable_type = {}\n" - "obj.retro_mapobj_vis_mode = '{}'\n" - "obj.retro_mappable_sclyid = '0x{:08X}'\n" - "mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "obj.rotation_mode = 'QUATERNION'\n" - "obj.location = mtxd[0]\n" - "obj.rotation_quaternion = mtxd[1]\n" - "obj.scale = mtxd[2]\n"), - moIdx, int(moMP12->type), RetroMapObjVisModes[moMP12->visMode], moMP12->sclyId, mtxF[0][0], mtxF[0][1], - mtxF[0][2], mtxF[0][3], mtxF[1][0], mtxF[1][1], mtxF[1][2], mtxF[1][3], mtxF[2][0], mtxF[2][1], - mtxF[2][2], mtxF[2][3]); - ++moIdx; - continue; - } else { - const MAPA::MappableObjectMP3* moMP3 = static_cast(mo.get()); - zeus::simd_floats mtxF[3]; - for (int i = 0; i < 3; ++i) - moMP3->transformMtx[i].simd.copy_to(mtxF[i]); - os.format(FMT_STRING("obj = bpy.data.objects.new('MAPOBJ_{:02d}', None)\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "obj.retro_mappable_type = {}\n" - "obj.retro_mapobj_vis_mode = '{}'\n" - "obj.retro_mappable_sclyid = '0x{:08X}'\n" - "mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "obj.rotation_mode = 'QUATERNION'\n" - "obj.location = mtxd[0]\n" - "obj.rotation_quaternion = mtxd[1]\n" - "obj.scale = mtxd[2]\n"), - moIdx, int(moMP3->type), RetroMapObjVisModes[moMP3->visMode], moMP3->sclyId, mtxF[0][0], mtxF[0][1], - mtxF[0][2], mtxF[0][3], mtxF[1][0], mtxF[1][1], mtxF[1][2], mtxF[1][3], mtxF[2][0], mtxF[2][1], - mtxF[2][2], mtxF[2][3]); - ++moIdx; - continue; - } - } - - os << "# Begin bmesh\n" - "bm = bmesh.new()\n" - "\n"; - - /* Read in verts */ - for (const atVec3f& vert : mapa.vertices) { - zeus::simd_floats f(vert.simd); - os.format(FMT_STRING("bm.verts.new(({},{},{}))\n"), f[0], f[1], f[2]); - } - os << "bm.verts.ensure_lookup_table()\n"; - - /* Read in surfaces */ - for (const typename MAPA::Surface& surf : mapa.surfaces) { - for (const typename MAPA::Surface::Primitive& prim : surf.primitives) { - auto iit = prim.indices.cbegin(); - - /* 3 Prim Verts to start */ - int c = 0; - unsigned int primVerts[3] = {*iit++, *iit++, *iit++}; - - if (GX::Primitive(prim.type) == GX::TRIANGLESTRIP) { - atUint8 flip = 0; - for (size_t v = 0; v < prim.indexCount - 2; ++v) { - if (flip) { - os.format(FMT_STRING("add_triangle(bm, ({},{},{}))\n"), primVerts[c % 3], primVerts[(c + 2) % 3], - primVerts[(c + 1) % 3]); - } else { - os.format(FMT_STRING("add_triangle(bm, ({},{},{}))\n"), primVerts[c % 3], primVerts[(c + 1) % 3], - primVerts[(c + 2) % 3]); - } - flip ^= 1; - - /* Break if done */ - if (iit == prim.indices.cend()) - break; - - bool peek = (v >= prim.indexCount - 3); - - /* Advance one prim vert */ - if (peek) - primVerts[c % 3] = *iit; - else - primVerts[c % 3] = *iit++; - ++c; - } - } else if (GX::Primitive(prim.type) == GX::TRIANGLES) { - for (size_t v = 0; v < prim.indexCount; v += 3) { - os.format(FMT_STRING("add_triangle(bm, ({},{},{}))\n"), primVerts[0], primVerts[1], primVerts[2]); - - /* Break if done */ - if (v + 3 >= prim.indexCount) - break; - - /* Advance 3 Prim Verts */ - for (int pv = 0; pv < 3; ++pv) - primVerts[pv] = *iit++; - } - } - } - - for (const typename MAPA::Surface::Border& border : surf.borders) { - auto iit = border.indices.cbegin(); - for (size_t i = 0; i < border.indexCount - 1; ++i) { - os.format(FMT_STRING("add_border(bm, ({},{}))\n"), *iit, *(iit + 1)); - ++iit; - } - } - } - - os << "mesh = bpy.data.meshes.new('MAP')\n" - "obj = bpy.data.objects.new(mesh.name, mesh)\n" - "bm.to_mesh(mesh)\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "bm.free()\n"; - - const zeus::CMatrix4f* tmpMtx = pakRouter.lookupMAPATransform(entry.id); - const zeus::CMatrix4f& mtx = tmpMtx ? *tmpMtx : zeus::skIdentityMatrix4f; - os.format(FMT_STRING("mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "obj.rotation_mode = 'QUATERNION'\n" - "obj.location = mtxd[0]\n" - "obj.rotation_quaternion = mtxd[1]\n" - "obj.scale = mtxd[2]\n"), - mtx[0][0], mtx[1][0], mtx[2][0], mtx[3][0], mtx[0][1], mtx[1][1], mtx[2][1], mtx[3][1], mtx[0][2], - mtx[1][2], mtx[2][2], mtx[3][2]); - - /* World background */ - hecl::ProjectPath worldDir = outPath.getParentPath().getParentPath(); - for (const auto& ent : hecl::DirectoryEnumerator(worldDir.getAbsolutePath())) { - if (hecl::StringUtils::BeginsWith(ent.m_name, "!world") && - hecl::StringUtils::EndsWith(ent.m_name, ".blend")) { - os.linkBackground(fmt::format(FMT_STRING("//../{}"), ent.m_name), "World"sv); - break; - } - } - - os.centerView(); - os.close(); - conn.saveBlend(); - return true; -} - -template bool ReadMAPAToBlender>(hecl::blender::Connection& conn, const MAPA& mapa, - const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - bool force); - -template bool ReadMAPAToBlender>(hecl::blender::Connection& conn, const MAPA& mapa, - const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - bool force); - -template bool ReadMAPAToBlender>(hecl::blender::Connection& conn, const MAPA& mapa, - const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - bool force); - -template -bool Cook(const hecl::blender::MapArea& mapaIn, const hecl::ProjectPath& out) { - if (mapaIn.verts.size() >= 256) { - Log.report(logvisor::Error, FMT_STRING("MAPA {} vertex range exceeded [{}/{}]"), out.getRelativePath(), - mapaIn.verts.size(), 255); - return false; - } - - MAPAType mapa; - mapa.magic = 0xDEADD00D; - mapa.version = MAPAType::Version(); - - zeus::CAABox aabb; - for (const hecl::blender::Vector3f& vert : mapaIn.verts) - aabb.accumulateBounds(vert.val); - - mapa.header = std::make_unique(); - typename MAPAType::Header& header = static_cast(*mapa.header); - header.unknown1 = 0; - header.mapVisMode = mapaIn.visType; - header.boundingBox[0] = aabb.min; - header.boundingBox[1] = aabb.max; - header.moCount = mapaIn.pois.size(); - header.vtxCount = mapaIn.verts.size(); - header.surfCount = mapaIn.surfaces.size(); - - mapa.mappableObjects.reserve(mapaIn.pois.size()); - for (const hecl::blender::MapArea::POI& poi : mapaIn.pois) { - mapa.mappableObjects.push_back(std::make_unique()); - typename MAPAType::MappableObject& mobj = - static_cast(*mapa.mappableObjects.back()); - mobj.type = MAPA::IMappableObject::Type(poi.type); - mobj.visMode = poi.visMode; - mobj.sclyId = poi.objid; - mobj.transformMtx[0] = poi.xf.val[0]; - mobj.transformMtx[1] = poi.xf.val[1]; - mobj.transformMtx[2] = poi.xf.val[2]; - } - - mapa.vertices.reserve(mapaIn.verts.size()); - for (const hecl::blender::Vector3f& vert : mapaIn.verts) - mapa.vertices.push_back(vert.val); - - size_t offsetCur = 0; - for (const auto& mo : mapa.mappableObjects) - mo->binarySize(offsetCur); - offsetCur += mapa.vertices.size() * 12; - offsetCur += mapaIn.surfaces.size() * 32; - - mapa.surfaceHeaders.reserve(mapaIn.surfaces.size()); - mapa.surfaces.reserve(mapaIn.surfaces.size()); - for (const hecl::blender::MapArea::Surface& surfIn : mapaIn.surfaces) { - mapa.surfaceHeaders.emplace_back(); - DNAMAPA::MAPA::SurfaceHeader& surfHead = mapa.surfaceHeaders.back(); - mapa.surfaces.emplace_back(); - DNAMAPA::MAPA::Surface& surf = mapa.surfaces.back(); - - surf.primitiveCount = 1; - surf.primitives.emplace_back(); - DNAMAPA::MAPA::Surface::Primitive& prim = surf.primitives.back(); - prim.type = GX::TRIANGLESTRIP; - prim.indexCount = surfIn.count; - prim.indices.reserve(surfIn.count); - auto itBegin = mapaIn.indices.begin() + surfIn.start; - auto itEnd = itBegin + surfIn.count; - for (auto it = itBegin; it != itEnd; ++it) - prim.indices.push_back(*it); - - surf.borderCount = surfIn.borders.size(); - surf.borders.reserve(surfIn.borders.size()); - for (const auto& borderIn : surfIn.borders) { - surf.borders.emplace_back(); - DNAMAPA::MAPA::Surface::Border& border = surf.borders.back(); - border.indexCount = borderIn.second; - border.indices.reserve(borderIn.second); - auto it2Begin = mapaIn.indices.begin() + borderIn.first; - auto it2End = it2Begin + borderIn.second; - for (auto it = it2Begin; it != it2End; ++it) - border.indices.push_back(*it); - } - - surfHead.normal = surfIn.normal.val; - surfHead.centroid = surfIn.centerOfMass; - surfHead.polyOff = offsetCur; - offsetCur += 4; - prim.binarySize(offsetCur); - surfHead.edgeOff = offsetCur; - offsetCur += 4; - for (const auto& border : surf.borders) - border.binarySize(offsetCur); - } - - athena::io::FileWriter f(out.getAbsolutePath()); - mapa.write(f); - int64_t rem = f.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - f.writeBytes((atInt8*)"\xff", 1); - return true; -} - -template bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out); -template bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out); -template bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out); - -} // namespace DataSpec::DNAMAPA diff --git a/DataSpec/DNACommon/MAPA.hpp b/DataSpec/DNACommon/MAPA.hpp deleted file mode 100644 index 4d3a470f4..000000000 --- a/DataSpec/DNACommon/MAPA.hpp +++ /dev/null @@ -1,177 +0,0 @@ -#pragma once - -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace hecl { -class ProjectPath; -} - -namespace hecl::blender { -class Connection; -struct MapArea; -} // namespace hecl::blender - -namespace DataSpec::DNAMAPA { -struct MAPA : BigDNA { - AT_DECL_EXPLICIT_DNA - Value magic; - Value version; - struct IMAPAHeader : BigDNAV { - Delete _d; - virtual atUint32 visMode() const = 0; - virtual atUint32 mappableObjectCount() const = 0; - virtual atUint32 vertexCount() const = 0; - virtual atUint32 surfaceCount() const = 0; - }; - - struct HeaderMP1 : IMAPAHeader { - AT_DECL_DNAV - Value unknown1 = 0; - Value mapVisMode = 0; - Value boundingBox[2] = {}; - Value moCount = 0; - Value vtxCount = 0; - Value surfCount = 0; - atUint32 visMode() const override { return mapVisMode; } - atUint32 mappableObjectCount() const override { return moCount; } - atUint32 vertexCount() const override { return vtxCount; } - atUint32 surfaceCount() const override { return surfCount; } - }; - - struct HeaderMP2 : IMAPAHeader { - AT_DECL_DNAV - Value unknown1 = 0; - Value mapVisMode = 0; - Value boundingBox[2] = {}; - Value unknown3 = 0; - Value unknown4 = 0; - Value unknown5 = 0; - Value moCount = 0; - Value vtxCount = 0; - Value surfCount = 0; - atUint32 visMode() const override { return mapVisMode; } - atUint32 mappableObjectCount() const override { return moCount; } - atUint32 vertexCount() const override { return vtxCount; } - atUint32 surfaceCount() const override { return surfCount; } - }; - - struct HeaderMP3 : IMAPAHeader { - AT_DECL_DNAV - Value unknown1 = 0; - Value mapVisMode = 0; - Value boundingBox[2] = {}; - Value unknown3 = 0; - Value unknown4 = 0; - Value unknown5 = 0; - Value unknown6 = 0; - Value moCount = 0; - Value vtxCount = 0; - Value surfCount = 0; - Value internalNameLength = 0; - Value unknown7 = 0; - String internalName; - atUint32 visMode() const override { return mapVisMode; } - atUint32 mappableObjectCount() const override { return moCount; } - atUint32 vertexCount() const override { return vtxCount; } - atUint32 surfaceCount() const override { return surfCount; } - }; - - std::unique_ptr header; - - struct IMappableObject : BigDNAV { - Delete _d; - enum class Type : atUint32 { - BlueDoor = 0, - ShieldDoor = 1, - IceDoor = 2, - WaveDoor = 3, - PlasmaDoor = 4, - BigDoor1 = 5, - BigDoor2 = 6, - IceDoorCeiling = 7, - IceDoorFloor = 8, - WaveDoorCeiling = 9, - WaveDoorFloor = 10, - IceDoorFloor2 = 13, - WaveDoorFloor2 = 14, - DownArrowYellow = 27, /* Maintenance Tunnel */ - UpArrowYellow = 28, /* Phazon Processing Center */ - DownArrowGreen = 29, /* Elevator A */ - UpArrowGreen = 30, /* Elite Control Access */ - DownArrowRed = 31, /* Elevator B */ - UpArrowRed = 32, /* Fungal Hall Access */ - TransportLift = 33, - SaveStation = 34, - MissileStation = 37 - }; - }; - - struct MappableObjectMP1_2 : IMappableObject { - AT_DECL_DNAV - Value type; - Value visMode; - Value sclyId; - Value seek1 = -1; - Value transformMtx[3]; - Value seek2[4] = {-1, -1, -1, -1}; - }; - - struct MappableObjectMP3 : IMappableObject { - AT_DECL_DNAV - Value type; - Value visMode; - Value sclyId; - Buffer unknownHash; - Value seek1 = -1; - Value transformMtx[3]; - Value seek2[4] = {-1, -1, -1, -1}; - }; - - std::vector> mappableObjects; - VectorvertexCount())> vertices; - - struct SurfaceHeader : BigDNA { - AT_DECL_DNA - Value normal; - Value centroid; - Value polyOff; - Value edgeOff; - }; - - VectorsurfaceCount())> surfaceHeaders; - - struct Surface : BigDNA { - AT_DECL_DNA - Value primitiveCount; - struct Primitive : BigDNA { - AT_DECL_DNA - Value type; - Value indexCount; - Vector indices; - Align<4> align; - }; - Vector primitives; - Value borderCount; - struct Border : BigDNA { - AT_DECL_DNA - Value indexCount; - Vector indices; - Align<4> align; - }; - Vector borders; - }; - - VectorsurfaceCount())> surfaces; -}; - -template -bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force); - -template -bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out); - -} // namespace DataSpec::DNAMAPA diff --git a/DataSpec/DNACommon/MAPU.cpp b/DataSpec/DNACommon/MAPU.cpp deleted file mode 100644 index 04e4c029a..000000000 --- a/DataSpec/DNACommon/MAPU.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include "DataSpec/DNACommon/MAPU.hpp" - -#include "DataSpec/DNAMP1/DNAMP1.hpp" -#include "DataSpec/DNAMP2/DNAMP2.hpp" -#include "DataSpec/DNAMP3/DNAMP3.hpp" - -#include -#include - -namespace DataSpec::DNAMAPU { - -template -bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force) { - if (!force && outPath.isFile()) - return true; - - if (!conn.createBlend(outPath, hecl::blender::BlendType::MapUniverse)) - return false; - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - - os << "import bpy\n" - "from mathutils import Matrix\n" - "\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "bpy.types.Object.retro_mapworld_color = bpy.props.FloatVectorProperty(name='Retro: MapWorld Color'," - " description='Sets map world color', subtype='COLOR', size=4, min=0.0, max=1.0)\n" - "bpy.types.Object.retro_mapworld_path = bpy.props.StringProperty(name='Retro: MapWorld Path'," - " description='Sets path to World root')\n" - "\n"; - - hecl::ProjectPath hexPath = pakRouter.getWorking(mapu.hexMapa); - os.linkMesh(hexPath.getAbsolutePath(), "MAP"); - os << "hexMesh = bpy.data.objects['MAP'].data\n"; - - for (const MAPU::World& wld : mapu.worlds) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(wld.mlvl); - const MAPU::Transform& wldXf = wld.transform; - zeus::simd_floats wldXfF[3]; - for (int i = 0; i < 3; ++i) - wldXf.xf[i].simd.copy_to(wldXfF[i]); - zeus::simd_floats hexColorF(wld.hexColor.mSimd); - os.format(FMT_STRING("wldObj = bpy.data.objects.new('{}', None)\n" - "mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "wldObj.rotation_mode = 'QUATERNION'\n" - "wldObj.location = mtxd[0]\n" - "wldObj.rotation_quaternion = mtxd[1]\n" - "wldObj.scale = mtxd[2]\n" - "wldObj.retro_mapworld_color = ({}, {}, {}, {})\n" - "wldObj.retro_mapworld_path = '''{}'''\n" - "bpy.context.scene.collection.objects.link(wldObj)\n"), - wld.name, wldXfF[0][0], wldXfF[0][1], wldXfF[0][2], wldXfF[0][3], wldXfF[1][0], wldXfF[1][1], - wldXfF[1][2], wldXfF[1][3], wldXfF[2][0], wldXfF[2][1], wldXfF[2][2], wldXfF[2][3], hexColorF[0], - hexColorF[1], hexColorF[2], hexColorF[3], path.getParentPath().getRelativePath()); - int idx = 0; - for (const MAPU::Transform& hexXf : wld.hexTransforms) { - zeus::simd_floats hexXfF[3]; - for (int i = 0; i < 3; ++i) - hexXf.xf[i].simd.copy_to(hexXfF[i]); - os.format(FMT_STRING("obj = bpy.data.objects.new('{}_{}', hexMesh)\n" - "mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "obj.rotation_mode = 'QUATERNION'\n" - "obj.location = mtxd[0]\n" - "obj.rotation_quaternion = mtxd[1]\n" - "obj.scale = mtxd[2]\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "obj.parent = wldObj\n"), - wld.name, idx++, hexXfF[0][0], hexXfF[0][1], hexXfF[0][2], hexXfF[0][3], hexXfF[1][0], hexXfF[1][1], - hexXfF[1][2], hexXfF[1][3], hexXfF[2][0], hexXfF[2][1], hexXfF[2][2], hexXfF[2][3]); - } - } - - os << "for screen in bpy.data.screens:\n" - " for area in screen.areas:\n" - " for space in area.spaces:\n" - " if space.type == 'VIEW_3D':\n" - " space.clip_end = 8000.0\n"; - - os.centerView(); - os.close(); - conn.saveBlend(); - return true; -} - -template bool ReadMAPUToBlender>(hecl::blender::Connection& conn, const MAPU& mapu, - const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - bool force); - -template bool ReadMAPUToBlender>(hecl::blender::Connection& conn, const MAPU& mapu, - const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - bool force); - -bool MAPU::Cook(const hecl::blender::MapUniverse& mapuIn, const hecl::ProjectPath& out) { - MAPU mapu; - - mapu.magic = 0xABCDEF01; - mapu.version = 1; - mapu.hexMapa = mapuIn.hexagonPath; - - mapu.worldCount = mapuIn.worlds.size(); - mapu.worlds.reserve(mapuIn.worlds.size()); - for (const hecl::blender::MapUniverse::World& wld : mapuIn.worlds) { - mapu.worlds.emplace_back(); - MAPU::World& wldOut = mapu.worlds.back(); - wldOut.name = wld.name; - for (const auto& ent : wld.worldPath.enumerateDir()) { - if (hecl::StringUtils::BeginsWith(ent.m_name, "!world") && - hecl::StringUtils::EndsWith(ent.m_name, ".blend")) { - wldOut.mlvl = hecl::ProjectPath(wld.worldPath, ent.m_name); - break; - } - } - wldOut.transform.xf[0] = wld.xf.val[0]; - wldOut.transform.xf[1] = wld.xf.val[1]; - wldOut.transform.xf[2] = wld.xf.val[2]; - wldOut.hexCount = wld.hexagons.size(); - wldOut.hexTransforms.reserve(wld.hexagons.size()); - for (const hecl::blender::Matrix4f& mtx : wld.hexagons) { - wldOut.hexTransforms.emplace_back(); - MAPU::Transform& xf = wldOut.hexTransforms.back(); - xf.xf[0] = mtx.val[0]; - xf.xf[1] = mtx.val[1]; - xf.xf[2] = mtx.val[2]; - } - wldOut.hexColor = zeus::CColor(wld.color.val); - } - - athena::io::FileWriter f(out.getAbsolutePath()); - mapu.write(f); - int64_t rem = f.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - f.writeBytes((atInt8*)"\xff", 1); - return true; -} - -} // namespace DataSpec::DNAMAPU diff --git a/DataSpec/DNACommon/MAPU.hpp b/DataSpec/DNACommon/MAPU.hpp deleted file mode 100644 index 55fe10610..000000000 --- a/DataSpec/DNACommon/MAPU.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace hecl { -class ProjectPath; -} - -namespace hecl::blender { -class Connection; -struct MapUniverse; -} // namespace hecl::blender - -namespace DataSpec::DNAMAPU { -struct MAPU : BigDNA { - AT_DECL_DNA - Value magic; - Value version; - UniqueID32 hexMapa; - Value worldCount; - struct Transform : BigDNA { - AT_DECL_DNA - Value xf[3]; - }; - struct World : BigDNA { - AT_DECL_DNA - String<-1> name; - UniqueID32 mlvl; - Transform transform; - Value hexCount; - Vector hexTransforms; - DNAColor hexColor; - }; - Vector worlds; - - static bool Cook(const hecl::blender::MapUniverse& mapu, const hecl::ProjectPath& out); -}; - -template -bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force); - -} // namespace DataSpec::DNAMAPU diff --git a/DataSpec/DNACommon/MLVL.cpp b/DataSpec/DNACommon/MLVL.cpp deleted file mode 100644 index 24c081147..000000000 --- a/DataSpec/DNACommon/MLVL.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "DataSpec/DNACommon/MLVL.hpp" - -#include "DataSpec/DNAMP1/MLVL.hpp" -#include "DataSpec/DNAMP2/MLVL.hpp" -#include "DataSpec/DNAMP3/MLVL.hpp" - -#include -#include - -namespace DataSpec::DNAMLVL { - -template -bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force, - std::function fileChanged) { - hecl::ProjectPath blendPath = outPath.getWithExtension(".blend", true); - if (!force && blendPath.isFile()) - return true; - - /* Create World Blend */ - if (!conn.createBlend(blendPath, hecl::blender::BlendType::World)) - return false; - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os << "import bpy\n" - "import bmesh\n" - "from mathutils import Matrix\n" - "\n" - "bpy.context.scene.name = 'World'\n" - "\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n"; - - /* Insert area empties */ - int areaIdx = 0; - for (const auto& area : mlvl.areas) { - const typename PAKRouter::EntryType* mreaEntry = pakRouter.lookupEntry(area.areaMREAId); - - os.AABBToBMesh(area.aabb[0], area.aabb[1]); - zeus::simd_floats xfMtxF[3]; - for (int i = 0; i < 3; ++i) - area.transformMtx[i].simd.copy_to(xfMtxF[i]); - os.format(FMT_STRING("box_mesh = bpy.data.meshes.new('''{}''')\n" - "bm.to_mesh(box_mesh)\n" - "bm.free()\n" - "box = bpy.data.objects.new(box_mesh.name, box_mesh)\n" - "bpy.context.scene.collection.objects.link(box)\n" - "mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "box.rotation_mode = 'QUATERNION'\n" - "box.location = mtxd[0]\n" - "box.rotation_quaternion = mtxd[1]\n" - "box.scale = mtxd[2]\n"), - *mreaEntry->unique.m_areaName, xfMtxF[0][0], xfMtxF[0][1], xfMtxF[0][2], xfMtxF[0][3], xfMtxF[1][0], xfMtxF[1][1], - xfMtxF[1][2], xfMtxF[1][3], xfMtxF[2][0], xfMtxF[2][1], xfMtxF[2][2], xfMtxF[2][3]); - - /* Insert dock planes */ - int dockIdx = 0; - for (const auto& dock : area.docks) { - os << "bm = bmesh.new()\n"; - zeus::CVector3f pvAvg; - for (const atVec3f& pv : dock.planeVerts) - pvAvg += pv; - pvAvg /= zeus::CVector3f(dock.planeVerts.size()); - int idx = 0; - for (const atVec3f& pv : dock.planeVerts) { - const zeus::CVector3f pvRel = zeus::CVector3f(pv) - pvAvg; - os.format(FMT_STRING("bm.verts.new(({},{},{}))\n" - "bm.verts.ensure_lookup_table()\n"), - pvRel[0], pvRel[1], pvRel[2]); - if (idx) - os << "bm.edges.new((bm.verts[-2], bm.verts[-1]))\n"; - ++idx; - } - os << "bm.edges.new((bm.verts[-1], bm.verts[0]))\n"; - os.format(FMT_STRING("dockMesh = bpy.data.meshes.new('DOCK_{:02d}_{:02d}')\n"), areaIdx, dockIdx); - os << "dockObj = bpy.data.objects.new(dockMesh.name, dockMesh)\n" - "bpy.context.scene.collection.objects.link(dockObj)\n" - "bm.to_mesh(dockMesh)\n" - "bm.free()\n" - "dockObj.parent = box\n"; - os.format(FMT_STRING("dockObj.location = ({},{},{})\n"), float(pvAvg[0]), float(pvAvg[1]), float(pvAvg[2])); - ++dockIdx; - } - ++areaIdx; - } - - os.centerView(); - os.close(); - conn.saveBlend(); - return true; -} - -template bool ReadMLVLToBlender, DNAMP1::MLVL>( - hecl::blender::Connection& conn, const DNAMP1::MLVL& mlvl, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAKRouter::EntryType& entry, bool force, - std::function fileChanged); - -template bool ReadMLVLToBlender, DNAMP2::MLVL>( - hecl::blender::Connection& conn, const DNAMP2::MLVL& mlvl, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAKRouter::EntryType& entry, bool force, - std::function fileChanged); - -template bool ReadMLVLToBlender, DNAMP3::MLVL>( - hecl::blender::Connection& conn, const DNAMP3::MLVL& mlvl, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAKRouter::EntryType& entry, bool force, - std::function fileChanged); - -} // namespace DataSpec::DNAMLVL diff --git a/DataSpec/DNACommon/MLVL.hpp b/DataSpec/DNACommon/MLVL.hpp deleted file mode 100644 index 452d421d1..000000000 --- a/DataSpec/DNACommon/MLVL.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace hecl { -class ProjectPath; -} - -namespace hecl::blender { -class Connection; -} - -namespace DataSpec::DNAMLVL { - -template -bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force, - std::function fileChanged); - -} diff --git a/DataSpec/DNACommon/MayaSpline.hpp b/DataSpec/DNACommon/MayaSpline.hpp deleted file mode 100644 index 11de1f0bf..000000000 --- a/DataSpec/DNACommon/MayaSpline.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace DataSpec { -struct MayaSpline : public BigDNA { - AT_DECL_DNA_YAML - Value preInf; - Value postInf; - Value knotCount; - struct Knot : BigDNA { - AT_DECL_DNA_YAML - Value time; - Value amplitude; - Value unk1; - Value unk2; - Vector unk1Floats; - Vector unk2Floats; - }; - - Vector knots; - Value clampMode; - Value minAmp; - Value maxAmp; -}; -} // namespace DataSpec \ No newline at end of file diff --git a/DataSpec/DNACommon/MetaforceVersionInfo.hpp b/DataSpec/DNACommon/MetaforceVersionInfo.hpp deleted file mode 100644 index 20505ef13..000000000 --- a/DataSpec/DNACommon/MetaforceVersionInfo.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace DataSpec { -enum class ERegion { Invalid = -1, NTSC_U = 'E', PAL = 'P', NTSC_J = 'J' }; -enum class EGame { - Invalid = 0, - MetroidPrime1, - MetroidPrime2, - MetroidPrime3, -}; - -struct MetaforceVersionInfo : BigDNA { - AT_DECL_DNA_YAML - - String<-1> version; - Value region; - Value game; - Value isTrilogy; -}; -} // namespace DataSpec diff --git a/DataSpec/DNACommon/OBBTreeBuilder.cpp b/DataSpec/DNACommon/OBBTreeBuilder.cpp deleted file mode 100644 index e778d4b5f..000000000 --- a/DataSpec/DNACommon/OBBTreeBuilder.cpp +++ /dev/null @@ -1,258 +0,0 @@ -#include "DataSpec/DNACommon/OBBTreeBuilder.hpp" - -#include -#include -#include - -#include "DataSpec/DNAMP1/DCLN.hpp" - -#include -#include -#include -#include - -namespace DataSpec { - -using ColMesh = hecl::blender::ColMesh; - -struct FittedOBB { - zeus::CTransform xf; - zeus::CVector3f he; -}; - -static std::vector MakeRootTriangleIndex(const ColMesh& mesh) { - std::vector ret; - ret.reserve(mesh.trianges.size()); - for (size_t i = 0; i < mesh.trianges.size(); ++i) - ret.push_back(i); - return ret; -} - -static std::unordered_set GetTriangleVerts(const ColMesh& mesh, int triIdx) { - const ColMesh::Triangle& T = mesh.trianges[triIdx]; - std::unordered_set verts; - verts.insert(mesh.edges[T.edges[0]].verts[0]); - verts.insert(mesh.edges[T.edges[0]].verts[1]); - verts.insert(mesh.edges[T.edges[1]].verts[0]); - verts.insert(mesh.edges[T.edges[1]].verts[1]); - verts.insert(mesh.edges[T.edges[2]].verts[0]); - verts.insert(mesh.edges[T.edges[2]].verts[1]); - return verts; -} - -// method to set the OBB parameters which produce a box oriented according to -// the covariance matrix C, which just containts the points pnts -static FittedOBB BuildFromCovarianceMatrix(gmm::dense_matrix& C, const ColMesh& mesh, - const std::vector& index) { - FittedOBB ret; - - // extract the eigenvalues and eigenvectors from C - gmm::dense_matrix eigvec(3, 3); - std::vector eigval(3); - using namespace gmm; - using MAT1 = gmm::dense_matrix; - gmm::symmetric_qr_algorithm(C, eigval, eigvec, default_tol_for_qr); - - // find the right, up and forward vectors from the eigenvectors - zeus::CVector3f r(eigvec(0, 0), eigvec(1, 0), eigvec(2, 0)); - zeus::CVector3f f(eigvec(0, 1), eigvec(1, 1), eigvec(2, 1)); - zeus::CVector3f u(eigvec(0, 2), eigvec(1, 2), eigvec(2, 2)); - r.normalize(); - f.normalize(); - u.normalize(); - - // set the rotation matrix using the eigvenvectors - ret.xf.basis[0] = r; - ret.xf.basis[1] = f; - ret.xf.basis[2] = u; - ret.xf.orthonormalize(); - - // now build the bounding box extents in the rotated frame - zeus::CVector3f minim(1e10f, 1e10f, 1e10f), maxim(-1e10f, -1e10f, -1e10f); - for (int triIdx : index) { - std::unordered_set verts = GetTriangleVerts(mesh, triIdx); - for (uint32_t v : verts) { - const zeus::CVector3f& p = mesh.verts[v].val; - zeus::CVector3f p_prime(ret.xf.basis[0].dot(p), ret.xf.basis[1].dot(p), ret.xf.basis[2].dot(p)); - minim = zeus::min(minim, p_prime); - maxim = zeus::max(maxim, p_prime); - } - } - - // set the center of the OBB to be the average of the - // minimum and maximum, and the extents be half of the - // difference between the minimum and maximum - zeus::CVector3f center = (maxim + minim) * 0.5f; - ret.xf.origin = ret.xf.basis * center; - ret.he = (maxim - minim) * 0.5f; - - return ret; -} - -// builds an OBB from triangles specified as an array of -// points with integer indices into the point array. Forms -// the covariance matrix for the triangles, then uses the -// method build_from_covariance_matrix() method to fit -// the box. ALL points will be fit in the box, regardless -// of whether they are indexed by a triangle or not. -static FittedOBB FitOBB(const ColMesh& mesh, const std::vector& index) { - float Ai, Am = 0.0; - zeus::CVector3f mu, mui; - gmm::dense_matrix C(3, 3); - float cxx = 0.0, cxy = 0.0, cxz = 0.0, cyy = 0.0, cyz = 0.0, czz = 0.0; - - // loop over the triangles this time to find the - // mean location - for (int i : index) { - std::unordered_set verts = GetTriangleVerts(mesh, i); - auto it = verts.begin(); - zeus::CVector3f p = mesh.verts[*it++].val; - zeus::CVector3f q = mesh.verts[*it++].val; - zeus::CVector3f r = mesh.verts[*it++].val; - mui = (p + q + r) / 3.f; - Ai = (q - p).cross(r - p).magnitude() / 2.f; - mu += mui * Ai; - Am += Ai; - - // these bits set the c terms to Am*E[xx], Am*E[xy], Am*E[xz].... - cxx += (9.0 * mui.x() * mui.x() + p.x() * p.x() + q.x() * q.x() + r.x() * r.x()) * (Ai / 12.0); - cxy += (9.0 * mui.x() * mui.y() + p.x() * p.y() + q.x() * q.y() + r.x() * r.y()) * (Ai / 12.0); - cxz += (9.0 * mui.x() * mui.z() + p.x() * p.z() + q.x() * q.z() + r.x() * r.z()) * (Ai / 12.0); - cyy += (9.0 * mui.y() * mui.y() + p.y() * p.y() + q.y() * q.y() + r.y() * r.y()) * (Ai / 12.0); - cyz += (9.0 * mui.y() * mui.z() + p.y() * p.z() + q.y() * q.z() + r.y() * r.z()) * (Ai / 12.0); - } - - if (zeus::close_enough(Am, 0.f)) - return {}; - - // divide out the Am fraction from the average position and - // covariance terms - mu = mu / Am; - cxx /= Am; - cxy /= Am; - cxz /= Am; - cyy /= Am; - cyz /= Am; - czz /= Am; - - // now subtract off the E[x]*E[x], E[x]*E[y], ... terms - cxx -= mu.x() * mu.x(); - cxy -= mu.x() * mu.y(); - cxz -= mu.x() * mu.z(); - cyy -= mu.y() * mu.y(); - cyz -= mu.y() * mu.z(); - czz -= mu.z() * mu.z(); - - // now build the covariance matrix - C(0, 0) = cxx; - C(0, 1) = cxy; - C(0, 2) = cxz; - C(1, 0) = cxy; - C(1, 1) = cyy; - C(1, 2) = cyz; - C(2, 0) = cxz; - C(2, 1) = cyz; - C(2, 2) = czz; - - // set the obb parameters from the covariance matrix - return BuildFromCovarianceMatrix(C, mesh, index); -} - -template -static void MakeLeaf(const ColMesh& mesh, const std::vector& index, Node& n) { - n.left.reset(); - n.right.reset(); - n.isLeaf = true; - n.leafData = std::make_unique(); - n.leafData->triangleIndexCount = atUint32(index.size()); - n.leafData->triangleIndices.reserve(n.leafData->triangleIndexCount); - for (int i : index) - n.leafData->triangleIndices.push_back(i); -} - -template -static std::unique_ptr RecursiveMakeNode(const ColMesh& mesh, const std::vector& index) { - // calculate root OBB - FittedOBB obb = FitOBB(mesh, index); - - // make results row-major and also invert the rotation basis - obb.xf.basis.transpose(); - - std::unique_ptr n = std::make_unique(); - for (int i = 0; i < 3; ++i) { - n->xf[i] = zeus::CVector4f{obb.xf.basis[i]}; - n->xf[i].simd[3] = float(obb.xf.origin[i]); - } - n->halfExtent = obb.he; - - // terminate branch when volume < 1.0 - if (obb.he[0] * obb.he[1] * obb.he[2] < 1.f) { - MakeLeaf(mesh, index, *n); - return n; - } - - n->isLeaf = false; - - std::vector indexNeg[3]; - std::vector indexPos[3]; - for (int c = 0; c < 3; ++c) { - // subdivide negative side - indexNeg[c].reserve(index.size()); - for (int i : index) { - std::unordered_set verts = GetTriangleVerts(mesh, i); - for (uint32_t vtx : verts) { - zeus::CVector3f v = mesh.verts[vtx].val; - v = obb.xf.basis * (v - obb.xf.origin); - if (v[c] < 0.f) { - indexNeg[c].push_back(i); - break; - } - } - } - - // subdivide positive side - indexPos[c].reserve(index.size()); - for (int i : index) { - std::unordered_set verts = GetTriangleVerts(mesh, i); - for (uint32_t vtx : verts) { - zeus::CVector3f v = mesh.verts[vtx].val; - v = obb.xf.basis * (v - obb.xf.origin); - if (v[c] >= 0.f) { - indexPos[c].push_back(i); - break; - } - } - } - } - - size_t idxMin = index.size(); - int minComp = -1; - for (int c = 0; c < 3; ++c) { - size_t test = std::max(indexNeg[c].size(), indexPos[c].size()); - if (test < idxMin && test < index.size() * 3 / 4) { - minComp = c; - idxMin = test; - } - } - - if (minComp == -1) { - MakeLeaf(mesh, index, *n); - return n; - } - - n->left = RecursiveMakeNode(mesh, indexNeg[minComp]); - n->right = RecursiveMakeNode(mesh, indexPos[minComp]); - - return n; -} - -template -std::unique_ptr OBBTreeBuilder::buildCol(const ColMesh& mesh) { - std::vector root = MakeRootTriangleIndex(mesh); - return RecursiveMakeNode(mesh, root); -} - -template std::unique_ptr -OBBTreeBuilder::buildCol(const ColMesh& mesh); - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/OBBTreeBuilder.hpp b/DataSpec/DNACommon/OBBTreeBuilder.hpp deleted file mode 100644 index 45085966f..000000000 --- a/DataSpec/DNACommon/OBBTreeBuilder.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -#include - -namespace DataSpec { - -struct OBBTreeBuilder { - using ColMesh = hecl::blender::ColMesh; - template - static std::unique_ptr buildCol(const ColMesh& mesh); -}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/PAK.cpp b/DataSpec/DNACommon/PAK.cpp deleted file mode 100644 index c8e626fed..000000000 --- a/DataSpec/DNACommon/PAK.cpp +++ /dev/null @@ -1,679 +0,0 @@ -#include "DataSpec/DNACommon/PAK.hpp" - -#include "DataSpec/DNAMP1/DNAMP1.hpp" -#include "DataSpec/DNAMP2/DNAMP2.hpp" -#include "DataSpec/DNAMP3/DNAMP3.hpp" - -namespace DataSpec { - -template -void UniqueResult::checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRIDGE::PAKType::Entry& entry) { - UniqueResult::Type resultType = UniqueResult::Type::NotFound; - bool foundOneLayer = false; - const std::string* levelName = nullptr; - typename PAKBRIDGE::PAKType::IDType useLevelId; - typename PAKBRIDGE::PAKType::IDType useAreaId; - unsigned layerIdx = 0; - for (const auto& [levelId, level] : pakBridge.m_levelDeps) { - if (entry.id == levelId || level.resources.find(entry.id) != level.resources.end()) { - levelName = &level.name; - resultType = UniqueResult::Type::Level; - break; - } - - for (const auto& [areaId, area] : level.areas) { - unsigned l = 0; - for (const auto& layer : area.layers) { - if (layer.resources.find(entry.id) != layer.resources.end()) { - if (foundOneLayer) { - if (useAreaId == areaId) { - resultType = UniqueResult::Type::Area; - } else if (useLevelId == levelId) { - resultType = UniqueResult::Type::Level; - break; - } else { - m_type = UniqueResult::Type::Pak; - return; - } - continue; - } else - resultType = UniqueResult::Type::Layer; - levelName = &level.name; - useLevelId = levelId; - useAreaId = areaId; - layerIdx = l; - foundOneLayer = true; - } - ++l; - } - if (area.resources.find(entry.id) != area.resources.end()) { - if (foundOneLayer) { - if (useAreaId == areaId) { - resultType = UniqueResult::Type::Area; - } else if (useLevelId == levelId) { - resultType = UniqueResult::Type::Level; - break; - } else { - m_type = UniqueResult::Type::Pak; - return; - } - continue; - } else - resultType = UniqueResult::Type::Area; - levelName = &level.name; - useLevelId = levelId; - useAreaId = areaId; - foundOneLayer = true; - } - } - } - m_type = resultType; - m_levelName = levelName; - if (resultType == UniqueResult::Type::Layer || resultType == UniqueResult::Type::Area) { - const typename PAKBRIDGE::Level::Area& area = pakBridge.m_levelDeps.at(useLevelId).areas.at(useAreaId); - m_areaName = &area.name; - if (resultType == UniqueResult::Type::Layer) { - const typename PAKBRIDGE::Level::Area::Layer& layer = area.layers[layerIdx]; - m_layerName = &layer.name; - } - } -} - -template void UniqueResult::checkEntry(const DNAMP1::PAKBridge& pakBridge, - const DNAMP1::PAKBridge::PAKType::Entry& entry); -template void UniqueResult::checkEntry(const DNAMP2::PAKBridge& pakBridge, - const DNAMP2::PAKBridge::PAKType::Entry& entry); -template void UniqueResult::checkEntry(const DNAMP3::PAKBridge& pakBridge, - const DNAMP3::PAKBridge::PAKType::Entry& entry); - -hecl::ProjectPath UniqueResult::uniquePath(const hecl::ProjectPath& pakPath) const { - if (m_type == Type::Pak) - return pakPath; - - hecl::ProjectPath levelDir; - if (m_levelName) - levelDir.assign(pakPath, *m_levelName); - else - levelDir = pakPath; - - if (m_type == Type::Area) { - hecl::ProjectPath areaDir(levelDir, *m_areaName); - return areaDir; - } else if (m_type == Type::Layer) { - hecl::ProjectPath areaDir(levelDir, *m_areaName); - hecl::ProjectPath layerDir(areaDir, *m_layerName); - return layerDir; - } - - return levelDir; -} - -template -void PAKRouter::build(std::vector& bridges, std::function progress) { - m_bridges = &bridges; - m_bridgePaths.clear(); - - m_uniqueEntries.clear(); - m_sharedEntries.clear(); - m_charAssoc.m_cmdlRigs.clear(); - size_t count = 0; - float bridgesSz = bridges.size(); - - /* Route entries unique/shared per-pak */ - size_t bridgeIdx = 0; - for (BRIDGETYPE& bridge : bridges) { - const auto& name = bridge.getName(); - - std::string_view::const_iterator extit = name.end() - 4; - std::string baseName(name.begin(), extit); - - m_bridgePaths.emplace_back( - std::make_pair(hecl::ProjectPath(m_gameWorking, baseName), hecl::ProjectPath(m_gameCooked, baseName))); - - /* Index this PAK */ - bridge.build(); - - /* Add to global entry lookup */ - const typename BRIDGETYPE::PAKType& pak = bridge.getPAK(); - for (const auto& entry : pak.m_entries) { - if (!pak.m_noShare) { - auto sSearch = m_sharedEntries.find(entry.first); - if (sSearch != m_sharedEntries.end()) - continue; - auto uSearch = m_uniqueEntries.find(entry.first); - if (uSearch != m_uniqueEntries.end()) { - m_uniqueEntries.erase(uSearch); - m_sharedEntries[entry.first] = std::make_pair(bridgeIdx, &entry.second); - } else - m_uniqueEntries[entry.first] = std::make_pair(bridgeIdx, &entry.second); - } else - m_uniqueEntries[entry.first] = std::make_pair(bridgeIdx, &entry.second); - } - - /* Add RigPairs to global map */ - bridge.addCMDLRigPairs(*this, m_charAssoc); - - progress(++count / bridgesSz); - ++bridgeIdx; - } - - /* Add named resources to catalog YAML files */ - for (BRIDGETYPE& bridge : bridges) { - athena::io::YAMLDocWriter catalogWriter; - - enterPAKBridge(bridge); - - /* Add MAPA transforms to global map */ - bridge.addMAPATransforms(*this, m_mapaTransforms, m_overrideEntries); - - const typename BRIDGETYPE::PAKType& pak = bridge.getPAK(); - for (const auto& namedEntry : pak.m_nameEntries) { - if (namedEntry.name == "holo_cinf") - continue; /* Problematic corner case */ - if (auto rec = catalogWriter.enterSubRecord(namedEntry.name)) { - hecl::ProjectPath working = getWorking(namedEntry.id); - if (working.getAuxInfo().size()) { - if (auto v = catalogWriter.enterSubVector()) { - catalogWriter.writeString(working.getRelativePath()); - catalogWriter.writeString(working.getAuxInfo()); - } - } else - catalogWriter.writeString(working.getRelativePath()); - } - } - - /* Write catalog */ - intptr_t curBridgeIdx = reinterpret_cast(m_curBridgeIdx.get()); - const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first; - pakPath.makeDirChain(true); - athena::io::FileWriter writer(hecl::ProjectPath(pakPath, "!catalog.yaml").getAbsolutePath()); - catalogWriter.finish(&writer); - } -} - -template -void PAKRouter::enterPAKBridge(const BRIDGETYPE& pakBridge) { - g_PakRouter.reset(this); - auto pit = m_bridgePaths.begin(); - size_t bridgeIdx = 0; - for (const BRIDGETYPE& bridge : *m_bridges) { - if (&bridge == &pakBridge) { - m_pak.reset(&pakBridge.getPAK()); - m_node.reset(&pakBridge.getNode()); - m_curBridgeIdx.reset(reinterpret_cast(bridgeIdx)); - return; - } - ++pit; - ++bridgeIdx; - } - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("PAKBridge provided to PAKRouter::enterPAKBridge() was not part of build()")); -} - -template -hecl::ProjectPath PAKRouter::getCharacterWorking(const EntryType* entry) const { - auto characterSearch = m_charAssoc.m_cskrToCharacter.find(entry->id); - if (characterSearch != m_charAssoc.m_cskrToCharacter.cend()) { - hecl::ProjectPath characterPath = getWorking(characterSearch->second.first); - if (entry->type == FOURCC('EVNT')) { - std::string extension(characterSearch->second.second); - return characterPath.getWithExtension((std::string(".") + extension.c_str()).c_str(), true); - } - return characterPath.ensureAuxInfo(characterSearch->second.second); - } - return {}; -} - -template -hecl::ProjectPath PAKRouter::getWorking(const EntryType* entry, - const ResExtractor& extractor) const { - if (!entry) - return hecl::ProjectPath(); - - auto overrideSearch = m_overrideEntries.find(entry->id); - if (overrideSearch != m_overrideEntries.end()) - return overrideSearch->second; - - const PAKType* pak = m_pak.get(); - intptr_t curBridgeIdx = reinterpret_cast(m_curBridgeIdx.get()); - if (pak && pak->m_noShare) { - const EntryType* singleSearch = pak->lookupEntry(entry->id); - if (singleSearch) { - const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first; - std::string entName = getBestEntryName(*entry); - std::string auxInfo; - if (extractor.fileExts[0] && !extractor.fileExts[1]) - entName += extractor.fileExts[0]; - else if (extractor.fileExts[0]) - entName += ".*"; - else if (hecl::ProjectPath chWork = getCharacterWorking(entry)) - return chWork; - return hecl::ProjectPath(pakPath, entName).ensureAuxInfo(auxInfo); - } - } - - auto uniqueSearch = m_uniqueEntries.find(entry->id); - if (uniqueSearch != m_uniqueEntries.end()) { - const BRIDGETYPE& bridge = m_bridges->at(uniqueSearch->second.first); - const hecl::ProjectPath& pakPath = m_bridgePaths[uniqueSearch->second.first].first; - std::string entName = getBestEntryName(*entry); - std::string auxInfo; - if (extractor.fileExts[0] && !extractor.fileExts[1]) - entName += extractor.fileExts[0]; - else if (extractor.fileExts[0]) - entName += ".*"; - else if (hecl::ProjectPath chWork = getCharacterWorking(entry)) - return chWork; - if (bridge.getPAK().m_noShare) { - return hecl::ProjectPath(pakPath, entName).ensureAuxInfo(auxInfo); - } else { - hecl::ProjectPath uniquePath = entry->unique.uniquePath(pakPath); - return hecl::ProjectPath(uniquePath, entName).ensureAuxInfo(auxInfo); - } - } - - auto sharedSearch = m_sharedEntries.find(entry->id); - if (sharedSearch != m_sharedEntries.end()) { - std::string entBase = getBestEntryName(*entry); - std::string auxInfo; - std::string entName = entBase; - if (extractor.fileExts[0] && !extractor.fileExts[1]) - entName += extractor.fileExts[0]; - else if (extractor.fileExts[0]) - entName += ".*"; - else if (hecl::ProjectPath chWork = getCharacterWorking(entry)) - return chWork; - hecl::ProjectPath sharedPath(m_sharedWorking, entName); - return sharedPath.ensureAuxInfo(auxInfo); - } - - LogDNACommon.report(logvisor::Fatal, FMT_STRING("Unable to find entry {}"), entry->id); - return hecl::ProjectPath(); -} - -template -hecl::ProjectPath PAKRouter::getWorking(const EntryType* entry) const { - if (!entry) - return hecl::ProjectPath(); - return getWorking(entry, BRIDGETYPE::LookupExtractor(*m_node.get(), *m_pak.get(), *entry)); -} - -template -hecl::ProjectPath PAKRouter::getWorking(const IDType& id, bool silenceWarnings) const { - return getWorking(lookupEntry(id, nullptr, silenceWarnings, false)); -} - -template -hecl::ProjectPath PAKRouter::getCooked(const EntryType* entry) const { - if (!entry) - return hecl::ProjectPath(); - - auto overrideSearch = m_overrideEntries.find(entry->id); - if (overrideSearch != m_overrideEntries.end()) { - return overrideSearch->second.getCookedPath( - *m_dataSpec.overrideDataSpec(overrideSearch->second, m_dataSpec.getDataSpecEntry())); - } - - const PAKType* pak = m_pak.get(); - intptr_t curBridgeIdx = reinterpret_cast(m_curBridgeIdx.get()); - if (pak && pak->m_noShare) { - const EntryType* singleSearch = pak->lookupEntry(entry->id); - if (singleSearch) { - const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].second; - return hecl::ProjectPath(pakPath, getBestEntryName(*entry)); - } - } - auto uniqueSearch = m_uniqueEntries.find(entry->id); - if (uniqueSearch != m_uniqueEntries.end()) { - const BRIDGETYPE& bridge = m_bridges->at(uniqueSearch->second.first); - const hecl::ProjectPath& pakPath = m_bridgePaths[uniqueSearch->second.first].second; - if (bridge.getPAK().m_noShare) { - return hecl::ProjectPath(pakPath, getBestEntryName(*entry)); - } else { - hecl::ProjectPath uniquePath = entry->unique.uniquePath(pakPath); - return hecl::ProjectPath(uniquePath, getBestEntryName(*entry)); - } - } - auto sharedSearch = m_sharedEntries.find(entry->id); - if (sharedSearch != m_sharedEntries.end()) { - return hecl::ProjectPath(m_sharedCooked, getBestEntryName(*entry)); - } - LogDNACommon.report(logvisor::Fatal, FMT_STRING("Unable to find entry {}"), entry->id); - return hecl::ProjectPath(); -} - -template -hecl::ProjectPath PAKRouter::getCooked(const IDType& id, bool silenceWarnings) const { - return getCooked(lookupEntry(id, nullptr, silenceWarnings, false)); -} - -template -std::string PAKRouter::getResourceRelativePath(const EntryType& a, const IDType& b) const { - const nod::Node* node = m_node.get(); - const PAKType* pak = m_pak.get(); - if (!pak) - LogDNACommon.report( - logvisor::Fatal, - FMT_STRING("PAKRouter::enterPAKBridge() must be called before PAKRouter::getResourceRelativePath()")); - const typename BRIDGETYPE::PAKType::Entry* be = lookupEntry(b); - if (!be) - return std::string(); - hecl::ProjectPath aPath = getWorking(&a, BRIDGETYPE::LookupExtractor(*node, *pak, a)); - std::string ret; - for (size_t i = 0; i < aPath.levelCount(); ++i) - ret += "../"; - hecl::ProjectPath bPath = getWorking(be, BRIDGETYPE::LookupExtractor(*node, *pak, *be)); - ret += bPath.getRelativePath(); - return ret; -} - -template -std::string PAKRouter::getBestEntryName(const EntryType& entry, bool stdOverride) const { - std::string name; - for (const BRIDGETYPE& bridge : *m_bridges) { - const typename BRIDGETYPE::PAKType& pak = bridge.getPAK(); - const typename BRIDGETYPE::PAKType::Entry* e = pak.lookupEntry(entry.id); - if (!e) - continue; - - if (stdOverride && !pak.m_noShare) { - if (entry.type == FOURCC('MLVL')) - return fmt::format(FMT_STRING("!world_{}"), entry.id); - else if (entry.type == FOURCC('MREA')) - return fmt::format(FMT_STRING("!area_{}"), entry.id); - else if (entry.type == FOURCC('MAPA')) - return fmt::format(FMT_STRING("!map_{}"), entry.id); - else if (entry.type == FOURCC('PATH')) - return fmt::format(FMT_STRING("!path_{}"), entry.id); - else if (entry.type == FOURCC('MAPW')) - return fmt::format(FMT_STRING("!mapw_{}"), entry.id); - else if (entry.type == FOURCC('SAVW')) - return fmt::format(FMT_STRING("!savw_{}"), entry.id); - } - - std::string catalogueName; - name = pak.bestEntryName(bridge.getNode(), entry, catalogueName); - if (!catalogueName.empty()) - return name; - } - return name; -} - -template -std::string PAKRouter::getBestEntryName(const IDType& entry, bool stdOverride) const { - std::string name; - for (const BRIDGETYPE& bridge : *m_bridges) { - const typename BRIDGETYPE::PAKType& pak = bridge.getPAK(); - const typename BRIDGETYPE::PAKType::Entry* e = pak.lookupEntry(entry); - if (!e) - continue; - - if (stdOverride && !pak.m_noShare) { - if (e->type == FOURCC('MLVL')) - return fmt::format(FMT_STRING("!world_{}"), e->id); - else if (e->type == FOURCC('MREA')) - return fmt::format(FMT_STRING("!area_{}"), e->id); - else if (e->type == FOURCC('MAPA')) - return fmt::format(FMT_STRING("!map_{}"), e->id); - else if (e->type == FOURCC('PATH')) - return fmt::format(FMT_STRING("!path_{}"), e->id); - else if (e->type == FOURCC('MAPW')) - return fmt::format(FMT_STRING("!mapw_{}"), e->id); - else if (e->type == FOURCC('SAVW')) - return fmt::format(FMT_STRING("!savw_{}"), e->id); - } - - std::string catalogueName; - name = pak.bestEntryName(bridge.getNode(), *e, catalogueName); - if (!catalogueName.empty()) - return name; - } - return name; -} - -template -bool PAKRouter::extractResources(const BRIDGETYPE& pakBridge, bool force, hecl::blender::Token& btok, - std::function progress) { - enterPAKBridge(pakBridge); - size_t count = 0; - size_t sz = m_pak->m_entries.size(); - float fsz = sz; - for (unsigned w = 0; count < sz; ++w) { - for (const auto& item : m_pak->m_firstEntries) { - const auto* entryPtr = m_pak->lookupEntry(item); - ResExtractor extractor = BRIDGETYPE::LookupExtractor(*m_node.get(), *m_pak.get(), *entryPtr); - if (extractor.weight != w) - continue; - - std::string bestName = getBestEntryName(*entryPtr, false); - float thisFac = ++count / fsz; - progress(bestName.c_str(), thisFac); - - const nod::Node* node = m_node.get(); - - hecl::ProjectPath working = getWorking(entryPtr, extractor); - working.makeDirChain(false); - hecl::ResourceLock resLk(working); - if (!resLk) - continue; - - /* Extract to unmodified directory */ - hecl::ProjectPath cooked = working.getCookedPath(m_dataSpec.getUnmodifiedSpec()); - if (force || cooked.isNone()) { - cooked.makeDirChain(false); - PAKEntryReadStream s = entryPtr->beginReadStream(*node); - const auto fout = hecl::FopenUnique(cooked.getAbsolutePath().data(), "wb"); - std::fwrite(s.data(), 1, s.length(), fout.get()); - } - - if (extractor.func_a) /* Doesn't need PAKRouter access */ - { - if (force || !extractor.IsFullyExtracted(working)) { - PAKEntryReadStream s = entryPtr->beginReadStream(*node); - extractor.func_a(s, working); - } - } else if (extractor.func_b) /* Needs PAKRouter access */ - { - if (force || !extractor.IsFullyExtracted(working)) { - PAKEntryReadStream s = entryPtr->beginReadStream(*node); - extractor.func_b(m_dataSpec, s, working, *this, *entryPtr, force, btok, - [&progress, thisFac](const char* update) { progress(update, thisFac); }); - } - } - } - } - - return true; -} - -template -const typename BRIDGETYPE::PAKType::Entry* -PAKRouter::lookupEntry(const IDType& entry, const nod::Node** nodeOut, bool silenceWarnings, - bool currentPAK) const { - if (!entry.isValid()) - return nullptr; - - if (!m_bridges) - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("PAKRouter::build() must be called before PAKRouter::lookupEntry()")); - - const PAKType* pak = m_pak.get(); - const nod::Node* node = m_node.get(); - if (pak) { - const EntryType* ent = pak->lookupEntry(entry); - if (ent) { - if (nodeOut) - *nodeOut = node; - return ent; - } - } - - if (currentPAK) { -#ifndef NDEBUG - if (!silenceWarnings) - LogDNACommon.report(logvisor::Warning, FMT_STRING("unable to find PAK entry {} in current PAK"), entry); -#endif - return nullptr; - } - - for (const BRIDGETYPE& bridge : *m_bridges) { - const PAKType& pak = bridge.getPAK(); - const EntryType* ent = pak.lookupEntry(entry); - if (ent) { - if (nodeOut) - *nodeOut = &bridge.getNode(); - return ent; - } - } - -#ifndef NDEBUG - if (!silenceWarnings) - LogDNACommon.report(logvisor::Warning, FMT_STRING("unable to find PAK entry {}"), entry); -#endif - if (nodeOut) - *nodeOut = nullptr; - return nullptr; -} - -template -const typename CharacterAssociations::IDType>::RigPair* -PAKRouter::lookupCMDLRigPair(const IDType& id) const { - auto search = m_charAssoc.m_cmdlRigs.find(id); - if (search == m_charAssoc.m_cmdlRigs.end()) - return nullptr; - return &search->second; -} - -template -const typename CharacterAssociations::IDType>::MultimapIteratorPair -PAKRouter::lookupCharacterAttachmentRigs(const IDType& id) const { - return m_charAssoc.m_characterToAttachmentRigs.equal_range(id); -} - -template -const zeus::CMatrix4f* PAKRouter::lookupMAPATransform(const IDType& id) const { - auto search = m_mapaTransforms.find(id); - if (search == m_mapaTransforms.end()) - return nullptr; - return &search->second; -} - -template -hecl::ProjectPath PAKRouter::getAreaLayerWorking(const IDType& areaId, int layerIdx) const { - if (!m_bridges) - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("PAKRouter::build() must be called before PAKRouter::getAreaLayerWorking()")); - auto bridgePathIt = m_bridgePaths.cbegin(); - for (const BRIDGETYPE& bridge : *m_bridges) { - for (const auto& level : bridge.m_levelDeps) - for (const auto& area : level.second.areas) - if (area.first == areaId) { - hecl::ProjectPath levelPath(bridgePathIt->first, level.second.name); - hecl::ProjectPath areaPath(levelPath, area.second.name); - if (layerIdx < 0) - return areaPath; - return hecl::ProjectPath(areaPath, area.second.layers.at(layerIdx).name); - } - ++bridgePathIt; - } - return hecl::ProjectPath(); -} - -template -hecl::ProjectPath PAKRouter::getAreaLayerWorking(const IDType& areaId, int layerIdx, - bool& activeOut) const { - activeOut = false; - if (!m_bridges) - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("PAKRouter::build() must be called before PAKRouter::getAreaLayerWorking()")); - auto bridgePathIt = m_bridgePaths.cbegin(); - for (const BRIDGETYPE& bridge : *m_bridges) { - for (const auto& level : bridge.m_levelDeps) - for (const auto& area : level.second.areas) - if (area.first == areaId) { - hecl::ProjectPath levelPath(bridgePathIt->first, level.second.name); - hecl::ProjectPath areaPath(levelPath, area.second.name); - if (layerIdx < 0) - return areaPath; - const typename Level::Area::Layer& layer = area.second.layers.at(layerIdx); - activeOut = layer.active; - return hecl::ProjectPath(areaPath, layer.name); - } - ++bridgePathIt; - } - return hecl::ProjectPath(); -} - -template -hecl::ProjectPath PAKRouter::getAreaLayerCooked(const IDType& areaId, int layerIdx) const { - if (!m_bridges) - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("PAKRouter::build() must be called before PAKRouter::getAreaLayerCooked()")); - auto bridgePathIt = m_bridgePaths.cbegin(); - for (const BRIDGETYPE& bridge : *m_bridges) { - for (const auto& level : bridge.m_levelDeps) - for (const auto& area : level.second.areas) - if (area.first == areaId) { - hecl::ProjectPath levelPath(bridgePathIt->second, level.second.name); - hecl::ProjectPath areaPath(levelPath, area.second.name); - if (layerIdx < 0) - return areaPath; - return hecl::ProjectPath(areaPath, area.second.layers.at(layerIdx).name); - } - ++bridgePathIt; - } - return hecl::ProjectPath(); -} - -template -hecl::ProjectPath PAKRouter::getAreaLayerCooked(const IDType& areaId, int layerIdx, bool& activeOut) const { - activeOut = false; - if (!m_bridges) - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("PAKRouter::build() must be called before PAKRouter::getAreaLayerCooked()")); - auto bridgePathIt = m_bridgePaths.cbegin(); - for (const BRIDGETYPE& bridge : *m_bridges) { - for (const auto& level : bridge.m_levelDeps) - for (const auto& area : level.second.areas) - if (area.first == areaId) { - hecl::ProjectPath levelPath(bridgePathIt->second, level.second.name); - hecl::ProjectPath areaPath(levelPath, area.second.name); - if (layerIdx < 0) - return areaPath; - const typename Level::Area::Layer& layer = area.second.layers.at(layerIdx); - activeOut = layer.active; - return hecl::ProjectPath(areaPath, layer.name); - } - ++bridgePathIt; - } - return hecl::ProjectPath(); -} - -template -void PAKRouter::enumerateResources(const std::function& func) { - if (!m_bridges) - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("PAKRouter::build() must be called before PAKRouter::enumerateResources()")); - for (const auto& entryPair : m_uniqueEntries) - if (!func(entryPair.second.second)) - return; - for (const auto& entryPair : m_sharedEntries) - if (!func(entryPair.second.second)) - return; -} - -template -bool PAKRouter::mreaHasDupeResources(const IDType& id) const { - const PAKType* pak = m_pak.get(); - if (!pak) - LogDNACommon.report( - logvisor::Fatal, - FMT_STRING("PAKRouter::enterPAKBridge() must be called before PAKRouter::mreaHasDupeResources()")); - return pak->mreaHasDupeResources(id); -} - -template class PAKRouter; -template class PAKRouter; -template class PAKRouter; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/PAK.hpp b/DataSpec/DNACommon/PAK.hpp deleted file mode 100644 index 56e956436..000000000 --- a/DataSpec/DNACommon/PAK.hpp +++ /dev/null @@ -1,234 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -#include -#include -#include - -namespace DataSpec { - -/** PAK entry stream reader */ -class PAKEntryReadStream : public athena::io::IStreamReader { - std::unique_ptr m_buf; - atUint64 m_sz = 0; - atUint64 m_pos = 0; - -public: - PAKEntryReadStream() = default; - explicit operator bool() const { return m_buf.operator bool(); } - PAKEntryReadStream(const PAKEntryReadStream& other) = delete; - PAKEntryReadStream(PAKEntryReadStream&& other) = default; - PAKEntryReadStream& operator=(const PAKEntryReadStream& other) = delete; - PAKEntryReadStream& operator=(PAKEntryReadStream&& other) = default; - PAKEntryReadStream(std::unique_ptr&& buf, atUint64 sz, atUint64 pos) - : m_buf(std::move(buf)), m_sz(sz), m_pos(pos) { - if (m_pos >= m_sz) - LogDNACommon.report(logvisor::Fatal, FMT_STRING("PAK stream cursor overrun")); - } - void seek(atInt64 pos, athena::SeekOrigin origin) override { - if (origin == athena::SeekOrigin::Begin) { - m_pos = pos; - } else if (origin == athena::SeekOrigin::Current) { - m_pos += pos; - } else if (origin == athena::SeekOrigin::End) { - m_pos = m_sz + pos; - } - if (m_pos > m_sz) { - LogDNACommon.report(logvisor::Fatal, FMT_STRING("PAK stream cursor overrun")); - } - } - atUint64 position() const override { return m_pos; } - atUint64 length() const override { return m_sz; } - const atUint8* data() const { return m_buf.get(); } - atUint64 readUBytesToBuf(void* buf, atUint64 len) override { - atUint64 bufEnd = m_pos + len; - if (bufEnd > m_sz) - len -= bufEnd - m_sz; - memmove(buf, m_buf.get() + m_pos, len); - m_pos += len; - return len; - } -}; - -struct UniqueResult { - enum class Type { NotFound, Pak, Level, Area, Layer } m_type = Type::NotFound; - const std::string* m_levelName = nullptr; - const std::string* m_areaName = nullptr; - const std::string* m_layerName = nullptr; - UniqueResult() = default; - UniqueResult(Type tp) : m_type(tp) {} - - template - void checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRIDGE::PAKType::Entry& entry); - - hecl::ProjectPath uniquePath(const hecl::ProjectPath& pakPath) const; -}; - -template -class PAKRouter; - -/** Resource extractor type */ -template -struct ResExtractor { - std::function func_a; - std::function&, - const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::blender::Token&, - std::function)> - func_b; - std::array fileExts = {}; - unsigned weight = 0; - std::function&, typename PAKBRIDGE::PAKType::Entry&)> - func_name; - - ResExtractor() = default; - - ResExtractor(std::function func, - std::array&& fileExtsIn, unsigned weightin = 0, - std::function&, - typename PAKBRIDGE::PAKType::Entry&)> - nfunc = {}) - : func_a(std::move(func)), fileExts(std::move(fileExtsIn)), weight(weightin), func_name(std::move(nfunc)) {} - - ResExtractor(std::function&, - const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::blender::Token&, - std::function)> - func, - std::array&& fileExtsIn, unsigned weightin = 0, - std::function&, - typename PAKBRIDGE::PAKType::Entry&)> - nfunc = {}) - : func_b(std::move(func)), fileExts(std::move(fileExtsIn)), weight(weightin), func_name(std::move(nfunc)) {} - - bool IsFullyExtracted(const hecl::ProjectPath& path) const { - hecl::ProjectPath::Type tp = path.getPathType(); - if (tp == hecl::ProjectPath::Type::None) - return false; - else if (tp == hecl::ProjectPath::Type::Glob) { - for (int i = 0; i < 6; ++i) { - if (!fileExts[i]) - break; - hecl::ProjectPath withExt = path.getWithExtension(fileExts[i], true); - if (withExt.isNone()) - return false; - } - } - return true; - } -}; - -/** Level hierarchy representation */ -template -struct Level { - std::string name; - struct Area { - std::string name; - struct Layer { - std::string name; - bool active; - std::unordered_set resources; - }; - std::vector layers; - std::unordered_set resources; - }; - std::unordered_map areas; - std::unordered_set resources; -}; - -/** PAKRouter (for detecting shared entry locations) */ -template -class PAKRouter : public PAKRouterBase { -public: - using PAKType = typename BRIDGETYPE::PAKType; - using IDType = typename PAKType::IDType; - using EntryType = typename PAKType::Entry; - -private: - const std::vector* m_bridges = nullptr; - std::vector> m_bridgePaths; - ThreadLocalPtr m_curBridgeIdx; - const hecl::ProjectPath& m_gameWorking; - const hecl::ProjectPath& m_gameCooked; - hecl::ProjectPath m_sharedWorking; - hecl::ProjectPath m_sharedCooked; - ThreadLocalPtr m_pak; - ThreadLocalPtr m_node; - std::unordered_map> m_uniqueEntries; - std::unordered_map> m_sharedEntries; - std::unordered_map m_overrideEntries; - CharacterAssociations m_charAssoc; - std::unordered_map m_mapaTransforms; - - hecl::ProjectPath getCharacterWorking(const EntryType* entry) const; - -public: - PAKRouter(const SpecBase& dataSpec, const hecl::ProjectPath& working, const hecl::ProjectPath& cooked) - : PAKRouterBase(dataSpec) - , m_gameWorking(working) - , m_gameCooked(cooked) - , m_sharedWorking(working, "Shared") - , m_sharedCooked(cooked, "Shared") {} - - void build(std::vector& bridges, std::function progress); - - void enterPAKBridge(const BRIDGETYPE& pakBridge); - const BRIDGETYPE& getCurrentBridge() const { return (*m_bridges)[reinterpret_cast(m_curBridgeIdx.get())]; } - - using PAKRouterBase::getWorking; - hecl::ProjectPath getWorking(const EntryType* entry, const ResExtractor& extractor) const; - hecl::ProjectPath getWorking(const EntryType* entry) const; - hecl::ProjectPath getWorking(const IDType& id, bool silenceWarnings = false) const override; - hecl::ProjectPath getCooked(const EntryType* entry) const; - hecl::ProjectPath getCooked(const IDType& id, bool silenceWarnings = false) const; - - std::string getResourceRelativePath(const EntryType& a, const IDType& b) const; - - std::string getBestEntryName(const EntryType& entry, bool stdOverride = true) const; - std::string getBestEntryName(const IDType& entry, bool stdOverride = true) const; - - bool extractResources(const BRIDGETYPE& pakBridge, bool force, hecl::blender::Token& btok, - std::function progress); - - const typename BRIDGETYPE::PAKType::Entry* lookupEntry(const IDType& entry, const nod::Node** nodeOut = nullptr, - bool silenceWarnings = false, bool currentPAK = false) const; - - template - bool lookupAndReadDNA(const IDType& id, DNA& out, bool silenceWarnings = false) { - const nod::Node* node; - const EntryType* entry = lookupEntry(id, &node, silenceWarnings); - if (!entry) - return false; - PAKEntryReadStream rs = entry->beginReadStream(*node); - out.read(rs); - return true; - } - - PAKEntryReadStream beginReadStreamForId(const IDType& id, bool silenceWarnings = false) { - const nod::Node* node; - const EntryType* entry = lookupEntry(id, &node, silenceWarnings); - return entry->beginReadStream(*node); - } - - const typename CharacterAssociations::RigPair* lookupCMDLRigPair(const IDType& id) const; - const typename CharacterAssociations::MultimapIteratorPair - lookupCharacterAttachmentRigs(const IDType& id) const; - const zeus::CMatrix4f* lookupMAPATransform(const IDType& mapaId) const; - - hecl::ProjectPath getAreaLayerWorking(const IDType& areaId, int layerIdx) const; - hecl::ProjectPath getAreaLayerWorking(const IDType& areaId, int layerIdx, bool& activeOut) const; - hecl::ProjectPath getAreaLayerCooked(const IDType& areaId, int layerIdx) const; - hecl::ProjectPath getAreaLayerCooked(const IDType& areaId, int layerIdx, bool& activeOut) const; - - void enumerateResources(const std::function& func); - - bool mreaHasDupeResources(const IDType& id) const; -}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/PART.cpp b/DataSpec/DNACommon/PART.cpp deleted file mode 100644 index 23176e42a..000000000 --- a/DataSpec/DNACommon/PART.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "DataSpec/DNACommon/PART.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAParticle { - -template struct PPImpl<_GPSM>; -template struct PPImpl<_GPSM>; - -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_GPSM>) -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_GPSM>) - -template <> -std::string_view GPSM::DNAType() { - return "GPSM"sv; -} - -template <> -std::string_view GPSM::DNAType() { - return "GPSM"sv; -} - -template -bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - GPSM gpsm; - gpsm.read(rs); - athena::io::ToYAMLStream(gpsm, writer); - return true; - } - return false; -} -template bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteGPSM(const GPSM& gpsm, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - gpsm.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteGPSM(const GPSM& gpsm, const hecl::ProjectPath& outPath); -template bool WriteGPSM(const GPSM& gpsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/PART.def b/DataSpec/DNACommon/PART.def deleted file mode 100644 index 8b932cbf3..000000000 --- a/DataSpec/DNACommon/PART.def +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef ENTRY -#define ENTRY(name, identifier) -#endif - -#ifndef INT_ENTRY -#define INT_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef REAL_ENTRY -#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef VECTOR_ENTRY -#define VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef MOD_VECTOR_ENTRY -#define MOD_VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef COLOR_ENTRY -#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef EMITTER_ENTRY -#define EMITTER_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef UV_ENTRY -#define UV_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef RES_ENTRY -#define RES_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef KSSM_ENTRY -#define KSSM_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef BOOL_ENTRY -#define BOOL_ENTRY(name, identifier, def) ENTRY(name, identifier) -#endif - -VECTOR_ENTRY('PSIV', x0_PSIV) -MOD_VECTOR_ENTRY('PSVM', x4_PSVM) -VECTOR_ENTRY('PSOV', x8_PSOV) -INT_ENTRY('PSLT', xc_PSLT) -INT_ENTRY('PSWT', x10_PSWT) -REAL_ENTRY('PSTS', x14_PSTS) -VECTOR_ENTRY('POFS', x18_POFS) -INT_ENTRY('SEED', x1c_SEED) -REAL_ENTRY('LENG', x20_LENG) -REAL_ENTRY('WIDT', x24_WIDT) -INT_ENTRY('MAXP', x28_MAXP) -REAL_ENTRY('GRTE', x2c_GRTE) -COLOR_ENTRY('COLR', x30_COLR) -INT_ENTRY('LTME', x34_LTME) -VECTOR_ENTRY('ILOC', x38_ILOC) -VECTOR_ENTRY('IVEC', x3c_IVEC) -EMITTER_ENTRY('EMTR', x40_EMTR) -INT_ENTRY('MBSP', x48_MBSP) -REAL_ENTRY('SIZE', x4c_SIZE) -REAL_ENTRY('ROTA', x50_ROTA) -UV_ENTRY('TEXR', x54_TEXR) -UV_ENTRY('TIND', x58_TIND) -RES_ENTRY('PMDL', x5c_PMDL) -VECTOR_ENTRY('PMOP', x6c_PMOP) -VECTOR_ENTRY('PMRT', x70_PMRT) -VECTOR_ENTRY('PMSC', x74_PMSC) -COLOR_ENTRY('PMCL', x78_PMCL) -MOD_VECTOR_ENTRY('VEL1', x7c_VEL1) -MOD_VECTOR_ENTRY('VEL2', x80_VEL2) -MOD_VECTOR_ENTRY('VEL3', x84_VEL3) -MOD_VECTOR_ENTRY('VEL4', x88_VEL4) -RES_ENTRY('ICTS', x8c_ICTS) -INT_ENTRY('NCSY', x9c_NCSY) -INT_ENTRY('CSSD', xa0_CSSD) -RES_ENTRY('IDTS', xa4_IDTS) -INT_ENTRY('NDSY', xb4_NDSY) -RES_ENTRY('IITS', xb8_IITS) -INT_ENTRY('PISY', xc8_PISY) -INT_ENTRY('SISY', xcc_SISY) -KSSM_ENTRY('KSSM', xd0_KSSM) -RES_ENTRY('SSWH', xd4_SSWH) -INT_ENTRY('SSSD', xe4_SSSD) -VECTOR_ENTRY('SSPO', xe8_SSPO) -INT_ENTRY('SESD', xf8_SESD) -VECTOR_ENTRY('SEPO', xfc_SEPO) -RES_ENTRY('PMLC', xec_PMLC) -INT_ENTRY('LTYP', x100_LTYP) -COLOR_ENTRY('LCLR', x104_LCLR) -REAL_ENTRY('LINT', x108_LINT) -VECTOR_ENTRY('LOFF', x10c_LOFF) -VECTOR_ENTRY('LDIR', x110_LDIR) -INT_ENTRY('LFOT', x114_LFOT) -REAL_ENTRY('LFOR', x118_LFOR) -REAL_ENTRY('LSLA', x11c_LSLA) - -/* 0-00 additions */ -RES_ENTRY('SELC', xd8_SELC) -REAL_ENTRY('ADV1', x10c_ADV1) -REAL_ENTRY('ADV2', x110_ADV2) -REAL_ENTRY('ADV3', x114_ADV3) -REAL_ENTRY('ADV4', x118_ADV4) -REAL_ENTRY('ADV5', x11c_ADV5) -REAL_ENTRY('ADV6', x120_ADV6) -REAL_ENTRY('ADV7', x124_ADV7) -REAL_ENTRY('ADV8', x128_ADV8) - -BOOL_ENTRY('SORT', x44_28_SORT, false) -BOOL_ENTRY('MBLR', x44_30_MBLR, false) -BOOL_ENTRY('LINE', x44_24_LINE, false) -BOOL_ENTRY('LIT_', x44_29_LIT_, false) -BOOL_ENTRY('AAPH', x44_26_AAPH, false) -BOOL_ENTRY('ZBUF', x44_27_ZBUF, false) -BOOL_ENTRY('FXLL', x44_25_FXLL, false) -BOOL_ENTRY('PMAB', x44_31_PMAB, false) -BOOL_ENTRY('VMD4', x45_29_VMD4, false) -BOOL_ENTRY('VMD3', x45_28_VMD3, false) -BOOL_ENTRY('VMD2', x45_27_VMD2, false) -BOOL_ENTRY('VMD1', x45_26_VMD1, false) -BOOL_ENTRY('OPTS', x45_31_OPTS, false) -BOOL_ENTRY('PMUS', x45_24_PMUS, false) -BOOL_ENTRY('PMOO', x45_25_PMOO, true) -BOOL_ENTRY('CIND', x45_30_CIND, false) - -BOOL_ENTRY('ORNT', x30_30_ORNT, false) -BOOL_ENTRY('RSOP', x30_31_RSOP, false) - -#undef ENTRY -#undef INT_ENTRY -#undef REAL_ENTRY -#undef VECTOR_ENTRY -#undef MOD_VECTOR_ENTRY -#undef COLOR_ENTRY -#undef EMITTER_ENTRY -#undef UV_ENTRY -#undef RES_ENTRY -#undef KSSM_ENTRY -#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/PART.hpp b/DataSpec/DNACommon/PART.hpp deleted file mode 100644 index 679f6dfe2..000000000 --- a/DataSpec/DNACommon/PART.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ParticleCommon.hpp" - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAParticle { - -template -struct _GPSM { - static constexpr ParticleType Type = ParticleType::GPSM; - -#define INT_ENTRY(name, identifier) IntElementFactory identifier; -#define REAL_ENTRY(name, identifier) RealElementFactory identifier; -#define VECTOR_ENTRY(name, identifier) VectorElementFactory identifier; -#define MOD_VECTOR_ENTRY(name, identifier) ModVectorElementFactory identifier; -#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; -#define EMITTER_ENTRY(name, identifier) EmitterElementFactory identifier; -#define UV_ENTRY(name, identifier) UVElementFactory identifier; -#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; -#define KSSM_ENTRY(name, identifier) SpawnSystemKeyframeData identifier; -#define BOOL_ENTRY(name, identifier, def) bool identifier = def; -#include "PART.def" - - template - void constexpr Enumerate(_Func f) { -#define ENTRY(name, identifier) f(FOURCC(name), identifier); -#define BOOL_ENTRY(name, identifier, def) f(FOURCC(name), identifier, def); -#include "PART.def" - } - - template - bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { -#define ENTRY(name, identifier) \ - case SBIG(name): \ - f(identifier); \ - return true; -#include "PART.def" - default: - return false; - } - } -}; -template -using GPSM = PPImpl<_GPSM>; - -template -bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteGPSM(const GPSM& gpsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/PATH.cpp b/DataSpec/DNACommon/PATH.cpp deleted file mode 100644 index 9ef5325fb..000000000 --- a/DataSpec/DNACommon/PATH.cpp +++ /dev/null @@ -1,249 +0,0 @@ -#include "PATH.hpp" -#include "hecl/Blender/Connection.hpp" -#include "zeus/CAABox.hpp" -#include "DataSpec/DNACommon/AROTBuilder.hpp" -#include - -namespace DataSpec::DNAPATH { - -#define DUMP_OCTREE 0 - -#if DUMP_OCTREE -/* octree dumper */ -static void OutputOctreeNode(hecl::blender::PyOutStream& os, int idx, const zeus::CAABox& aabb) { - const zeus::CVector3f pos = aabb.center(); - const zeus::CVector3f extent = aabb.extents(); - os.format( - "obj = bpy.data.objects.new('Leaf_%d', None)\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "obj.location = (%f,%f,%f)\n" - "obj.scale = (%f,%f,%f)\n" - "obj.empty_display_type = 'CUBE'\n" - "obj.layers[1] = True\n" - "obj.layers[0] = False\n", - idx, pos.x(), pos.y(), pos.z(), extent.x(), extent.y(), extent.z()); -} -#endif - -template -void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entryName, - const zeus::CMatrix4f* xf, const std::string& areaPath) { - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os << "import bpy\n" - "import bmesh\n" - "from mathutils import Vector, Matrix\n" - "\n" - "bpy.types.Material.retro_path_idx_mask = bpy.props.IntProperty(name='Retro: Path Index Mask')\n" - "bpy.types.Material.retro_path_type_mask = bpy.props.IntProperty(name='Retro: Path Type Mask')\n" - "\n" - "material_dict = {}\n" - "material_index = []\n" - "def make_ground_material(idxMask):\n" - " mat = bpy.data.materials.new('Ground %X' % idxMask)\n" - " mat.diffuse_color = (0.8, 0.460, 0.194, 1.0)\n" - " return mat\n" - "def make_flyer_material(idxMask):\n" - " mat = bpy.data.materials.new('Flyer %X' % idxMask)\n" - " mat.diffuse_color = (0.016, 0.8, 0.8, 1.0)\n" - " return mat\n" - "def make_swimmer_material(idxMask):\n" - " mat = bpy.data.materials.new('Swimmer %X' % idxMask)\n" - " mat.diffuse_color = (0.074, 0.293, 0.8, 1.0)\n" - " return mat\n" - "def select_material(meshIdxMask, meshTypeMask):\n" - " key = (meshIdxMask, meshTypeMask)\n" - " if key in material_index:\n" - " return material_index.index(key)\n" - " elif key in material_dict:\n" - " material_index.append(key)\n" - " return len(material_index)-1\n" - " else:\n" - " if meshTypeMask == 0x2:\n" - " mat = make_flyer_material(meshIdxMask)\n" - " elif meshTypeMask == 0x4:\n" - " mat = make_swimmer_material(meshIdxMask)\n" - " else:\n" - " mat = make_ground_material(meshIdxMask)\n" - " mat.retro_path_idx_mask = meshIdxMask\n" - " mat.retro_path_type_mask = meshTypeMask\n" - " material_dict[key] = mat\n" - " material_index.append(key)\n" - " return len(material_index)-1\n" - "\n"; - os.format(FMT_STRING("bpy.context.scene.name = '{}'\n"), entryName); - os << "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "bm = bmesh.new()\n" - "height_lay = bm.faces.layers.float.new('Height')\n"; - - for (const Node& n : nodes) { - zeus::simd_floats f(n.position.simd); - os.format(FMT_STRING("bm.verts.new(({},{},{}))\n"), f[0], f[1], f[2]); - } - - os << "bm.verts.ensure_lookup_table()\n"; - - for (const Region& r : regions) { - os << "tri_verts = []\n"; - for (atUint32 i = 0; i < r.nodeCount; ++i) - os.format(FMT_STRING("tri_verts.append(bm.verts[{}])\n"), r.nodeStart + i); - - os.format(FMT_STRING("face = bm.faces.get(tri_verts)\n" - "if face is None:\n" - " face = bm.faces.new(tri_verts)\n" - " face.normal_flip()\n" - "face.material_index = select_material(0x{:04X}, 0x{:04X})\n" - "face.smooth = False\n" - "face[height_lay] = {}\n" - "\n"), - r.meshIndexMask, r.meshTypeMask, r.height); - -#if 0 - const zeus::CVector3f center = xf->multiplyOneOverW(r.centroid); - zeus::CAABox aabb(xf->multiplyOneOverW(r.aabb[0]), xf->multiplyOneOverW(r.aabb[1])); - os.format(FMT_STRING("aabb = bpy.data.objects.new('AABB', None)\n") - "aabb.location = (%f,%f,%f)\n" - "aabb.scale = (%f,%f,%f)\n" - "aabb.empty_display_type = 'CUBE'\n" - "bpy.context.scene.collection.objects.link(aabb)\n" - "centr = bpy.data.objects.new('Center', None)\n" - "centr.location = (%f,%f,%f)\n" - "bpy.context.scene.collection.objects.link(centr)\n", - aabb.min[0] + (aabb.max[0] - aabb.min[0]) / 2.f, - aabb.min[1] + (aabb.max[1] - aabb.min[1]) / 2.f, - aabb.min[2] + (aabb.max[2] - aabb.min[2]) / 2.f, - (aabb.max[0] - aabb.min[0]) / 2.f, - (aabb.max[1] - aabb.min[1]) / 2.f, - (aabb.max[2] - aabb.min[2]) / 2.f, - center.x(), center.y(), center.z()); -#endif - } - -#if 0 - for (const Node& n : nodes) { - zeus::simd_floats f(n.position.simd); - zeus::simd_floats no(n.position.simd + n.normal.simd); - os.format(FMT_STRING("v = bm.verts.new((%f,%f,%f))\n") - "v2 = bm.verts.new((%f,%f,%f))\n" - "bm.edges.new((v, v2))\n", f[0], f[1], f[2], no[0], no[1], no[2]); - } -#endif - - os << "bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.001)\n" - "path_mesh = bpy.data.meshes.new('PATH')\n" - "bm.to_mesh(path_mesh)\n" - "path_mesh_obj = bpy.data.objects.new(path_mesh.name, path_mesh)\n" - "\n" - "for mat_name in material_index:\n" - " mat = material_dict[mat_name]\n" - " path_mesh.materials.append(mat)\n" - "\n" - "bpy.context.scene.collection.objects.link(path_mesh_obj)\n" - "path_mesh_obj.display_type = 'SOLID'\n" - "bpy.context.scene.hecl_path_obj = path_mesh_obj.name\n" - "\n"; - - if (xf) { - const zeus::CMatrix4f& w = *xf; - zeus::simd_floats xfMtxF[4]; - for (int i = 0; i < 4; ++i) - w.m[i].mSimd.copy_to(xfMtxF[i]); - os.format(FMT_STRING("mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "path_mesh_obj.rotation_mode = 'QUATERNION'\n" - "path_mesh_obj.location = mtxd[0]\n" - "path_mesh_obj.rotation_quaternion = mtxd[1]\n" - "path_mesh_obj.scale = mtxd[2]\n"), - xfMtxF[0][0], xfMtxF[1][0], xfMtxF[2][0], xfMtxF[3][0], xfMtxF[0][1], xfMtxF[1][1], xfMtxF[2][1], - xfMtxF[3][1], xfMtxF[0][2], xfMtxF[1][2], xfMtxF[2][2], xfMtxF[3][2]); - } - -#if DUMP_OCTREE - { - int idx = 0; - for (const auto& n : octree) { - if (n.isLeaf) - OutputOctreeNode(os, idx, zeus::CAABox(n.aabb[0], n.aabb[1])); - ++idx; - } - } -#endif - - os.linkBackground(fmt::format(FMT_STRING("//{}"), areaPath)); - os.centerView(); - os.close(); -} - -template -bool PATH::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKBridge::PAKType::Entry& entry, - bool force, hecl::blender::Token& btok, - std::function fileChanged) { - PATH path; - path.read(rs); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::PathMesh)) - return false; - - std::string areaPath; - for (const auto& ent : hecl::DirectoryEnumerator(outPath.getParentPath().getAbsolutePath())) { - if (hecl::StringUtils::BeginsWith(ent.m_name, "!area_")) { - areaPath = ent.m_name; - break; - } - } - - const zeus::CMatrix4f* xf = pakRouter.lookupMAPATransform(entry.id); - path.sendToBlender(conn, pakRouter.getBestEntryName(entry, false), xf, areaPath); - return conn.saveBlend(); -} - -template -bool PATH::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const PathMesh& mesh, - hecl::blender::Token& btok) { - athena::io::MemoryReader r(mesh.data.data(), mesh.data.size()); - PATH path; - path.read(r); - if (!path.regions.empty()) { - AROTBuilder octreeBuilder; - octreeBuilder.buildPath(path); - } else { - path.octreeNodeCount = 1; - path.octree.emplace_back(); - OctreeNode& n = path.octree.back(); - n.isLeaf = 1; - n.aabb[0] = zeus::CVector3f{FLT_MAX, FLT_MAX, FLT_MAX}; - n.aabb[1] = zeus::CVector3f{-FLT_MAX, -FLT_MAX, -FLT_MAX}; - for (int i = 0; i < 8; ++i) - n.children[i] = 0xffffffff; - } - -#if DUMP_OCTREE - { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(inPath.getWithExtension(".octree.blend", true), hecl::blender::BlendType::PathMesh)) - return false; - - zeus::CMatrix4f xf; - path.sendToBlender(conn, "PATH"sv, &xf); - conn.saveBlend(); - } -#endif - - athena::io::FileWriter w(outPath.getAbsolutePath()); - path.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} - -template struct PATH; -template struct PATH; -template struct PATH; - -} // namespace DataSpec::DNAPATH diff --git a/DataSpec/DNACommon/PATH.hpp b/DataSpec/DNACommon/PATH.hpp deleted file mode 100644 index 8058f9c5f..000000000 --- a/DataSpec/DNACommon/PATH.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNAMP1/DNAMP1.hpp" -#include "DataSpec/DNAMP2/DNAMP2.hpp" -#include "DataSpec/DNAMP3/DNAMP3.hpp" - -namespace DataSpec::DNAPATH { -template -struct RegionPointers {}; -template <> -struct RegionPointers : BigDNA { - AT_DECL_DNA - Value regionIdxPtr; -}; -template <> -struct RegionPointers : BigDNA { - AT_DECL_DNA - Value unk0; - Value unk1; - Value unk2; - Value regionIdxPtr; -}; -template <> -struct RegionPointers : BigDNA { - AT_DECL_DNA - Value unk0; - Value unk1; - Value unk2; - Value regionIdxPtr; -}; - -template -struct AT_SPECIALIZE_PARMS(DataSpec::DNAMP1::PAKBridge, DataSpec::DNAMP2::PAKBridge, DataSpec::DNAMP3::PAKBridge) PATH -: BigDNA { - using PathMesh = hecl::blender::PathMesh; - - AT_DECL_DNA - Value version; - - struct Node : BigDNA { - AT_DECL_DNA - Value position; - Value normal; - }; - Value nodeCount; - Vector nodes; - - struct Link : BigDNA { - AT_DECL_DNA - Value nodeIdx; - Value regionIdx; - Value width2d; - Value oneOverWidth2d; - }; - Value linkCount; - Vector links; - - struct Region : BigDNA { - AT_DECL_DNA - Value nodeCount; - Value nodeStart; - Value linkCount; - Value linkStart; - Value meshIndexMask; - Value meshTypeMask; - Value height; - Value normal; - Value regionIdx; - Value centroid; - Value aabb[2]; - Value> pointers; - }; - Value regionCount; - Vector regions; - - Vector bitmap1; - Vector bitmap2; - - /* Unused in all games, removed in MP3 */ - Vector - ? 0 - : (((((regionCount * regionCount) + 31) / 32) - bitmap1.size()) * 2))> - bitmap3; - - Value octreeRegionLookupCount; - Vector octreeRegionLookup; - - struct OctreeNode : BigDNA { - AT_DECL_DNA - Value isLeaf; - Value aabb[2]; - Value centroid; - Value children[8]; - Value regionCount; - Value regionStart; - }; - Value octreeNodeCount; - Vector octree; - - void sendToBlender(hecl::blender::Connection& conn, std::string_view entryName, const zeus::CMatrix4f* xf, - const std::string& areaPath); - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKBridge::PAKType::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged); - - static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const PathMesh& mesh, - hecl::blender::Token& btok); -}; -} // namespace DataSpec::DNAPATH diff --git a/DataSpec/DNACommon/ParticleCommon.cpp b/DataSpec/DNACommon/ParticleCommon.cpp deleted file mode 100644 index 79c1381ee..000000000 --- a/DataSpec/DNACommon/ParticleCommon.cpp +++ /dev/null @@ -1,586 +0,0 @@ -#include "ParticleCommon.hpp" - -namespace DataSpec::DNAParticle { -logvisor::Module LogModule("DataSpec::DNAParticle"); - -template struct PEImpl<_RealElementFactory>; -template struct PEImpl<_IntElementFactory>; -template struct PEImpl<_VectorElementFactory>; -template struct PEImpl<_ColorElementFactory>; -template struct PEImpl<_ModVectorElementFactory>; -template struct PEImpl<_EmitterElementFactory>; -template struct PEImpl<_UVElementFactory>; -template struct PEImpl<_UVElementFactory>; - -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_RealElementFactory>) -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_IntElementFactory>) -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_VectorElementFactory>) -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_ColorElementFactory>) -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_ModVectorElementFactory>) -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_EmitterElementFactory>) -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_UVElementFactory>) -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_UVElementFactory>) - -template <> -void REConstant::Enumerate(typename ReadYaml::StreamT& r) { - val = r.readFloat(); -} -template <> -void REConstant::Enumerate(typename WriteYaml::StreamT& w) { - w.writeFloat(val); -} -template <> -void REConstant::Enumerate(typename BinarySize::StreamT& s) { - s += 4; -} -template <> -void REConstant::Enumerate(typename Read::StreamT& r) { - val = r.readFloatBig(); -} -template <> -void REConstant::Enumerate(typename Write::StreamT& w) { - w.writeFloatBig(val); -} - -template <> -void IEConstant::Enumerate(typename ReadYaml::StreamT& r) { - val = r.readUint32(); -} -template <> -void IEConstant::Enumerate(typename WriteYaml::StreamT& w) { - w.writeUint32(val); -} -template <> -void IEConstant::Enumerate(typename BinarySize::StreamT& s) { - s += 4; -} -template <> -void IEConstant::Enumerate(typename Read::StreamT& r) { - val = r.readUint32Big(); -} -template <> -void IEConstant::Enumerate(typename Write::StreamT& w) { - w.writeUint32Big(val); -} - -template <> -void VEConstant::Enumerate(typename ReadYaml::StreamT& r) { - size_t elemCount; - if (auto v = r.enterSubVector(elemCount)) { - for (size_t i = 0; i < 3 && i < elemCount; ++i) { - if (auto rec = r.enterSubRecord()) - comps[i].read(r); - } - } -} -template <> -void VEConstant::Enumerate(typename WriteYaml::StreamT& w) { - if (auto v = w.enterSubVector()) - for (int i = 0; i < 3; ++i) - if (auto rec = w.enterSubRecord()) - comps[i].write(w); -} -template <> -void VEConstant::Enumerate(typename BinarySize::StreamT& s) { - comps[0].binarySize(s); - comps[1].binarySize(s); - comps[2].binarySize(s); -} -template <> -void VEConstant::Enumerate(typename Read::StreamT& r) { - comps[0].read(r); - comps[1].read(r); - comps[2].read(r); -} -template <> -void VEConstant::Enumerate(typename Write::StreamT& w) { - comps[0].write(w); - comps[1].write(w); - comps[2].write(w); -} - -template <> -void CEConstant::Enumerate(typename ReadYaml::StreamT& r) { - for (int i = 0; i < 4; ++i) - if (auto rec = r.enterSubRecord()) - comps[i].read(r); -} -template <> -void CEConstant::Enumerate(typename WriteYaml::StreamT& w) { - if (auto v = w.enterSubVector()) - for (int i = 0; i < 4; ++i) - if (auto rec = w.enterSubRecord()) - comps[i].write(w); -} -template <> -void CEConstant::Enumerate(typename BinarySize::StreamT& s) { - comps[0].binarySize(s); - comps[1].binarySize(s); - comps[2].binarySize(s); - comps[3].binarySize(s); -} -template <> -void CEConstant::Enumerate(typename Read::StreamT& r) { - comps[0].read(r); - comps[1].read(r); - comps[2].read(r); - comps[3].read(r); -} -template <> -void CEConstant::Enumerate(typename Write::StreamT& w) { - comps[0].write(w); - comps[1].write(w); - comps[2].write(w); - comps[3].write(w); -} - -template <> -void MVEConstant::Enumerate(typename ReadYaml::StreamT& r) { - for (int i = 0; i < 3; ++i) - if (auto rec = r.enterSubRecord()) - comps[i].read(r); -} -template <> -void MVEConstant::Enumerate(typename WriteYaml::StreamT& w) { - if (auto v = w.enterSubVector()) - for (int i = 0; i < 3; ++i) - if (auto rec = w.enterSubRecord()) - comps[i].write(w); -} -template <> -void MVEConstant::Enumerate(typename BinarySize::StreamT& s) { - comps[0].binarySize(s); - comps[1].binarySize(s); - comps[2].binarySize(s); -} -template <> -void MVEConstant::Enumerate(typename Read::StreamT& r) { - comps[0].read(r); - comps[1].read(r); - comps[2].read(r); -} -template <> -void MVEConstant::Enumerate(typename Write::StreamT& w) { - comps[0].write(w); - comps[1].write(w); - comps[2].write(w); -} - -template <> -void BoolHelper::Enumerate(typename ReadYaml::StreamT& r) { - value = r.readBool(); -} -template <> -void BoolHelper::Enumerate(typename WriteYaml::StreamT& w) { - w.writeBool(value); -} -template <> -void BoolHelper::Enumerate(typename BinarySize::StreamT& s) { - s += 5; -} -template <> -void BoolHelper::Enumerate(typename Read::StreamT& r) { - uint32_t clsId; - r.readBytesToBuf(&clsId, 4); - if (clsId == SBIG('CNST')) - value = r.readBool(); - else - value = false; -} -template <> -void BoolHelper::Enumerate(typename Write::StreamT& w) { - w.writeBytes("CNST", 4); - w.writeBool(value); -} - -template struct ValueHelper; -template struct ValueHelper; - -AT_SUBSPECIALIZE_DNA_YAML(ValueHelper) -AT_SUBSPECIALIZE_DNA_YAML(ValueHelper) - -template <> -void EESimpleEmitterTR::Enumerate(typename ReadYaml::StreamT& r) { - position.reset(); - velocity.reset(); - if (auto rec = r.enterSubRecord("ILOC")) - position.read(r); - if (auto rec = r.enterSubRecord("IVEC")) - velocity.read(r); -} -template <> -void EESimpleEmitterTR::Enumerate(typename WriteYaml::StreamT& w) { - if (auto rec = w.enterSubRecord("ILOC")) - position.write(w); - if (auto rec = w.enterSubRecord("IVEC")) - velocity.write(w); -} -template <> -void EESimpleEmitterTR::Enumerate(typename BinarySize::StreamT& s) { - s += 8; - position.binarySize(s); - velocity.binarySize(s); -} -template <> -void EESimpleEmitterTR::Enumerate(typename Read::StreamT& r) { - position.reset(); - velocity.reset(); - uint32_t clsId; - r.readBytesToBuf(&clsId, 4); - if (clsId == SBIG('ILOC')) { - position.read(r); - r.readBytesToBuf(&clsId, 4); - if (clsId == SBIG('IVEC')) - velocity.read(r); - } -} -template <> -void EESimpleEmitterTR::Enumerate(typename Write::StreamT& w) { - w.writeBytes("ILOC", 4); - position.write(w); - w.writeBytes("IVEC", 4); - velocity.write(w); -} - -template <> -std::string_view UVEConstant::DNAType() { - return "UVEConstant"sv; -} -template <> -std::string_view UVEConstant::DNAType() { - return "UVEConstant"sv; -} - -template -void UVEConstant::_read(typename ReadYaml::StreamT& r) { - tex.clear(); - if (auto rec = r.enterSubRecord("tex")) - tex.read(r); -} -template -void UVEConstant::_write(typename WriteYaml::StreamT& w) const { - if (auto rec = w.enterSubRecord("tex")) - tex.write(w); -} -template -void UVEConstant::_binarySize(typename BinarySize::StreamT& _s) const { - _s += 4; - tex.binarySize(_s); -} -template -void UVEConstant::_read(typename Read::StreamT& r) { - tex.clear(); - uint32_t clsId; - r.readBytesToBuf(&clsId, 4); - if (clsId == SBIG('CNST')) - tex.read(r); -} -template -void UVEConstant::_write(typename Write::StreamT& w) const { - w.writeBytes("CNST", 4); - tex.write(w); -} - -AT_SUBSPECIALIZE_DNA_YAML(UVEConstant) -AT_SUBSPECIALIZE_DNA_YAML(UVEConstant) - -template struct UVEConstant; -template struct UVEConstant; - -template <> -std::string_view UVEAnimTexture::DNAType() { - return "UVEAnimTexture"sv; -} -template <> -std::string_view UVEAnimTexture::DNAType() { - return "UVEAnimTexture"sv; -} - -template -void UVEAnimTexture::_read(typename ReadYaml::StreamT& r) { - tex.clear(); - if (auto rec = r.enterSubRecord("tex")) - tex.read(r); - if (auto rec = r.enterSubRecord("tileW")) - tileW.read(r); - if (auto rec = r.enterSubRecord("tileH")) - tileH.read(r); - if (auto rec = r.enterSubRecord("strideW")) - strideW.read(r); - if (auto rec = r.enterSubRecord("strideH")) - strideH.read(r); - if (auto rec = r.enterSubRecord("cycleFrames")) - cycleFrames.read(r); - if (auto rec = r.enterSubRecord("loop")) - loop = r.readBool(); -} -template -void UVEAnimTexture::_write(typename WriteYaml::StreamT& w) const { - if (auto rec = w.enterSubRecord("tex")) - tex.write(w); - if (auto rec = w.enterSubRecord("tileW")) - tileW.write(w); - if (auto rec = w.enterSubRecord("tileH")) - tileH.write(w); - if (auto rec = w.enterSubRecord("strideW")) - strideW.write(w); - if (auto rec = w.enterSubRecord("strideH")) - strideH.write(w); - if (auto rec = w.enterSubRecord("cycleFrames")) - cycleFrames.write(w); - w.writeBool("loop", loop); -} -template -void UVEAnimTexture::_binarySize(typename BinarySize::StreamT& _s) const { - _s += 9; - tex.binarySize(_s); - tileW.binarySize(_s); - tileH.binarySize(_s); - strideW.binarySize(_s); - strideH.binarySize(_s); - cycleFrames.binarySize(_s); -} -template -void UVEAnimTexture::_read(typename Read::StreamT& r) { - tex.clear(); - uint32_t clsId; - r.readBytesToBuf(&clsId, 4); - if (clsId == SBIG('CNST')) - tex.read(r); - tileW.read(r); - tileH.read(r); - strideW.read(r); - strideH.read(r); - cycleFrames.read(r); - r.readBytesToBuf(&clsId, 4); - if (clsId == SBIG('CNST')) - loop = r.readBool(); -} -template -void UVEAnimTexture::_write(typename Write::StreamT& w) const { - w.writeBytes("CNST", 4); - tex.write(w); - tileW.write(w); - tileH.write(w); - strideW.write(w); - strideH.write(w); - cycleFrames.write(w); - w.writeBytes("CNST", 4); - w.writeBool(loop); -} - -AT_SUBSPECIALIZE_DNA_YAML(UVEAnimTexture) -AT_SUBSPECIALIZE_DNA_YAML(UVEAnimTexture) - -template struct UVEAnimTexture; -template struct UVEAnimTexture; - -template <> -std::string_view UVElementFactory::DNAType() { - return "UVElementFactory"sv; -} -template <> -std::string_view UVElementFactory::DNAType() { - return "UVElementFactory"sv; -} - -template <> -std::string_view SpawnSystemKeyframeData::SpawnSystemKeyframeInfo::DNAType() { - return "SpawnSystemKeyframeData::SpawnSystemKeyframeInfo"sv; -} -template <> -std::string_view SpawnSystemKeyframeData::SpawnSystemKeyframeInfo::DNAType() { - return "SpawnSystemKeyframeData::SpawnSystemKeyframeInfo"sv; -} - -template -template -void SpawnSystemKeyframeData::SpawnSystemKeyframeInfo::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"id"}, id, s); - Do(athena::io::PropId{"a"}, a, s); - Do(athena::io::PropId{"b"}, b, s); - Do(athena::io::PropId{"c"}, c, s); -} - -template <> -std::string_view SpawnSystemKeyframeData::DNAType() { - return "SpawnSystemKeyframeData"sv; -} -template <> -std::string_view SpawnSystemKeyframeData::DNAType() { - return "SpawnSystemKeyframeData"sv; -} - -template -void SpawnSystemKeyframeData::_read(typename ReadYaml::StreamT& r) { - if (auto rec = r.enterSubRecord("a")) - a = r.readUint32(); - if (auto rec = r.enterSubRecord("b")) - b = r.readUint32(); - if (auto rec = r.enterSubRecord("endFrame")) - endFrame = r.readUint32(); - if (auto rec = r.enterSubRecord("d")) - d = r.readUint32(); - spawns.clear(); - size_t spawnCount; - if (auto v = r.enterSubVector("spawns", spawnCount)) { - spawns.reserve(spawnCount); - for (const auto& child : r.getCurNode()->m_seqChildren) { - (void)child; - if (auto rec = r.enterSubRecord()) { - spawns.emplace_back(); - spawns.back().first = r.readUint32("startFrame"); - size_t systemCount; - if (auto v = r.enterSubVector("systems", systemCount)) { - spawns.back().second.reserve(systemCount); - for (const auto& in : r.getCurNode()->m_seqChildren) { - (void)in; - spawns.back().second.emplace_back(); - SpawnSystemKeyframeInfo& info = spawns.back().second.back(); - if (auto rec = r.enterSubRecord()) - info.read(r); - } - } - } - } - } -} - -template -void SpawnSystemKeyframeData::_write(typename WriteYaml::StreamT& w) const { - if (spawns.empty()) - return; - w.writeUint32("a", a); - w.writeUint32("b", b); - w.writeUint32("endFrame", endFrame); - w.writeUint32("d", d); - if (auto v = w.enterSubVector("spawns")) { - for (const auto& spawn : spawns) { - if (auto rec = w.enterSubRecord()) { - w.writeUint32("startFrame", spawn.first); - if (auto v = w.enterSubVector("systems")) - for (const auto& info : spawn.second) - if (auto rec = w.enterSubRecord()) - info.write(w); - } - } - } -} - -template -void SpawnSystemKeyframeData::_binarySize(typename BinarySize::StreamT& s) const { - s += 20; - for (const auto& spawn : spawns) { - s += 8; - for (const auto& info : spawn.second) - info.binarySize(s); - } -} - -template -void SpawnSystemKeyframeData::_read(typename Read::StreamT& r) { - uint32_t clsId; - r.readBytesToBuf(&clsId, 4); - if (clsId != SBIG('CNST')) - return; - - a = r.readUint32Big(); - b = r.readUint32Big(); - endFrame = r.readUint32Big(); - d = r.readUint32Big(); - uint32_t count = r.readUint32Big(); - spawns.clear(); - spawns.reserve(count); - for (size_t i = 0; i < count; ++i) { - spawns.emplace_back(); - spawns.back().first = r.readUint32Big(); - uint32_t infoCount = r.readUint32Big(); - spawns.back().second.reserve(infoCount); - for (size_t j = 0; j < infoCount; ++j) { - spawns.back().second.emplace_back(); - spawns.back().second.back().read(r); - } - } -} - -template -void SpawnSystemKeyframeData::_write(typename Write::StreamT& w) const { - if (spawns.empty()) { - w.writeBytes("NONE", 4); - return; - } - w.writeBytes("CNST", 4); - w.writeUint32Big(a); - w.writeUint32Big(b); - w.writeUint32Big(endFrame); - w.writeUint32Big(d); - w.writeUint32Big(spawns.size()); - for (const auto& spawn : spawns) { - w.writeUint32Big(spawn.first); - w.writeUint32Big(spawn.second.size()); - for (const auto& info : spawn.second) - info.write(w); - } -} - -AT_SUBSPECIALIZE_DNA_YAML(SpawnSystemKeyframeData) -AT_SUBSPECIALIZE_DNA_YAML(SpawnSystemKeyframeData) - -template struct SpawnSystemKeyframeData; -template struct SpawnSystemKeyframeData; - -template <> -std::string_view ChildResourceFactory::DNAType() { - return "ChildResourceFactory"sv; -} -template <> -std::string_view ChildResourceFactory::DNAType() { - return "ChildResourceFactory"sv; -} - -template -void ChildResourceFactory::_read(typename ReadYaml::StreamT& r) { - id.clear(); - if (auto rec = r.enterSubRecord("CNST")) - id.read(r); -} - -template -void ChildResourceFactory::_write(typename WriteYaml::StreamT& w) const { - if (id.isValid()) - if (auto rec = w.enterSubRecord("CNST")) - id.write(w); -} - -template -void ChildResourceFactory::_binarySize(typename BinarySize::StreamT& s) const { - if (id.isValid()) - id.binarySize(s); - s += 4; -} - -template -void ChildResourceFactory::_read(typename Read::StreamT& r) { - id.clear(); - uint32_t clsId; - r.readBytesToBuf(&clsId, 4); - if (clsId == SBIG('CNST')) - id.read(r); -} - -template -void ChildResourceFactory::_write(typename Write::StreamT& w) const { - if (id.isValid()) { - w.writeBytes("CNST", 4); - id.write(w); - } else - w.writeBytes("NONE", 4); -} - -AT_SUBSPECIALIZE_DNA_YAML(ChildResourceFactory) -AT_SUBSPECIALIZE_DNA_YAML(ChildResourceFactory) - -template struct ChildResourceFactory; -template struct ChildResourceFactory; - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/ParticleCommon.hpp b/DataSpec/DNACommon/ParticleCommon.hpp deleted file mode 100644 index 950c52a7b..000000000 --- a/DataSpec/DNACommon/ParticleCommon.hpp +++ /dev/null @@ -1,1553 +0,0 @@ -#pragma once - -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -#include - -namespace DataSpec::DNAParticle { -extern logvisor::Module LogModule; - -enum class ParticleType { - GPSM = SBIG('GPSM'), - SWSH = SBIG('SWSH'), - ELSM = SBIG('ELSM'), - DPSM = SBIG('DPSM'), - CRSM = SBIG('CRSM'), - WPSM = SBIG('WPSM') -}; - -/* - * The particle property (PP) metaclass system provides common compile-time utilities - * for storing, enumerating, and streaming particle scripts. - */ - -template -struct PPImpl : BigDNA, _Basis { - AT_DECL_EXPLICIT_DNA_YAML - - template - static constexpr bool _shouldStore(T& p, bool defaultBool) { - if constexpr (std::is_same_v) { - return p != defaultBool; - } else if constexpr (std::is_same_v) { - return p != 0xffffffff; - } else if constexpr (std::is_same_v) { - return true; - } else { - return p.operator bool(); - } - } - - constexpr void _read(athena::io::IStreamReader& r) { - constexpr FourCC RefType = uint32_t(_Basis::Type); - DNAFourCC clsId(r); - if (clsId != RefType) { - LogModule.report(logvisor::Warning, FMT_STRING("non {} provided to {} parser"), RefType, RefType); - return; - } - clsId.read(r); - while (clsId != SBIG('_END')) { - if (!_Basis::Lookup(clsId, [&](auto& p) { - using Tp = std::decay_t; - if constexpr (std::is_same_v) { - DNAFourCC tp(r); - if (tp == SBIG('CNST')) - p = r.readBool(); - } else if constexpr (std::is_same_v) { - DNAFourCC tp(r); - if (tp == SBIG('CNST')) - p = r.readUint32Big(); - } else if constexpr (std::is_same_v) { - DNAFourCC tp(r); - if (tp == SBIG('CNST')) - p = r.readFloatBig(); - } else { - p.read(r); - } - })) { - LogModule.report(logvisor::Fatal, FMT_STRING("Unknown {} class {} @{}"), RefType, clsId, r.position()); - } - clsId.read(r); - } - } - - constexpr void _write(athena::io::IStreamWriter& w) { - constexpr DNAFourCC RefType = uint32_t(_Basis::Type); - RefType.write(w); - _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { - if (_shouldStore(p, defaultBool)) { - using Tp = std::decay_t; - DNAFourCC(fcc).write(w); - if constexpr (std::is_same_v) { - w.writeBytes("CNST", 4); - w.writeBool(p); - } else if constexpr (std::is_same_v) { - w.writeBytes("CNST", 4); - w.writeUint32Big(p); - } else if constexpr (std::is_same_v) { - w.writeBytes("CNST", 4); - w.writeFloatBig(p); - } else { - p.write(w); - } - } - }); - w.writeBytes("_END", 4); - } - - constexpr void _binarySize(std::size_t& s) { - constexpr DNAFourCC RefType = uint32_t(_Basis::Type); - RefType.binarySize(s); - _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { - if (_shouldStore(p, defaultBool)) { - using Tp = std::decay_t; - DNAFourCC(fcc).binarySize(s); - if constexpr (std::is_same_v) { - s += 5; - } else if constexpr (std::is_same_v || std::is_same_v) { - s += 8; - } else { - p.binarySize(s); - } - } - }); - s += 4; - } - - void _read(athena::io::YAMLDocReader& r) { - constexpr DNAFourCC RefType = uint32_t(_Basis::Type); - - for (const auto& [key, value] : r.getCurNode()->m_mapChildren) { - if (key == "DNAType"sv) - continue; - if (key.size() < 4) { - LogModule.report(logvisor::Warning, FMT_STRING("short FourCC in element '{}'"), key); - continue; - } - - if (auto rec = r.enterSubRecord(key)) { - const DNAFourCC clsId = key.c_str(); - if (!_Basis::Lookup(clsId, [&](auto& p) { - using Tp = std::decay_t; - if constexpr (std::is_same_v) { - p = r.readBool(); - } else if constexpr (std::is_same_v) { - p = r.readUint32(); - } else if constexpr (std::is_same_v) { - p = r.readFloat(); - } else { - p.read(r); - } - })) { - LogModule.report(logvisor::Fatal, FMT_STRING("Unknown {} class {}"), RefType, clsId); - } - } - } - } - - constexpr void _write(athena::io::YAMLDocWriter& w) { - _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { - if (_shouldStore(p, defaultBool)) { - using Tp = std::decay_t; - if (auto rec = w.enterSubRecord(fcc.toStringView())) { - if constexpr (std::is_same_v) { - w.writeBool(p); - } else if constexpr (std::is_same_v) { - w.writeUint32(p); - } else if constexpr (std::is_same_v) { - w.writeFloat(p); - } else { - p.write(w); - } - } - } - }); - } - - constexpr void gatherDependencies(std::vector& deps) { - _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { - using Tp = std::decay_t; - if constexpr (!std::is_same_v && !std::is_same_v && !std::is_same_v) - p.gatherDependencies(deps); - }); - } - - constexpr void gatherDependencies(std::vector& deps) const { - const_cast(*this).gatherDependencies(deps); - } -}; - -template -struct PEType { - using Type = _Type; -}; - -template -struct PEImpl : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - using _PtrType = typename _Basis::PtrType; - - void _read(athena::io::IStreamReader& r) { - DNAFourCC clsId(r); - if (clsId == FOURCC('NONE')) { - m_elem.reset(); - return; - } - if (!_Basis::Lookup(clsId, [&](auto&& p) { - using Tp = std::decay_t; - m_elem = std::make_unique(); - m_elem->read(r); - })) { - LogModule.report(logvisor::Fatal, FMT_STRING("Unknown {} class {} @{}"), _PtrType::TypeName, clsId, r.position()); - } - } - - void _write(athena::io::IStreamWriter& w) { - if (m_elem) { - w.writeBytes(m_elem->ClassID().data(), 4); - m_elem->write(w); - } else { - w.writeBytes("NONE", 4); - } - } - - void _binarySize(std::size_t& s) { - if (m_elem) - m_elem->binarySize(s); - s += 4; - } - - void _read(athena::io::YAMLDocReader& r) { - const auto& mapChildren = r.getCurNode()->m_mapChildren; - if (mapChildren.empty()) { - m_elem.reset(); - return; - } - - const auto& [key, value] = mapChildren[0]; - if (key.size() < 4) - LogModule.report(logvisor::Fatal, FMT_STRING("short FourCC in element '{}'"), key); - - if (auto rec = r.enterSubRecord(key)) { - const DNAFourCC clsId = key.c_str(); - if (!_Basis::Lookup(clsId, [&](auto&& p) { - using Tp = std::decay_t; - m_elem = std::make_unique(); - m_elem->read(r); - })) { - LogModule.report(logvisor::Fatal, FMT_STRING("Unknown {} class {}"), _PtrType::TypeName, clsId); - } - } - } - - void _write(athena::io::YAMLDocWriter& w) { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); - } - - void gatherDependencies(std::vector& deps) const { _Basis::gatherDependencies(deps, m_elem); } - - explicit operator bool() const { return m_elem.operator bool(); } - auto* get() const { return m_elem.get(); } - auto* operator->() const { return get(); } - void reset() { m_elem.reset(); } - -private: - std::unique_ptr<_PtrType> m_elem; -}; - -struct IElement : BigDNAVYaml { - Delete _d; - ~IElement() override = default; - virtual std::string_view ClassID() const = 0; - std::string_view DNATypeV() const override { return ClassID(); } -}; - -struct IRealElement : IElement { - Delete _d2; - static constexpr std::string_view TypeName = "RealElement"sv; -}; -struct RELifetimeTween; -struct REConstant; -struct RETimeChain; -struct REAdd; -struct REClamp; -struct REKeyframeEmitter; -struct REKeyframeEmitter; -struct REInitialRandom; -struct RERandom; -struct REMultiply; -struct REPulse; -struct RETimeScale; -struct RELifetimePercent; -struct RESineWave; -struct REInitialSwitch; -struct RECompareLessThan; -struct RECompareEquals; -struct REParticleAdvanceParam1; -struct REParticleAdvanceParam2; -struct REParticleAdvanceParam3; -struct REParticleAdvanceParam4; -struct REParticleAdvanceParam5; -struct REParticleAdvanceParam6; -struct REParticleAdvanceParam7; -struct REParticleAdvanceParam8; -struct REParticleSizeOrLineLength; -struct REParticleRotationOrLineWidth; -struct RESubtract; -struct REVectorMagnitude; -struct REVectorXToReal; -struct REVectorYToReal; -struct REVectorZToReal; -struct RECEXT; -struct REIntTimesReal; -struct _RealElementFactory { - using PtrType = IRealElement; - template - static bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { - case SBIG('LFTW'): - f(PEType{}); - return true; - case SBIG('CNST'): - f(PEType{}); - return true; - case SBIG('CHAN'): - f(PEType{}); - return true; - case SBIG('ADD_'): - f(PEType{}); - return true; - case SBIG('CLMP'): - f(PEType{}); - return true; - case SBIG('KEYE'): - f(PEType{}); - return true; - case SBIG('KEYP'): - f(PEType{}); - return true; - case SBIG('IRND'): - f(PEType{}); - return true; - case SBIG('RAND'): - f(PEType{}); - return true; - case SBIG('MULT'): - f(PEType{}); - return true; - case SBIG('PULS'): - f(PEType{}); - return true; - case SBIG('SCAL'): - f(PEType{}); - return true; - case SBIG('RLPT'): - f(PEType{}); - return true; - case SBIG('SINE'): - f(PEType{}); - return true; - case SBIG('ISWT'): - f(PEType{}); - return true; - case SBIG('CLTN'): - f(PEType{}); - return true; - case SBIG('CEQL'): - f(PEType{}); - return true; - case SBIG('PAP1'): - f(PEType{}); - return true; - case SBIG('PAP2'): - f(PEType{}); - return true; - case SBIG('PAP3'): - f(PEType{}); - return true; - case SBIG('PAP4'): - f(PEType{}); - return true; - case SBIG('PAP5'): - f(PEType{}); - return true; - case SBIG('PAP6'): - f(PEType{}); - return true; - case SBIG('PAP7'): - f(PEType{}); - return true; - case SBIG('PAP8'): - f(PEType{}); - return true; - case SBIG('PSLL'): - f(PEType{}); - return true; - case SBIG('PRLW'): - f(PEType{}); - return true; - case SBIG('SUB_'): - f(PEType{}); - return true; - case SBIG('VMAG'): - f(PEType{}); - return true; - case SBIG('VXTR'): - f(PEType{}); - return true; - case SBIG('VYTR'): - f(PEType{}); - return true; - case SBIG('VZTR'): - f(PEType{}); - return true; - case SBIG('CEXT'): - f(PEType{}); - return true; - case SBIG('ITRL'): - f(PEType{}); - return true; - default: - return false; - } - } - static constexpr void gatherDependencies(std::vector& pathsOut, - const std::unique_ptr& elemPtr) {} -}; -using RealElementFactory = PEImpl<_RealElementFactory>; - -struct IIntElement : IElement { - Delete _d2; - static constexpr std::string_view TypeName = "IntElement"sv; -}; -struct IEKeyframeEmitter; -struct IEKeyframeEmitter; -struct IEDeath; -struct IEClamp; -struct IETimeChain; -struct IEAdd; -struct IEConstant; -struct IEImpulse; -struct IELifetimePercent; -struct IEInitialRandom; -struct IEPulse; -struct IEMultiply; -struct IESampleAndHold; -struct IERandom; -struct IETimeScale; -struct IEGTCP; -struct IEModulo; -struct IESubtract; -struct _IntElementFactory { - using PtrType = IIntElement; - template - static bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { - case SBIG('KEYE'): - f(PEType{}); - return true; - case SBIG('KEYP'): - f(PEType{}); - return true; - case SBIG('DETH'): - f(PEType{}); - return true; - case SBIG('CLMP'): - f(PEType{}); - return true; - case SBIG('CHAN'): - f(PEType{}); - return true; - case SBIG('ADD_'): - f(PEType{}); - return true; - case SBIG('CNST'): - f(PEType{}); - return true; - case SBIG('IMPL'): - f(PEType{}); - return true; - case SBIG('ILPT'): - f(PEType{}); - return true; - case SBIG('IRND'): - f(PEType{}); - return true; - case SBIG('PULS'): - f(PEType{}); - return true; - case SBIG('MULT'): - f(PEType{}); - return true; - case SBIG('SPAH'): - f(PEType{}); - return true; - case SBIG('RAND'): - f(PEType{}); - return true; - case SBIG('TSCL'): - f(PEType{}); - return true; - case SBIG('GTCP'): - f(PEType{}); - return true; - case SBIG('MODU'): - f(PEType{}); - return true; - case SBIG('SUB_'): - f(PEType{}); - return true; - default: - return false; - } - } - static constexpr void gatherDependencies(std::vector& pathsOut, - const std::unique_ptr& elemPtr) {} -}; -using IntElementFactory = PEImpl<_IntElementFactory>; - -struct IVectorElement : IElement { - Delete _d2; - static constexpr std::string_view TypeName = "VectorElement"sv; -}; -struct VECone; -struct VETimeChain; -struct VEAngleCone; -struct VEAdd; -struct VECircleCluster; -struct VEConstant; -struct VECircle; -struct VEKeyframeEmitter; -struct VEKeyframeEmitter; -struct VEMultiply; -struct VERealToVector; -struct VEPulse; -struct VEParticleVelocity; -struct VESPOS; -struct VEPLCO; -struct VEPLOC; -struct VEPSOR; -struct VEPSOF; -struct _VectorElementFactory { - using PtrType = IVectorElement; - template - static bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { - case SBIG('CONE'): - f(PEType{}); - return true; - case SBIG('CHAN'): - f(PEType{}); - return true; - case SBIG('ANGC'): - f(PEType{}); - return true; - case SBIG('ADD_'): - f(PEType{}); - return true; - case SBIG('CCLU'): - f(PEType{}); - return true; - case SBIG('CNST'): - f(PEType{}); - return true; - case SBIG('CIRC'): - f(PEType{}); - return true; - case SBIG('KEYE'): - f(PEType{}); - return true; - case SBIG('KEYP'): - f(PEType{}); - return true; - case SBIG('MULT'): - f(PEType{}); - return true; - case SBIG('RTOV'): - f(PEType{}); - return true; - case SBIG('PULS'): - f(PEType{}); - return true; - case SBIG('PVEL'): - f(PEType{}); - return true; - case SBIG('SPOS'): - f(PEType{}); - return true; - case SBIG('PLCO'): - f(PEType{}); - return true; - case SBIG('PLOC'): - f(PEType{}); - return true; - case SBIG('PSOR'): - f(PEType{}); - return true; - case SBIG('PSOF'): - f(PEType{}); - return true; - default: - return false; - } - } - static constexpr void gatherDependencies(std::vector& pathsOut, - const std::unique_ptr& elemPtr) {} -}; -using VectorElementFactory = PEImpl<_VectorElementFactory>; - -struct IColorElement : IElement { - Delete _d2; - static constexpr std::string_view TypeName = "ColorElement"sv; -}; -struct CEKeyframeEmitter; -struct CEKeyframeEmitter; -struct CEConstant; -struct CETimeChain; -struct CEFadeEnd; -struct CEFade; -struct CEPulse; -struct _ColorElementFactory { - using PtrType = IColorElement; - template - static bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { - case SBIG('KEYE'): - f(PEType{}); - return true; - case SBIG('KEYP'): - f(PEType{}); - return true; - case SBIG('CNST'): - f(PEType{}); - return true; - case SBIG('CHAN'): - f(PEType{}); - return true; - case SBIG('CFDE'): - f(PEType{}); - return true; - case SBIG('FADE'): - f(PEType{}); - return true; - case SBIG('PULS'): - f(PEType{}); - return true; - default: - return false; - } - } - static constexpr void gatherDependencies(std::vector& pathsOut, - const std::unique_ptr& elemPtr) {} -}; -using ColorElementFactory = PEImpl<_ColorElementFactory>; - -struct IModVectorElement : IElement { - Delete _d2; - static constexpr std::string_view TypeName = "ModVectorElement"sv; -}; -struct MVEImplosion; -struct MVEExponentialImplosion; -struct MVETimeChain; -struct MVEBounce; -struct MVEConstant; -struct MVEGravity; -struct MVEExplode; -struct MVESetPosition; -struct MVELinearImplosion; -struct MVEPulse; -struct MVEWind; -struct MVESwirl; -struct _ModVectorElementFactory { - using PtrType = IModVectorElement; - template - static bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { - case SBIG('IMPL'): - f(PEType{}); - return true; - case SBIG('EMPL'): - f(PEType{}); - return true; - case SBIG('CHAN'): - f(PEType{}); - return true; - case SBIG('BNCE'): - f(PEType{}); - return true; - case SBIG('CNST'): - f(PEType{}); - return true; - case SBIG('GRAV'): - f(PEType{}); - return true; - case SBIG('EXPL'): - f(PEType{}); - return true; - case SBIG('SPOS'): - f(PEType{}); - return true; - case SBIG('LMPL'): - f(PEType{}); - return true; - case SBIG('PULS'): - f(PEType{}); - return true; - case SBIG('WIND'): - f(PEType{}); - return true; - case SBIG('SWRL'): - f(PEType{}); - return true; - default: - return false; - } - } - static constexpr void gatherDependencies(std::vector& pathsOut, - const std::unique_ptr& elemPtr) {} -}; -using ModVectorElementFactory = PEImpl<_ModVectorElementFactory>; - -struct IEmitterElement : IElement { - Delete _d2; - static constexpr std::string_view TypeName = "EmitterElement"sv; -}; -struct EESimpleEmitterTR; -struct EESimpleEmitter; -struct VESphere; -struct VEAngleSphere; -struct _EmitterElementFactory { - using PtrType = IEmitterElement; - template - static bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { - case SBIG('SETR'): - f(PEType{}); - return true; - case SBIG('SEMR'): - f(PEType{}); - return true; - case SBIG('SPHE'): - f(PEType{}); - return true; - case SBIG('ASPH'): - f(PEType{}); - return true; - default: - return false; - } - } - static constexpr void gatherDependencies(std::vector& pathsOut, - const std::unique_ptr& elemPtr) {} -}; -using EmitterElementFactory = PEImpl<_EmitterElementFactory>; - -struct IUVElement : IElement { - Delete _d2; - virtual void gatherDependencies(std::vector& pathsOut) const = 0; - static constexpr std::string_view TypeName = "UVElement"sv; -}; - -struct BoolHelper : IElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - bool value = false; - explicit operator bool() const { return value; } - BoolHelper& operator=(bool val) { - value = val; - return *this; - } - std::string_view ClassID() const override { return "BoolHelper"sv; } -}; - -template -struct ValueHelper : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - - void _read(athena::io::IStreamReader& r) { - hecl::DNAFourCC ValueType; - ValueType.read(r); - if (ValueType == FOURCC('CNST')) - athena::io::Read::Do({}, value.emplace(), r); - else - value = std::nullopt; - } - void _write(athena::io::IStreamWriter& w) { - if (value) { - w.writeBytes("CNST", 4); - athena::io::Write::Do({}, *value, w); - } else { - w.writeBytes("NONE", 4); - } - } - void _binarySize(std::size_t& s) { - s += 4; - if (value) - athena::io::BinarySize::Do({}, *value, s); - } - void _read(athena::io::YAMLDocReader& r) { - athena::io::ReadYaml::Do({}, value.emplace(), r); - } - void _write(athena::io::YAMLDocWriter& w) { - athena::io::WriteYaml::Do({}, *value, w); - } - - static constexpr void gatherDependencies(std::vector& pathsOut) {} - - std::optional value = {}; - void emplace(Tp val) { value.emplace(val); } - Tp operator*() const { return *value; } - explicit operator bool() const { return value.operator bool(); } -}; - -struct RELifetimeTween : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "LFTW"sv; } -}; - -struct REConstant : IRealElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - Value val; - std::string_view ClassID() const override { return "CNST"sv; } -}; - -struct RETimeChain : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - IntElementFactory thresholdFrame; - std::string_view ClassID() const override { return "CHAN"sv; } -}; - -struct REAdd : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "ADD_"sv; } -}; - -struct REClamp : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory min; - RealElementFactory max; - RealElementFactory val; - std::string_view ClassID() const override { return "CLMP"sv; } -}; - -struct REKeyframeEmitter : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - Value percentageTween; - Value unk1; - Value loop; - Value unk2; - Value loopEnd; - Value loopStart; - Value count; - Vector keys; - std::string_view ClassID() const override { return percentageTween ? "KEYP"sv : "KEYE"sv; } -}; - -struct REInitialRandom : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "IRND"sv; } -}; - -struct RERandom : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "RAND"sv; } -}; - -struct REMultiply : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "MULT"sv; } -}; - -struct REPulse : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory aDuration; - IntElementFactory bDuration; - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "PULS"sv; } -}; - -struct RETimeScale : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory dv; - std::string_view ClassID() const override { return "SCAL"sv; } -}; - -struct RELifetimePercent : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory percent; - std::string_view ClassID() const override { return "RLPT"sv; } -}; - -struct RESineWave : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory frequency; - RealElementFactory amplitude; - RealElementFactory phase; - std::string_view ClassID() const override { return "SINE"sv; } -}; - -struct REInitialSwitch : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "ISWT"sv; } -}; - -struct RECompareLessThan : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory ca; - RealElementFactory cb; - RealElementFactory pass; - RealElementFactory fail; - std::string_view ClassID() const override { return "CLTN"sv; } -}; - -struct RECompareEquals : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory ca; - RealElementFactory cb; - RealElementFactory pass; - RealElementFactory fail; - std::string_view ClassID() const override { return "CEQL"sv; } -}; - -struct REParticleAdvanceParam1 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP1"sv; } -}; - -struct REParticleAdvanceParam2 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP2"sv; } -}; - -struct REParticleAdvanceParam3 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP3"sv; } -}; - -struct REParticleAdvanceParam4 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP4"sv; } -}; - -struct REParticleAdvanceParam5 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP5"sv; } -}; - -struct REParticleAdvanceParam6 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP6"sv; } -}; - -struct REParticleAdvanceParam7 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP7"sv; } -}; - -struct REParticleAdvanceParam8 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP8"sv; } -}; - -struct REParticleSizeOrLineLength : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PSLL"sv; } -}; - -struct REParticleRotationOrLineWidth : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PRLW"sv; } -}; - -struct RESubtract : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "SUB_"sv; } -}; - -struct REVectorMagnitude : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory vec; - std::string_view ClassID() const override { return "VMAG"sv; } -}; - -struct REVectorXToReal : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory vec; - std::string_view ClassID() const override { return "VXTR"sv; } -}; - -struct REVectorYToReal : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory vec; - std::string_view ClassID() const override { return "VYTR"sv; } -}; - -struct REVectorZToReal : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory vec; - std::string_view ClassID() const override { return "VZTR"sv; } -}; - -struct RECEXT : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory index; - std::string_view ClassID() const override { return "CEXT"sv; } -}; - -struct REIntTimesReal : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "ITRL"sv; } -}; - -struct IEKeyframeEmitter : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - Value percentageTween; - Value unk1; - Value loop; - Value unk2; - Value loopEnd; - Value loopStart; - Value count; - Vector keys; - std::string_view ClassID() const override { return percentageTween ? "KEYP"sv : "KEYE"sv; } -}; - -struct IEDeath : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory passthrough; - IntElementFactory thresholdFrame; - std::string_view ClassID() const override { return "DETH"sv; } -}; - -struct IEClamp : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory min; - IntElementFactory max; - IntElementFactory val; - std::string_view ClassID() const override { return "CLMP"sv; } -}; - -struct IETimeChain : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory a; - IntElementFactory b; - IntElementFactory thresholdFrame; - std::string_view ClassID() const override { return "CHAN"sv; } -}; - -struct IEAdd : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory a; - IntElementFactory b; - std::string_view ClassID() const override { return "ADD_"sv; } -}; - -struct IEConstant : IIntElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - Value val; - std::string_view ClassID() const override { return "CNST"sv; } -}; - -struct IEImpulse : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory val; - std::string_view ClassID() const override { return "IMPL"sv; } -}; - -struct IELifetimePercent : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory percent; - std::string_view ClassID() const override { return "ILPT"sv; } -}; - -struct IEInitialRandom : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory a; - IntElementFactory b; - std::string_view ClassID() const override { return "IRND"sv; } -}; - -struct IEPulse : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory aDuration; - IntElementFactory bDuration; - IntElementFactory a; - IntElementFactory b; - std::string_view ClassID() const override { return "PULS"sv; } -}; - -struct IEMultiply : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory a; - IntElementFactory b; - std::string_view ClassID() const override { return "MULT"sv; } -}; - -struct IESampleAndHold : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory waitMin; - IntElementFactory waitMax; - IntElementFactory val; - std::string_view ClassID() const override { return "SPAH"sv; } -}; - -struct IERandom : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory a; - IntElementFactory b; - std::string_view ClassID() const override { return "RAND"sv; } -}; - -struct IETimeScale : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory dv; - std::string_view ClassID() const override { return "TSCL"sv; } -}; - -struct IEGTCP : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "GTCP"sv; } -}; - -struct IEModulo : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory a; - IntElementFactory b; - std::string_view ClassID() const override { return "MODU"sv; } -}; - -struct IESubtract : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory direction; - IntElementFactory baseRadius; - std::string_view ClassID() const override { return "SUB_"sv; } -}; - -struct VECone : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "CONE"sv; } -}; - -struct VETimeChain : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory a; - VectorElementFactory b; - IntElementFactory thresholdFrame; - std::string_view ClassID() const override { return "CHAN"sv; } -}; - -struct VEAngleCone : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory angleXBias; - RealElementFactory angleYBias; - RealElementFactory angleXRange; - RealElementFactory angleYRange; - RealElementFactory magnitude; - std::string_view ClassID() const override { return "ANGC"sv; } -}; - -struct VEAdd : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory a; - VectorElementFactory b; - std::string_view ClassID() const override { return "ADD_"sv; } -}; - -struct VECircleCluster : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory circleOffset; - VectorElementFactory circleNormal; - IntElementFactory cycleFrames; - RealElementFactory randomFactor; - std::string_view ClassID() const override { return "CCLU"sv; } -}; - -struct VEConstant : IVectorElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - RealElementFactory comps[3]; - std::string_view ClassID() const override { return "CNST"sv; } -}; - -struct VECircle : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory circleOffset; - VectorElementFactory circleNormal; - RealElementFactory angleConstant; - RealElementFactory angleLinear; - RealElementFactory circleRadius; - std::string_view ClassID() const override { return "CIRC"sv; } -}; - -struct VEKeyframeEmitter : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - Value percentageTween; - Value unk1; - Value loop; - Value unk2; - Value loopEnd; - Value loopStart; - Value count; - Vector keys; - std::string_view ClassID() const override { return percentageTween ? "KEYP"sv : "KEYE"sv; } -}; - -struct VEMultiply : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory a; - VectorElementFactory b; - std::string_view ClassID() const override { return "MULT"sv; } -}; - -struct VERealToVector : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - std::string_view ClassID() const override { return "RTOV"sv; } -}; - -struct VEPulse : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory aDuration; - IntElementFactory bDuration; - VectorElementFactory a; - VectorElementFactory b; - std::string_view ClassID() const override { return "PULS"sv; } -}; - -struct VEParticleVelocity : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PVEL"sv; } -}; - -struct VESPOS : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory a; - std::string_view ClassID() const override { return "SPOS"sv; } -}; - -struct VEPLCO : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PLCO"sv; } -}; - -struct VEPLOC : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PLOC"sv; } -}; - -struct VEPSOR : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PSOR"sv; } -}; - -struct VEPSOF : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PSOF"sv; } -}; - -struct CEKeyframeEmitter : IColorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - Value percentageTween; - Value unk1; - Value loop; - Value unk2; - Value loopEnd; - Value loopStart; - Value count; - Vector keys; - std::string_view ClassID() const override { return percentageTween ? "KEYP"sv : "KEYE"sv; } -}; - -struct CEConstant : IColorElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - RealElementFactory comps[4]; - std::string_view ClassID() const override { return "CNST"sv; } -}; - -struct CETimeChain : IColorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - ColorElementFactory a; - ColorElementFactory b; - IntElementFactory thresholdFrame; - std::string_view ClassID() const override { return "CHAN"sv; } -}; - -struct CEFadeEnd : IColorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - ColorElementFactory a; - ColorElementFactory b; - RealElementFactory startFrame; - RealElementFactory endFrame; - std::string_view ClassID() const override { return "CFDE"sv; } -}; - -struct CEFade : IColorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - ColorElementFactory a; - ColorElementFactory b; - RealElementFactory endFrame; - std::string_view ClassID() const override { return "FADE"sv; } -}; - -struct CEPulse : IColorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory aDuration; - IntElementFactory bDuration; - ColorElementFactory a; - ColorElementFactory b; - std::string_view ClassID() const override { return "PULS"sv; } -}; - -struct MVEImplosion : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory implodePoint; - RealElementFactory velocityScale; - RealElementFactory maxRadius; - RealElementFactory minRadius; - BoolHelper enableMinRadius; - std::string_view ClassID() const override { return "IMPL"sv; } -}; - -struct MVEExponentialImplosion : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory implodePoint; - RealElementFactory velocityScale; - RealElementFactory maxRadius; - RealElementFactory minRadius; - BoolHelper enableMinRadius; - std::string_view ClassID() const override { return "EMPL"sv; } -}; - -struct MVETimeChain : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - ModVectorElementFactory a; - ModVectorElementFactory b; - IntElementFactory thresholdFrame; - std::string_view ClassID() const override { return "CHAN"sv; } -}; - -struct MVEBounce : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory planePoint; - VectorElementFactory planeNormal; - RealElementFactory friction; - RealElementFactory restitution; - BoolHelper dieOnPenetrate; - std::string_view ClassID() const override { return "BNCE"sv; } -}; - -struct MVEConstant : IModVectorElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - RealElementFactory comps[3]; - std::string_view ClassID() const override { return "CNST"sv; } -}; - -struct MVEGravity : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory acceleration; - std::string_view ClassID() const override { return "GRAV"sv; } -}; - -struct MVEExplode : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory impulseMagnitude; - RealElementFactory falloffFactor; - std::string_view ClassID() const override { return "EXPL"sv; } -}; - -struct MVESetPosition : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory position; - std::string_view ClassID() const override { return "SPOS"sv; } -}; - -struct MVELinearImplosion : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory implodePoint; - RealElementFactory velocityScale; - RealElementFactory maxRadius; - RealElementFactory minRadius; - BoolHelper enableMinRadius; - std::string_view ClassID() const override { return "LMPL"sv; } -}; - -struct MVEPulse : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory aDuration; - IntElementFactory bDuration; - ModVectorElementFactory a; - ModVectorElementFactory b; - std::string_view ClassID() const override { return "PULS"sv; } -}; - -struct MVEWind : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory windVelocity; - RealElementFactory factor; - std::string_view ClassID() const override { return "WIND"sv; } -}; - -struct MVESwirl : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory helixPoint; - VectorElementFactory curveBinormal; - RealElementFactory filterGain; - RealElementFactory tangentialVelocity; - std::string_view ClassID() const override { return "SWRL"sv; } -}; - -struct EESimpleEmitter : IEmitterElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory position; - VectorElementFactory velocity; - std::string_view ClassID() const override { return "SEMR"sv; } -}; - -struct VESphere : IEmitterElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory sphereOrigin; - RealElementFactory sphereRadius; - RealElementFactory magnitude; - std::string_view ClassID() const override { return "SPHE"sv; } -}; - -struct VEAngleSphere : IEmitterElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory sphereOrigin; - RealElementFactory angleXBias; - RealElementFactory angleYBias; - RealElementFactory angleXRange; - RealElementFactory angleYRange; - RealElementFactory sphereRadius; - RealElementFactory magnitude; - std::string_view ClassID() const override { return "ASPH"sv; } -}; - -struct EESimpleEmitterTR : EESimpleEmitter { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "SETR"sv; } -}; - -template -struct UVEConstant : IUVElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - AT_SUBDECL_DNA - CastIDToZero tex; - std::string_view ClassID() const override { return "CNST"sv; } - - void gatherDependencies(std::vector& pathsOut) const override { - if (tex.isValid()) - g_curSpec->flattenDependencies(tex, pathsOut); - } -}; - -template -struct UVEAnimTexture : IUVElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - AT_SUBDECL_DNA - CastIDToZero tex; - IntElementFactory tileW; - IntElementFactory tileH; - IntElementFactory strideW; - IntElementFactory strideH; - IntElementFactory cycleFrames; - Value loop = false; - std::string_view ClassID() const override { return "ATEX"sv; } - - void gatherDependencies(std::vector& pathsOut) const override { - if (tex.isValid()) - g_curSpec->flattenDependencies(tex, pathsOut); - } -}; - -template -struct _UVElementFactory { - using PtrType = IUVElement; - template - static bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { - case SBIG('CNST'): - f(PEType>{}); - return true; - case SBIG('ATEX'): - f(PEType>{}); - return true; - default: - return false; - } - } - static constexpr void gatherDependencies(std::vector& pathsOut, - const std::unique_ptr& elemPtr) { - if (elemPtr) - elemPtr->gatherDependencies(pathsOut); - } -}; -template -using UVElementFactory = PEImpl<_UVElementFactory>; - -template -struct SpawnSystemKeyframeData : BigDNA { - Value a; - Value b; - Value endFrame; - Value d; - - struct SpawnSystemKeyframeInfo : BigDNA { - IDType id; - Value a; - Value b; - Value c; - AT_DECL_EXPLICIT_DNA_YAML - }; - - std::vector>> spawns; - - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - - explicit operator bool() const { return spawns.size() != 0; } - - void gatherDependencies(std::vector& pathsOut) const { - for (const auto& p : spawns) - for (const SpawnSystemKeyframeInfo& info : p.second) - g_curSpec->flattenDependencies(info.id, pathsOut); - } -}; - -template -struct ChildResourceFactory : BigDNA { - IDType id; - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - explicit operator bool() const { return id.isValid(); } - void gatherDependencies(std::vector& pathsOut) const { - if (id.isValid()) - g_curSpec->flattenDependencies(id, pathsOut); - } -}; - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/RigInverter.cpp b/DataSpec/DNACommon/RigInverter.cpp deleted file mode 100644 index e1c6078ef..000000000 --- a/DataSpec/DNACommon/RigInverter.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#include "DataSpec/DNACommon/RigInverter.hpp" - -#include "DataSpec/DNAMP1/CINF.hpp" -#include "DataSpec/DNAMP2/CINF.hpp" -#include "DataSpec/DNAMP3/CINF.hpp" - -#include - -namespace DataSpec::DNAANIM { - -template -RigInverter::Bone::Bone(const CINFType& cinf, const typename CINFType::Bone& origBone) -: m_origBone(origBone) { - atUint32 parentIdx = cinf.getInternalBoneIdxFromId(origBone.parentId); - zeus::CVector3f boneOrigin(origBone.origin); - zeus::CVector3f naturalTail = boneOrigin + zeus::CVector3f{0.f, 0.5f, 0.f}; - if (parentIdx != UINT32_MAX) { - const typename CINFType::Bone& pBone = cinf.bones[parentIdx]; - m_parentDelta = boneOrigin - zeus::CVector3f(pBone.origin); - } - - size_t actualChildren = 0; - for (atUint32 chId : origBone.linked) { - if (chId == origBone.parentId) - continue; - atUint32 chIdx = cinf.getInternalBoneIdxFromId(chId); - if (chIdx != UINT32_MAX) - ++actualChildren; - } - - const std::string* bName = cinf.getBoneNameFromId(origBone.id); - bool isLCTR = false; - if (bName) - isLCTR = bName->find("_LCTR") != std::string::npos; - - if (parentIdx == UINT32_MAX) { - /* Root will always use +Y tail */ - m_tail = naturalTail; - } else if (actualChildren) { - /* Position tail to average of children */ - for (atUint32 chId : origBone.linked) { - if (chId == origBone.parentId) - continue; - atUint32 chIdx = cinf.getInternalBoneIdxFromId(chId); - if (chIdx != UINT32_MAX) { - const typename CINFType::Bone& chBone = cinf.bones[chIdx]; - m_tail += chBone.origin; - } - } - m_tail /= zeus::CVector3f(float(actualChildren)); - if ((m_tail - boneOrigin).magSquared() < 0.001f) - m_tail = naturalTail; - else if (isLCTR) - m_tail = boneOrigin + zeus::CVector3f{0.f, 1.0f, 0.f} * (m_tail - boneOrigin).magnitude(); - } else { - /* Extrapolate by delta with parent */ - m_tail = boneOrigin + m_parentDelta; - float deltaMag = m_parentDelta.magnitude(); - if (deltaMag < 0.001f) { - deltaMag = 0.5f; - m_tail = naturalTail; - } else if (deltaMag > 0.5f) { - /* Extreme bones capped to +0.5 value */ - deltaMag = 0.5f; - m_tail = boneOrigin + m_parentDelta.normalized() * 0.5f; - } - - if (isLCTR) - m_tail = boneOrigin + zeus::CVector3f{0.f, 1.0f, 0.f} * deltaMag; - } -} - -template -RigInverter::RigInverter(const CINFType& cinf) : m_cinf(cinf) { - m_bones.reserve(cinf.bones.size()); - for (const typename CINFType::Bone& b : cinf.bones) - m_bones.emplace_back(cinf, b); -} - -template -RigInverter::RigInverter(const CINFType& cinf, - const std::unordered_map& matrices) -: m_cinf(cinf) { - m_bones.reserve(cinf.bones.size()); - for (const typename CINFType::Bone& b : cinf.bones) { - m_bones.emplace_back(cinf, b); - - const std::string* name = cinf.getBoneNameFromId(b.id); - if (name) { - auto search = matrices.find(*name); - if (search != matrices.cend()) { - zeus::CMatrix3f boneMtx(search->second[0], search->second[1], search->second[2]); - m_bones.back().m_restorer = boneMtx; - m_bones.back().m_inverter = m_bones.back().m_restorer.inverse(); - } - } - } -} - -template -zeus::CQuaternion RigInverter::invertRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const { - for (const Bone& b : m_bones) - if (b.m_origBone.id == boneId) - return b.m_restorer * origRot * b.m_inverter; - return origRot; -} - -template -zeus::CVector3f RigInverter::invertPosition(atUint32 boneId, const zeus::CVector3f& origPos, - bool subDelta) const { - for (const Bone& b : m_bones) - if (b.m_origBone.id == boneId) { - zeus::CVector3f localPos = origPos; - if (subDelta) - localPos -= b.m_parentDelta; - return b.m_restorer.transform(localPos); - } - return origPos; -} - -template -zeus::CQuaternion RigInverter::restoreRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const { - for (const Bone& b : m_bones) - if (b.m_origBone.id == boneId) - return b.m_inverter * origRot * b.m_restorer; - return origRot; -} - -template -zeus::CVector3f RigInverter::restorePosition(atUint32 boneId, const zeus::CVector3f& origPos, - bool subDelta) const { - for (const Bone& b : m_bones) - if (b.m_origBone.id == boneId) { - zeus::CVector3f localPos = b.m_inverter.transform(origPos); - if (subDelta) - localPos += b.m_parentDelta; - return localPos; - } - return origPos; -} - -template class RigInverter; -template class RigInverter; - -} // namespace DataSpec::DNAANIM diff --git a/DataSpec/DNACommon/RigInverter.hpp b/DataSpec/DNACommon/RigInverter.hpp deleted file mode 100644 index 11e644ad3..000000000 --- a/DataSpec/DNACommon/RigInverter.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include -#include - -namespace DataSpec::DNAANIM { - -/** One-shot process to invert CINF armature into connected rig, - * inverting rotations/translations of ANIM data to match */ -template -class RigInverter { -public: - struct Bone { - const typename CINFType::Bone& m_origBone; - zeus::CQuaternion m_inverter; - zeus::CQuaternion m_restorer; - zeus::CVector3f m_tail; - zeus::CVector3f m_parentDelta; - Bone(const CINFType& cinf, const typename CINFType::Bone& origBone); - }; - -private: - const CINFType& m_cinf; - std::vector m_bones; - -public: - RigInverter(const CINFType& cinf); - RigInverter(const CINFType& cinf, const std::unordered_map& matrices); - const CINFType& getCINF() const { return m_cinf; } - const std::vector& getBones() const { return m_bones; } - - zeus::CQuaternion invertRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const; - zeus::CVector3f invertPosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const; - - zeus::CQuaternion restoreRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const; - zeus::CVector3f restorePosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const; -}; - -} // namespace DataSpec::DNAANIM diff --git a/DataSpec/DNACommon/SAVWCommon.hpp b/DataSpec/DNACommon/SAVWCommon.hpp deleted file mode 100644 index 5258c2ffd..000000000 --- a/DataSpec/DNACommon/SAVWCommon.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::SAVWCommon { -enum class EScanCategory { None, Data, Lore, Creature, Research, Artifact }; - -struct Header : BigDNA { - AT_DECL_DNA_YAML - Value magic; - Value version; - Value areaCount; -}; - -struct EnvironmentVariable : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unk1; - Value unk2; - Value unk3; -}; - -struct Layer : BigDNA { - AT_DECL_DNA_YAML - Value areaId; - Value layer; -}; - -template -static bool ExtractSAVW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - SAVW savw; - savw.read(rs); - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(savw, writer); - return true; -} - -} // namespace DataSpec::SAVWCommon diff --git a/DataSpec/DNACommon/STRG.cpp b/DataSpec/DNACommon/STRG.cpp deleted file mode 100644 index f6d0e6aed..000000000 --- a/DataSpec/DNACommon/STRG.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "DataSpec/DNACommon/STRG.hpp" - -#include "DataSpec/DNAMP1/STRG.hpp" -#include "DataSpec/DNAMP2/STRG.hpp" -#include "DataSpec/DNAMP3/STRG.hpp" - -#include - -namespace DataSpec { - -void ISTRG::gatherDependencies(std::vector& pathsOut) const { /* TODO: parse out resource tokens */ -} - -std::unique_ptr LoadSTRG(athena::io::IStreamReader& reader) { - uint32_t magic = reader.readUint32Big(); - if (magic != 0x87654321) { - LogDNACommon.report(logvisor::Error, FMT_STRING("invalid STRG magic")); - return {}; - } - - uint32_t version = reader.readUint32Big(); - switch (version) { - case 0: { - auto* newStrg = new DNAMP1::STRG; - newStrg->_read(reader); - return std::unique_ptr(newStrg); - } - case 1: { - auto* newStrg = new DNAMP2::STRG; - newStrg->_read(reader); - return std::unique_ptr(newStrg); - } - case 3: { - auto* newStrg = new DNAMP3::STRG; - newStrg->_read(reader); - return std::unique_ptr(newStrg); - } - default: - break; - } - return {}; -} -} // namespace DataSpec diff --git a/DataSpec/DNACommon/STRG.hpp b/DataSpec/DNACommon/STRG.hpp deleted file mode 100644 index 04fddba87..000000000 --- a/DataSpec/DNACommon/STRG.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -#include - -namespace athena::io { -class IStreamReader; -} - -namespace DataSpec { -struct ISTRG : BigDNAVYaml { - ~ISTRG() override = default; - - virtual size_t count() const = 0; - virtual std::string getUTF8(const FourCC& lang, size_t idx) const = 0; - virtual std::u16string getUTF16(const FourCC& lang, size_t idx) const = 0; - virtual int32_t lookupIdx(std::string_view name) const = 0; - - virtual void gatherDependencies(std::vector& pathsOut) const; -}; -std::unique_ptr LoadSTRG(athena::io::IStreamReader& reader); - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/SWHC.cpp b/DataSpec/DNACommon/SWHC.cpp deleted file mode 100644 index 404de21af..000000000 --- a/DataSpec/DNACommon/SWHC.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "DataSpec/DNACommon/SWHC.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAParticle { - -template struct PPImpl<_SWSH>; -template struct PPImpl<_SWSH>; - -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_SWSH>) -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_SWSH>) - -template <> -std::string_view SWSH::DNAType() { - return "SWSH"sv; -} - -template <> -std::string_view SWSH::DNAType() { - return "SWSH"sv; -} - -template -bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - SWSH swsh; - swsh.read(rs); - athena::io::ToYAMLStream(swsh, writer); - return true; - } - return false; -} -template bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteSWSH(const SWSH& swsh, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - swsh.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteSWSH(const SWSH& swsh, const hecl::ProjectPath& outPath); -template bool WriteSWSH(const SWSH& swsh, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/SWHC.def b/DataSpec/DNACommon/SWHC.def deleted file mode 100644 index 675d8b5ec..000000000 --- a/DataSpec/DNACommon/SWHC.def +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef ENTRY -#define ENTRY(name, identifier) -#endif - -#ifndef INT_ENTRY -#define INT_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef REAL_ENTRY -#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef VECTOR_ENTRY -#define VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef MOD_VECTOR_ENTRY -#define MOD_VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef COLOR_ENTRY -#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef UV_ENTRY -#define UV_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef BOOL_ENTRY -#define BOOL_ENTRY(name, identifier, def) ENTRY(name, identifier) -#endif - -INT_ENTRY('PSLT', x0_PSLT) -REAL_ENTRY('TIME', x4_TIME) -REAL_ENTRY('LRAD', x8_LRAD) -REAL_ENTRY('RRAD', xc_RRAD) -INT_ENTRY('LENG', x10_LENG) -COLOR_ENTRY('COLR', x14_COLR) -INT_ENTRY('SIDE', x18_SIDE) -REAL_ENTRY('IROT', x1c_IROT) -REAL_ENTRY('ROTM', x20_ROTM) -VECTOR_ENTRY('POFS', x24_POFS) -VECTOR_ENTRY('IVEL', x28_IVEL) -VECTOR_ENTRY('NPOS', x2c_NPOS) -MOD_VECTOR_ENTRY('VELM', x30_VELM) -MOD_VECTOR_ENTRY('VLM2', x34_VLM2) -INT_ENTRY('SPLN', x38_SPLN) -UV_ENTRY('TEXR', x3c_TEXR) -INT_ENTRY('TSPN', x40_TSPN) -BOOL_ENTRY('LLRD', x44_24_LLRD, false) -BOOL_ENTRY('CROS', x44_25_CROS, true) -BOOL_ENTRY('VLS1', x44_26_VLS1, false) -BOOL_ENTRY('VLS2', x44_27_VLS2, false) -BOOL_ENTRY('SROT', x44_28_SROT, false) -BOOL_ENTRY('WIRE', x44_29_WIRE, false) -BOOL_ENTRY('TEXW', x44_30_TEXW, false) -BOOL_ENTRY('AALP', x44_31_AALP, false) -BOOL_ENTRY('ZBUF', x45_24_ZBUF, false) -BOOL_ENTRY('ORNT', x45_25_ORNT, false) -BOOL_ENTRY('CRND', x45_26_CRND, false) - -#undef ENTRY -#undef INT_ENTRY -#undef REAL_ENTRY -#undef VECTOR_ENTRY -#undef MOD_VECTOR_ENTRY -#undef COLOR_ENTRY -#undef UV_ENTRY -#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/SWHC.hpp b/DataSpec/DNACommon/SWHC.hpp deleted file mode 100644 index 2665a56ea..000000000 --- a/DataSpec/DNACommon/SWHC.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ParticleCommon.hpp" - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAParticle { - -template -struct _SWSH { - static constexpr ParticleType Type = ParticleType::SWSH; - -#define INT_ENTRY(name, identifier) IntElementFactory identifier; -#define REAL_ENTRY(name, identifier) RealElementFactory identifier; -#define VECTOR_ENTRY(name, identifier) VectorElementFactory identifier; -#define MOD_VECTOR_ENTRY(name, identifier) ModVectorElementFactory identifier; -#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; -#define UV_ENTRY(name, identifier) UVElementFactory identifier; -#define BOOL_ENTRY(name, identifier, def) bool identifier = def; -#include "SWHC.def" - - template - void constexpr Enumerate(_Func f) { -#define ENTRY(name, identifier) f(FOURCC(name), identifier); -#define BOOL_ENTRY(name, identifier, def) f(FOURCC(name), identifier, def); -#include "SWHC.def" - } - - template - bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { -#define ENTRY(name, identifier) \ - case SBIG(name): \ - f(identifier); \ - return true; -#include "SWHC.def" - default: - return false; - } - } -}; -template -using SWSH = PPImpl<_SWSH>; - -template -bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteSWSH(const SWSH& gpsm, const hecl::ProjectPath& outPath); -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/TXTR.cpp b/DataSpec/DNACommon/TXTR.cpp deleted file mode 100644 index 12376b47a..000000000 --- a/DataSpec/DNACommon/TXTR.cpp +++ /dev/null @@ -1,1702 +0,0 @@ -#include "DataSpec/DNACommon/TXTR.hpp" - -#include -#include - -#include "DataSpec/DNACommon/PAK.hpp" - -#include -#include -#include -#include -#include - -namespace DataSpec { - -static logvisor::Module Log("libpng"); - -static int CountBits(uint32_t n) { - int ret = 0; - for (int i = 0; i < 32; ++i) { - if (((n >> i) & 1) != 0) { - ++ret; - } - } - return ret; -} - -/* Box filter algorithm (for mipmapping) */ -static void BoxFilter(const uint8_t* input, unsigned chanCount, unsigned inWidth, unsigned inHeight, uint8_t* output, - bool dxt1) { - unsigned mipWidth = 1; - unsigned mipHeight = 1; - if (inWidth > 1) { - mipWidth = inWidth / 2; - } - if (inHeight > 1) { - mipHeight = inHeight / 2; - } - - for (unsigned y = 0; y < mipHeight; ++y) { - const unsigned miplineBase = mipWidth * y; - const unsigned in1LineBase = inWidth * (y * 2); - const unsigned in2LineBase = inWidth * (y * 2 + 1); - for (unsigned x = 0; x < mipWidth; ++x) { - uint8_t* out = &output[(miplineBase + x) * chanCount]; - for (unsigned c = 0; c < chanCount; ++c) { - uint32_t tmp = 0; - tmp += input[(in1LineBase + (x * 2)) * chanCount + c]; - tmp += input[(in1LineBase + (x * 2 + 1)) * chanCount + c]; - tmp += input[(in2LineBase + (x * 2)) * chanCount + c]; - tmp += input[(in2LineBase + (x * 2 + 1)) * chanCount + c]; - out[c] = uint8_t(tmp / 4); - if (c == 3 && dxt1) { - out[c] = uint8_t(out[c] ? 0xff : 0x0); - } - } - } - } -} - -static size_t ComputeMippedTexelCount(unsigned inWidth, unsigned inHeight) { - size_t ret = 0; - while (inWidth > 0 && inHeight > 0) { - ret += inWidth * inHeight; - inWidth /= 2; - inHeight /= 2; - } - return ret; -} - -/* GX uses this upsampling technique to extract full 8-bit range */ -static constexpr uint8_t Convert3To8(uint8_t v) { - /* Swizzle bits: 00000123 -> 12312312 */ - return (v << 5) | (v << 2) | (v >> 1); -} - -static constexpr uint8_t Convert8To3(uint8_t v) { return v >> 5; } - -static constexpr uint8_t Convert4To8(uint8_t v) { - /* Swizzle bits: 00001234 -> 12341234 */ - return (v << 4) | v; -} - -static constexpr uint8_t Convert8To4(uint8_t v) { return v >> 4; } - -static constexpr uint8_t Convert5To8(uint8_t v) { - /* Swizzle bits: 00012345 -> 12345123 */ - return (v << 3) | (v >> 2); -} - -static constexpr uint8_t Convert8To5(uint8_t v) { return v >> 3; } - -static constexpr uint8_t Convert6To8(uint8_t v) { - /* Swizzle bits: 00123456 -> 12345612 */ - return (v << 2) | (v >> 4); -} - -static constexpr uint8_t Convert8To6(uint8_t v) { return v >> 2; } - -static uint8_t Lookup4BPP(const uint8_t* texels, int width, int x, int y) { - const int bwidth = (width + 7) / 8; - const int bx = x / 8; - const int by = y / 8; - const int rx = x % 8; - const int ry = y % 8; - const int bidx = by * bwidth + bx; - const uint8_t* btexels = &texels[32 * bidx]; - return btexels[ry * 4 + rx / 2] >> ((rx & 1) ? 0 : 4) & 0xf; -} - -static void Set4BPP(uint8_t* texels, int width, int x, int y, uint8_t val) { - const int bwidth = (width + 7) / 8; - const int bx = x / 8; - const int by = y / 8; - const int rx = x % 8; - const int ry = y % 8; - const int bidx = by * bwidth + bx; - uint8_t* btexels = &texels[32 * bidx]; - btexels[ry * 4 + rx / 2] |= (val & 0xf) << ((rx & 1) ? 0 : 4); -} - -static uint8_t Lookup8BPP(const uint8_t* texels, int width, int x, int y) { - int bwidth = (width + 7) / 8; - int bx = x / 8; - int by = y / 4; - int rx = x % 8; - int ry = y % 4; - int bidx = by * bwidth + bx; - const uint8_t* btexels = &texels[32 * bidx]; - return btexels[ry * 8 + rx]; -} - -static void Set8BPP(uint8_t* texels, int width, int x, int y, uint8_t val) { - const int bwidth = (width + 7) / 8; - const int bx = x / 8; - const int by = y / 4; - const int rx = x % 8; - const int ry = y % 4; - const int bidx = by * bwidth + bx; - uint8_t* btexels = &texels[32 * bidx]; - btexels[ry * 8 + rx] = val; -} - -static uint16_t Lookup16BPP(const uint8_t* texels, int width, int x, int y) { - const int bwidth = (width + 3) / 4; - const int bx = x / 4; - const int by = y / 4; - const int rx = x % 4; - const int ry = y % 4; - int bidx = by * bwidth + bx; - const uint16_t* btexels = reinterpret_cast(&texels[32 * bidx]); - return btexels[ry * 4 + rx]; -} - -static void Set16BPP(uint8_t* texels, int width, int x, int y, uint16_t val) { - const int bwidth = (width + 3) / 4; - const int bx = x / 4; - const int by = y / 4; - const int rx = x % 4; - const int ry = y % 4; - const int bidx = by * bwidth + bx; - auto* btexels = reinterpret_cast(&texels[32 * bidx]); - btexels[ry * 4 + rx] = val; -} - -static void LookupRGBA8(const uint8_t* texels, int width, int x, int y, uint8_t* r, uint8_t* g, uint8_t* b, - uint8_t* a) { - const int bwidth = (width + 3) / 4; - const int bx = x / 4; - const int by = y / 4; - const int rx = x % 4; - const int ry = y % 4; - const int bidx = (by * bwidth + bx) * 2; - const auto* artexels = reinterpret_cast(&texels[32 * bidx]); - const auto* gbtexels = reinterpret_cast(&texels[32 * (bidx + 1)]); - const uint16_t ar = hecl::SBig(artexels[ry * 4 + rx]); - *a = ar >> 8 & 0xff; - *r = ar & 0xff; - const uint16_t gb = hecl::SBig(gbtexels[ry * 4 + rx]); - *g = gb >> 8 & 0xff; - *b = gb & 0xff; -} - -static void SetRGBA8(uint8_t* texels, int width, int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - const int bwidth = (width + 3) / 4; - const int bx = x / 4; - const int by = y / 4; - const int rx = x % 4; - const int ry = y % 4; - const int bidx = (by * bwidth + bx) * 2; - uint16_t* artexels = reinterpret_cast(&texels[32 * bidx]); - uint16_t* gbtexels = reinterpret_cast(&texels[32 * (bidx + 1)]); - const uint16_t ar = (a << 8) | r; - artexels[ry * 4 + rx] = hecl::SBig(ar); - const uint16_t gb = (g << 8) | b; - gbtexels[ry * 4 + rx] = hecl::SBig(gb); -} - -static void DecodeI4(png_structp png, png_infop info, const uint8_t* texels, int width, int height) { - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - std::unique_ptr buf(new uint8_t[width]); - // memset(buf.get(), 0, width); - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - buf[x] = Convert4To8(Lookup4BPP(texels, width, x, y)); - } - png_write_row(png, buf.get()); - } -} - -#if 0 -static void EncodeI4(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) -{ - for (int y=height-1 ; y>=0 ; --y) - { - for (int x=0 ; x buf(new uint8_t[width]); - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - buf[x] = Lookup8BPP(texels, width, x, y); - } - png_write_row(png, buf.get()); - } -} - -static void EncodeI8(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) { - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - Set8BPP(texels, width, x, y, rgbaIn[x]); - } - rgbaIn += width; - } -} - -static void DecodeIA4(png_structp png, png_infop info, const uint8_t* texels, int width, int height) { - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_GRAY_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - std::unique_ptr buf(new uint8_t[width * 2]); - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - const uint8_t texel = Lookup8BPP(texels, width, x, y); - buf[x * 2] = Convert4To8(texel & 0xf); - buf[x * 2 + 1] = Convert4To8(texel >> 4 & 0xf); - } - png_write_row(png, buf.get()); - } -} - -#if 0 -static void EncodeIA4(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) -{ - for (int y=height-1 ; y>=0 ; --y) - { - for (int x=0 ; x buf(new uint16_t[width]); - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - buf[x] = hecl::SBig(Lookup16BPP(texels, width, x, y)); - } - png_write_row(png, reinterpret_cast(buf.get())); - } -} - -static void EncodeIA8(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) { - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - Set16BPP(texels, width, x, y, hecl::SBig(reinterpret_cast(rgbaIn)[x])); - } - rgbaIn += width * 2; - } -} - -static const uint8_t* DecodePalette(png_structp png, png_infop info, int numEntries, const uint8_t* data) { - const auto format = hecl::SBig(*reinterpret_cast(data)); - data += 8; - png_color cEntries[256]; - png_byte aEntries[256]; - switch (format) { - case 0: { - /* IA8 */ - for (int e = 0; e < numEntries; ++e) { - cEntries[e].red = data[e * 2]; - cEntries[e].green = data[e * 2]; - cEntries[e].blue = data[e * 2]; - aEntries[e] = data[e * 2 + 1]; - } - break; - } - case 1: { - /* RGB565 */ - const auto* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - const uint16_t texel = hecl::SBig(data16[e]); - cEntries[e].red = Convert5To8(texel >> 11 & 0x1f); - cEntries[e].green = Convert6To8(texel >> 5 & 0x3f); - cEntries[e].blue = Convert5To8(texel & 0x1f); - } - break; - } - case 2: { - /* RGB5A3 */ - const auto* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - const uint16_t texel = hecl::SBig(data16[e]); - if (texel & 0x8000) { - cEntries[e].red = Convert5To8(texel >> 10 & 0x1f); - cEntries[e].green = Convert5To8(texel >> 5 & 0x1f); - cEntries[e].blue = Convert5To8(texel & 0x1f); - aEntries[e] = 0xff; - } else { - cEntries[e].red = Convert4To8(texel >> 8 & 0xf); - cEntries[e].green = Convert4To8(texel >> 4 & 0xf); - cEntries[e].blue = Convert4To8(texel & 0xf); - aEntries[e] = Convert3To8(texel >> 12 & 0x7); - } - } - break; - } - } - png_set_PLTE(png, info, cEntries, numEntries); - if (format == 0 || format == 2) { - png_set_tRNS(png, info, aEntries, numEntries, nullptr); - } - data += numEntries * 2; - return data; -} - -static uint8_t* EncodePalette(png_structp png, png_infop info, int numEntries, uint8_t* data) { - png_colorp cEntries; - int pngNumEntries; - if (png_get_PLTE(png, info, &cEntries, &pngNumEntries) != PNG_INFO_PLTE) { - cEntries = nullptr; - pngNumEntries = 0; - } - - png_bytep aEntries; - int pngNumAEntries; - png_color_16p trans_color = nullptr; - if (png_get_tRNS(png, info, &aEntries, &pngNumAEntries, &trans_color) != PNG_INFO_tRNS) { - aEntries = nullptr; - pngNumAEntries = 0; - } - - uint32_t format = 0; /* Default IA8 */ - for (int e = 0; e < pngNumEntries; ++e) { - const png_const_colorp ent = &cEntries[e]; - if (ent->red != ent->green || ent->red != ent->blue) { - if (pngNumAEntries) { - format = 2; /* RGB565 if not greyscale and has alpha */ - } else { - format = 1; /* RGB565 if not greyscale */ - } - break; - } - } - - reinterpret_cast(data)[0] = hecl::SBig(format); - data += 4; - reinterpret_cast(data)[0] = hecl::SBig(uint16_t(numEntries)); - reinterpret_cast(data)[1] = hecl::SBig(uint16_t(1)); - data += 4; - - switch (format) { - case 0: { - /* IA8 */ - for (int e = 0; e < numEntries; ++e) { - if (e < pngNumEntries) - data[e * 2] = cEntries[e].green; - else - data[e * 2] = 0; - if (e < pngNumAEntries) - data[e * 2 + 1] = aEntries[e]; - else - data[e * 2 + 1] = 0; - } - break; - } - case 1: { - /* RGB565 */ - uint16_t* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - if (e < pngNumEntries) { - uint16_t texel = Convert8To5(cEntries[e].red) << 11; - texel |= Convert8To6(cEntries[e].green) << 5; - texel |= Convert8To5(cEntries[e].blue); - data16[e] = hecl::SBig(texel); - } else { - data16[e] = 0; - } - } - break; - } - case 2: { - /* RGB5A3 */ - auto* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - uint8_t alpha = 0; - if (e < pngNumAEntries) { - alpha = aEntries[e]; - } - - uint16_t texel = 0; - if (alpha == 0xff) { - texel |= 0x8000; - if (e < pngNumEntries) { - texel |= Convert8To5(cEntries[e].red) << 10; - texel |= Convert8To5(cEntries[e].green) << 5; - texel |= Convert8To5(cEntries[e].blue); - } - } else { - if (e < pngNumEntries) { - texel |= Convert8To4(cEntries[e].red) << 8; - texel |= Convert8To4(cEntries[e].green) << 4; - texel |= Convert8To4(cEntries[e].blue); - texel |= Convert8To3(alpha << 12); - } - } - data16[e] = hecl::SBig(texel); - } - break; - } - } - data += numEntries * 2; - return data; -} - -static const uint8_t* DecodePaletteSPLT(png_structp png, png_infop info, int numEntries, const uint8_t* data) { - const auto format = hecl::SBig(*reinterpret_cast(data)); - data += 8; - png_sPLT_entry entries[256] = {}; - png_sPLT_t GXEntry = {(char*)"GXPalette", 8, entries, numEntries}; - switch (format) { - case 0: { - /* IA8 */ - GXEntry.name = (char*)"GX_IA8"; - for (int e = 0; e < numEntries; ++e) { - entries[e].red = data[e * 2]; - entries[e].green = data[e * 2]; - entries[e].blue = data[e * 2]; - entries[e].alpha = data[e * 2 + 1]; - } - break; - } - case 1: { - /* RGB565 */ - GXEntry.name = (char*)"GX_RGB565"; - const auto* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - const uint16_t texel = hecl::SBig(data16[e]); - entries[e].red = Convert5To8(texel >> 11 & 0x1f); - entries[e].green = Convert6To8(texel >> 5 & 0x3f); - entries[e].blue = Convert5To8(texel & 0x1f); - entries[e].alpha = 0xff; - } - break; - } - case 2: { - /* RGB5A3 */ - GXEntry.name = (char*)"GX_RGB5A3"; - const auto* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - const uint16_t texel = hecl::SBig(data16[e]); - if (texel & 0x8000) { - entries[e].red = Convert5To8(texel >> 10 & 0x1f); - entries[e].green = Convert5To8(texel >> 5 & 0x1f); - entries[e].blue = Convert5To8(texel & 0x1f); - entries[e].alpha = 0xff; - } else { - entries[e].red = Convert4To8(texel >> 8 & 0xf); - entries[e].green = Convert4To8(texel >> 4 & 0xf); - entries[e].blue = Convert4To8(texel & 0xf); - entries[e].alpha = Convert3To8(texel >> 12 & 0x7); - } - } - break; - } - } - png_set_sPLT(png, info, &GXEntry, 1); - data += numEntries * 2; - return data; -} - -static uint8_t* EncodePaletteSPLT(png_structp png, png_infop info, int numEntries, uint8_t* data) { - png_sPLT_tp palettes; - const int pngNumPalettes = png_get_sPLT(png, info, &palettes); - int pngNumEntries = 0; - png_sPLT_entryp cEntries = nullptr; - for (int i = 0; i < pngNumPalettes; ++i) { - const png_const_sPLT_tp palette = &palettes[i]; - if (strncmp(palette->name, "GX_", 3) == 0) { - pngNumEntries = palette->nentries; - cEntries = palette->entries; - break; - } - } - - uint32_t format = 2; /* Default RGB5A3 */ - for (int e = 0; e < pngNumEntries; ++e) { - const png_const_sPLT_entryp ent = &cEntries[e]; - if (ent->red != ent->green || ent->red != ent->blue) { - if (ent->alpha) { - format = 2; - break; - } else { - format = 1; - } - } - } - - reinterpret_cast(data)[0] = hecl::SBig(format); - data += 4; - reinterpret_cast(data)[0] = hecl::SBig(uint16_t(1)); - reinterpret_cast(data)[1] = hecl::SBig(uint16_t(numEntries)); - data += 4; - - switch (format) { - case 0: { - /* IA8 */ - for (int e = 0; e < numEntries; ++e) { - if (e < pngNumEntries) { - data[e * 2] = cEntries[e].green; - data[e * 2 + 1] = cEntries[e].alpha; - } else { - data[e * 2] = 0; - data[e * 2 + 1] = 0; - } - } - break; - } - case 1: { - /* RGB565 */ - auto* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - if (e < pngNumEntries) { - uint16_t texel = Convert8To5(cEntries[e].red) << 11; - texel |= Convert8To6(cEntries[e].green) << 5; - texel |= Convert8To5(cEntries[e].blue); - data16[e] = hecl::SBig(texel); - } else { - data16[e] = 0; - } - } - break; - } - case 2: { - /* RGB5A3 */ - auto* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - uint16_t texel = 0; - if (cEntries && cEntries[e].alpha == 0xff) { - texel |= 0x8000; - if (e < pngNumEntries) { - texel |= Convert8To5(cEntries[e].red) << 10; - texel |= Convert8To5(cEntries[e].green) << 5; - texel |= Convert8To5(cEntries[e].blue); - } - } else { - if (e < pngNumEntries) { - texel |= Convert8To4(cEntries[e].red) << 8; - texel |= Convert8To4(cEntries[e].green) << 4; - texel |= Convert8To4(cEntries[e].blue); - texel |= Convert8To3(cEntries[e].alpha << 12); - } - } - data16[e] = hecl::SBig(texel); - } - break; - } - } - data += numEntries * 2; - return data; -} - -static const png_color C4Colors[] = { - {0, 0, 0}, {155, 0, 0}, {0, 155, 0}, {0, 0, 155}, {155, 155, 0}, {155, 0, 155}, {0, 155, 155}, {155, 155, 155}, - {55, 55, 55}, {255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 0}, {255, 0, 255}, {0, 255, 255}, {255, 255, 255}}; - -static void C4Palette(png_structp png, png_infop info) { png_set_PLTE(png, info, C4Colors, 16); } - -static void DecodeC4(png_structp png, png_infop info, const uint8_t* data, int width, int height) { - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - C4Palette(png, info); - const uint8_t* texels = DecodePaletteSPLT(png, info, 16, data); - png_write_info(png, info); - std::unique_ptr buf(new uint8_t[width]); - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - buf[x] = Lookup4BPP(texels, width, x, y); - } - png_write_row(png, buf.get()); - } -} - -static void EncodeC4(png_structp png, png_infop info, const uint8_t* rgbaIn, uint8_t* data, int width, int height) { - uint8_t* texels = EncodePaletteSPLT(png, info, 16, data); - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - Set4BPP(texels, width, x, y, rgbaIn[x]); - } - rgbaIn += width; - } -} - -static void DecodeC8(png_structp png, png_infop info, const uint8_t* data, int width, int height) { - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - const uint8_t* texels = DecodePalette(png, info, 256, data); - png_write_info(png, info); - std::unique_ptr buf(new uint8_t[width]); - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - buf[x] = Lookup8BPP(texels, width, x, y); - } - png_write_row(png, buf.get()); - } -} - -static void EncodeC8(png_structp png, png_infop info, const uint8_t* rgbaIn, uint8_t* data, int width, int height) { - uint8_t* texels = EncodePalette(png, info, 256, data); - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - Set8BPP(texels, width, x, y, rgbaIn[x]); - } - rgbaIn += width; - } -} - -static void DecodeRGB565(png_structp png, png_infop info, const uint8_t* texels, int width, int height) { - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - std::unique_ptr buf(new uint8_t[width * 3]); - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - const uint16_t texel = hecl::SBig(Lookup16BPP(texels, width, x, y)); - buf[x * 3] = Convert5To8(texel >> 11 & 0x1f); - buf[x * 3 + 1] = Convert6To8(texel >> 5 & 0x3f); - buf[x * 3 + 2] = Convert5To8(texel & 0x1f); - } - png_write_row(png, buf.get()); - } -} - -#if 0 -static void EncodeRGB565(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) -{ - for (int y=height-1 ; y>=0 ; --y) - { - for (int x=0 ; x buf(new uint8_t[width * 4]); - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - const uint16_t texel = hecl::SBig(Lookup16BPP(texels, width, x, y)); - if (texel & 0x8000) { - buf[x * 4] = Convert5To8(texel >> 10 & 0x1f); - buf[x * 4 + 1] = Convert5To8(texel >> 5 & 0x1f); - buf[x * 4 + 2] = Convert5To8(texel & 0x1f); - buf[x * 4 + 3] = 0xff; - } else { - buf[x * 4] = Convert4To8(texel >> 8 & 0xf); - buf[x * 4 + 1] = Convert4To8(texel >> 4 & 0xf); - buf[x * 4 + 2] = Convert4To8(texel & 0xf); - buf[x * 4 + 3] = Convert3To8(texel >> 12 & 0x7); - } - } - png_write_row(png, buf.get()); - } -} - -#if 0 -static void EncodeRGB5A3(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) -{ - for (int y=height-1 ; y>=0 ; --y) - { - for (int x=0 ; x buf(new uint8_t[width * 4]); - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - LookupRGBA8(texels, width, x, y, &buf[x * 4], &buf[x * 4 + 1], &buf[x * 4 + 2], &buf[x * 4 + 3]); - } - png_write_row(png, buf.get()); - } -} - -static void EncodeRGBA8(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) { - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - SetRGBA8(texels, width, x, y, rgbaIn[x * 4], rgbaIn[x * 4 + 1], rgbaIn[x * 4 + 2], rgbaIn[x * 4 + 3]); - } - rgbaIn += width * 4; - } -} - -struct DXTBlock { - uint16_t color1; - uint16_t color2; - uint8_t lines[4]; -}; - -static void DecodeCMPR(png_structp png, png_infop info, const uint8_t* texels, int width, int height) { - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - - /* Decode 8 rows at a time */ - const int bwidth = (width + 7) / 8; - const int bpwidth = bwidth * 8; - std::unique_ptr buf(new uint32_t[bpwidth * 8]); - uint32_t* bTargets[4] = {buf.get(), buf.get() + 4, buf.get() + 4 * width, buf.get() + 4 * width + 4}; - for (int y = height / 8 - 1; y >= 0; --y) { - const auto* blks = reinterpret_cast(texels + 32 * bwidth * y); - for (int x = 0; x < width; x += 8) { - uint32_t blkOut[4][4][4]; - squish::Decompress(reinterpret_cast(blkOut[0][0]), blks++, squish::kDxt1GCN); - squish::Decompress(reinterpret_cast(blkOut[1][0]), blks++, squish::kDxt1GCN); - squish::Decompress(reinterpret_cast(blkOut[2][0]), blks++, squish::kDxt1GCN); - squish::Decompress(reinterpret_cast(blkOut[3][0]), blks++, squish::kDxt1GCN); - - for (int bt = 0; bt < 4; ++bt) { - for (int by = 0; by < 4; ++by) { - std::memcpy(bTargets[bt] + x + width * by, blkOut[bt][by], 16); - } - } - } - for (int r = 7; r >= 0; --r) { - png_write_row(png, reinterpret_cast(bTargets[0] + width * r)); - } - } -} - -static void EncodeCMPR(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) { - /* Encode 8 rows at a time */ - const int bwidth = (width + 7) / 8; - const int bpwidth = bwidth * 8; - std::unique_ptr buf(new uint32_t[bpwidth * 8]); - uint32_t* bTargets[4] = {buf.get(), buf.get() + 4, buf.get() + 4 * width, buf.get() + 4 * width + 4}; - for (int y = height / 8 - 1; y >= 0; --y) { - for (int r = 7; r >= 0; --r) { - std::memcpy(bTargets[0] + width * r, rgbaIn, width * 4); - rgbaIn += width * 4; - } - auto* blks = reinterpret_cast(texels + 32 * bwidth * y); - for (int x = 0; x < width; x += 8) { - uint32_t blkIn[4][4][4]; - for (int bt = 0; bt < 4; ++bt) { - for (int by = 0; by < 4; ++by) { - std::memcpy(blkIn[bt][by], bTargets[bt] + x + width * by, 16); - } - } - - squish::Compress(reinterpret_cast(blkIn[0][0]), blks++, squish::kDxt1GCN); - squish::Compress(reinterpret_cast(blkIn[1][0]), blks++, squish::kDxt1GCN); - squish::Compress(reinterpret_cast(blkIn[2][0]), blks++, squish::kDxt1GCN); - squish::Compress(reinterpret_cast(blkIn[3][0]), blks++, squish::kDxt1GCN); - } - } -} - -static void PNGErr(png_structp png, png_const_charp msg) { Log.report(logvisor::Error, FMT_STRING("{}"), msg); } - -static void PNGWarn(png_structp png, png_const_charp msg) { Log.report(logvisor::Warning, FMT_STRING("{}"), msg); } - -bool TXTR::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - const uint32_t format = rs.readUint32Big(); - const uint16_t width = rs.readUint16Big(); - const uint16_t height = rs.readUint16Big(); - const uint32_t numMips = rs.readUint32Big(); - - auto fp = hecl::FopenUnique(outPath.getAbsolutePath().data(), "wb"); - if (fp == nullptr) { - Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for writing"), outPath.getAbsolutePath()); - return false; - } - png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, PNGErr, PNGWarn); - png_init_io(png, fp.get()); - png_infop info = png_create_info_struct(png); - - png_text textStruct = {}; - textStruct.key = png_charp("metaforce_nomip"); - if (numMips == 1) - png_set_text(png, info, &textStruct, 1); - - switch (format) { - case 0: - DecodeI4(png, info, rs.data() + 12, width, height); - break; - case 1: - DecodeI8(png, info, rs.data() + 12, width, height); - break; - case 2: - DecodeIA4(png, info, rs.data() + 12, width, height); - break; - case 3: - DecodeIA8(png, info, rs.data() + 12, width, height); - break; - case 4: - DecodeC4(png, info, rs.data() + 12, width, height); - break; - case 5: - DecodeC8(png, info, rs.data() + 12, width, height); - break; - case 7: - DecodeRGB565(png, info, rs.data() + 12, width, height); - break; - case 8: - DecodeRGB5A3(png, info, rs.data() + 12, width, height); - break; - case 9: - DecodeRGBA8(png, info, rs.data() + 12, width, height); - break; - case 10: - DecodeCMPR(png, info, rs.data() + 12, width, height); - break; - } - - png_write_end(png, info); - png_write_flush(png); - png_destroy_write_struct(&png, &info); - - return true; -} - -static std::unique_ptr ReadPalette(png_structp png, png_infop info, size_t& szOut) { - std::unique_ptr ret; - png_sPLT_tp palettes; - const int paletteCount = png_get_sPLT(png, info, &palettes); - if (paletteCount != 0) { - for (int i = 0; i < paletteCount; ++i) { - const png_const_sPLT_tp palette = &palettes[i]; - if (strncmp(palette->name, "GX_", 3) == 0) { - if (palette->nentries > 16) { - /* This is a C8 palette */ - ret.reset(new uint8_t[4 * 257]); - szOut = 4 * 257; - *reinterpret_cast(ret.get()) = hecl::SBig(256); - uint8_t* cur = ret.get() + 4; - for (int j = 0; j < 256; ++j) { - if (j < palette->nentries) { - const png_const_sPLT_entryp entry = &palette->entries[j]; - if (palette->depth == 16) { - *cur++ = entry->red >> 8; - *cur++ = entry->green >> 8; - *cur++ = entry->blue >> 8; - *cur++ = entry->alpha >> 8; - } else { - *cur++ = entry->red; - *cur++ = entry->green; - *cur++ = entry->blue; - *cur++ = entry->alpha; - } - } else { - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - } - } - } else { - /* This is a C4 palette */ - ret.reset(new uint8_t[4 * 17]); - szOut = 4 * 17; - *reinterpret_cast(ret.get()) = hecl::SBig(16); - uint8_t* cur = ret.get() + 4; - for (int j = 0; j < 16; ++j) { - if (j < palette->nentries) { - const png_const_sPLT_entryp entry = &palette->entries[j]; - if (palette->depth == 16) { - *cur++ = entry->red >> 8; - *cur++ = entry->green >> 8; - *cur++ = entry->blue >> 8; - *cur++ = entry->alpha >> 8; - } else { - *cur++ = entry->red; - *cur++ = entry->green; - *cur++ = entry->blue; - *cur++ = entry->alpha; - } - } else { - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - } - } - } - break; - } - } - } else { - png_colorp palettes2; - int colorCount; - if (png_get_PLTE(png, info, &palettes2, &colorCount) == PNG_INFO_PLTE) { - if (colorCount > 16) { - /* This is a C8 palette */ - ret.reset(new uint8_t[4 * 257]); - szOut = 4 * 257; - *reinterpret_cast(ret.get()) = hecl::SBig(256); - uint8_t* cur = ret.get() + 4; - for (int j = 0; j < 256; ++j) { - if (j < colorCount) { - const png_const_colorp entry = &palettes2[j]; - *cur++ = entry->red; - *cur++ = entry->green; - *cur++ = entry->blue; - *cur++ = 0xff; - } else { - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - } - } - } else { - /* This is a C4 palette */ - ret.reset(new uint8_t[4 * 17]); - szOut = 4 * 17; - *reinterpret_cast(ret.get()) = hecl::SBig(16); - uint8_t* cur = ret.get() + 4; - for (int j = 0; j < 16; ++j) { - if (j < colorCount) { - const png_const_colorp entry = &palettes2[j]; - *cur++ = entry->red; - *cur++ = entry->green; - *cur++ = entry->blue; - *cur++ = 0xff; - } else { - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - } - } - } - } - } - return ret; -} - -static int GetNumPaletteEntriesForGCN(png_structp png, png_infop info) { - png_sPLT_tp palettes; - const int paletteCount = png_get_sPLT(png, info, &palettes); - if (paletteCount != 0) { - for (int i = 0; i < paletteCount; ++i) { - const png_const_sPLT_tp palette = &palettes[i]; - if (strncmp(palette->name, "GX_", 3) == 0) { - if (palette->nentries > 16) { - /* This is a C8 palette */ - return 256; - } else { - /* This is a C4 palette */ - return 16; - } - } - } - } else { - png_colorp palletes2; - int colorCount; - if (png_get_PLTE(png, info, &palletes2, &colorCount) == PNG_INFO_PLTE) { - if (colorCount > 16) { - /* This is a C8 palette */ - return 256; - } else { - /* This is a C4 palette */ - return 16; - } - } - } - return 0; -} - -bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - auto inf = hecl::FopenUnique(inPath.getAbsolutePath().data(), "rb"); - if (inf == nullptr) { - Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for reading"), inPath.getAbsolutePath()); - return false; - } - - /* Validate PNG */ - char header[8]; - std::fread(header, 1, sizeof(header), inf.get()); - if (png_sig_cmp((png_const_bytep)header, 0, 8)) { - Log.report(logvisor::Error, FMT_STRING("invalid PNG signature in '{}'"), inPath.getAbsolutePath()); - return false; - } - - /* Setup PNG reader */ - png_structp pngRead = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!pngRead) { - Log.report(logvisor::Error, FMT_STRING("unable to initialize libpng")); - return false; - } - png_infop info = png_create_info_struct(pngRead); - if (!info) { - Log.report(logvisor::Error, FMT_STRING("unable to initialize libpng info")); - png_destroy_read_struct(&pngRead, nullptr, nullptr); - return false; - } - - if (setjmp(png_jmpbuf(pngRead))) { - Log.report(logvisor::Error, FMT_STRING("unable to initialize libpng I/O for '{}'"), - inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - png_init_io(pngRead, inf.get()); - png_set_sig_bytes(pngRead, 8); - - png_read_info(pngRead, info); - - const png_uint_32 width = png_get_image_width(pngRead, info); - const png_uint_32 height = png_get_image_height(pngRead, info); - const png_byte colorType = png_get_color_type(pngRead, info); - const png_byte bitDepth = png_get_bit_depth(pngRead, info); - - if (width < 4 || height < 4) { - Log.report(logvisor::Error, FMT_STRING("image must be 4x4 or larger")); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - /* Disable mipmapping if metaforce_nomip embedded */ - bool mipmap = true; - png_text* textStruct; - int numText; - png_get_text(pngRead, info, &textStruct, &numText); - for (int i = 0; i < numText; ++i) { - if (std::strcmp(textStruct[i].key, "metaforce_nomip") == 0) { - mipmap = false; - } - } - if (colorType == PNG_COLOR_TYPE_PALETTE) { - mipmap = false; - } - - /* Compute mipmap levels */ - size_t numMips = 1; - if (mipmap && CountBits(width) == 1 && CountBits(height) == 1) { - size_t index = std::min(width, height); - while (index >>= 1) { - ++numMips; - } - } - - if (bitDepth != 8) { - Log.report(logvisor::Error, FMT_STRING("'{}' is not 8 bits-per-channel"), inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - size_t rowSize = 0; - size_t nComps = 4; - int nPaletteEntries = 0; - switch (colorType) { - case PNG_COLOR_TYPE_GRAY: - rowSize = width; - nComps = 1; - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - rowSize = width * 2; - nComps = 2; - break; - case PNG_COLOR_TYPE_RGB: - rowSize = width * 3; - nComps = 4; - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - rowSize = width * 4; - nComps = 4; - break; - case PNG_COLOR_TYPE_PALETTE: - nPaletteEntries = GetNumPaletteEntriesForGCN(pngRead, info); - rowSize = width; - nComps = 1; - break; - default: - Log.report(logvisor::Error, FMT_STRING("unsupported color type in '{}'"), inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - /* Intermediate row-read buf (file components) */ - std::unique_ptr rowBuf; - if (colorType == PNG_COLOR_TYPE_RGB) - rowBuf.reset(new uint8_t[rowSize]); - - /* Final mipmapped buf (RGBA components) */ - std::unique_ptr bufOut; - size_t bufLen = 0; - if (numMips > 1) - bufLen = ComputeMippedTexelCount(width, height) * nComps; - else - bufLen = width * height * nComps; - bufOut.reset(new uint8_t[bufLen]); - - if (setjmp(png_jmpbuf(pngRead))) { - Log.report(logvisor::Fatal, FMT_STRING("unable to read image in '{}'"), inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - /* Track alpha values for DXT1 eligibility */ - bool doDXT1 = (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_RGB_ALPHA) && width >= 4 && height >= 4; - - /* Read into mip0 image buffer */ - for (png_uint_32 r = 0; r < height; ++r) { - if (colorType == PNG_COLOR_TYPE_RGB) { - png_read_row(pngRead, rowBuf.get(), nullptr); - for (unsigned i = 0; i < width; ++i) { - const size_t inbase = i * 3; - const size_t outbase = (r * width + i) * 4; - bufOut[outbase] = rowBuf[inbase]; - bufOut[outbase + 1] = rowBuf[inbase + 1]; - bufOut[outbase + 2] = rowBuf[inbase + 2]; - bufOut[outbase + 3] = 0xff; - } - } else { - png_read_row(pngRead, &bufOut[(r * width) * nComps], nullptr); - if (colorType == PNG_COLOR_TYPE_RGB_ALPHA) { - for (unsigned i = 0; i < width; ++i) { - const size_t outbase = (r * width + i) * nComps; - if (bufOut[outbase + 3] != 0 && bufOut[outbase + 3] != 255) { - doDXT1 = false; - } - } - } - } - } - - png_destroy_read_struct(&pngRead, &info, nullptr); - inf.reset(); - - /* Reduce mipmaps to minimum allowed dimensions */ - unsigned minDimX, minDimY; - if (doDXT1) { - minDimX = minDimY = 4; - } else { - switch (colorType) { - case PNG_COLOR_TYPE_GRAY: - minDimX = 8; - minDimY = 4; - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - default: - minDimX = 4; - minDimY = 4; - break; - case PNG_COLOR_TYPE_PALETTE: { - if (nPaletteEntries == 256) { - minDimX = 8; - minDimY = 4; - } else { - minDimX = minDimY = 8; - } - break; - } - } - } - { - unsigned totalPixels = 0; - unsigned filterWidth = width; - unsigned filterHeight = height; - for (size_t i = 0; i < numMips; ++i) { - totalPixels += filterWidth * filterHeight; - if (filterWidth == minDimX || filterHeight == minDimY) { - numMips = i + 1; - break; - } - filterWidth /= 2; - filterHeight /= 2; - } - bufLen = totalPixels * nComps; - } - - /* Perform box-filter mipmap */ - std::unique_ptr compOut; - size_t compLen = 0; - if (numMips > 1) { - const uint8_t* filterIn = bufOut.get(); - uint8_t* filterOut = bufOut.get() + width * height * nComps; - unsigned filterWidth = width; - unsigned filterHeight = height; - for (size_t i = 1; i < numMips; ++i) { - BoxFilter(filterIn, nComps, filterWidth, filterHeight, filterOut, doDXT1); - filterIn += filterWidth * filterHeight * nComps; - filterWidth /= 2; - filterHeight /= 2; - filterOut += filterWidth * filterHeight * nComps; - } - } - - /* Do DXT1 compression */ - int format; - if (doDXT1) { - int filterWidth = width; - int filterHeight = height; - for (size_t i = 0; i < numMips; ++i) { - compLen += squish::GetStorageRequirements(filterWidth, filterHeight, squish::kDxt1); - if (filterWidth == 8 || filterHeight == 8) { - numMips = i + 1; - break; - } - filterWidth /= 2; - filterHeight /= 2; - } - - compOut.reset(new uint8_t[compLen]); - - filterWidth = width; - filterHeight = height; - const uint8_t* rgbaIn = bufOut.get(); - uint8_t* blocksOut = compOut.get(); - std::memset(blocksOut, 0, compLen); - for (size_t i = 0; i < numMips; ++i) { - const int thisLen = squish::GetStorageRequirements(filterWidth, filterHeight, squish::kDxt1); - EncodeCMPR(rgbaIn, blocksOut, filterWidth, filterHeight); - rgbaIn += filterWidth * filterHeight * nComps; - blocksOut += thisLen; - filterWidth /= 2; - filterHeight /= 2; - } - - format = 10; - } else { - int filterWidth = width; - int filterHeight = height; - compLen = bufLen; - if (colorType == PNG_COLOR_TYPE_PALETTE) { - if (nPaletteEntries == 16) { - compLen /= 2; - } - compLen += 8 + nPaletteEntries * 2; - } - compOut.reset(new uint8_t[compLen]); - const uint8_t* rgbaIn = bufOut.get(); - uint8_t* dataOut = compOut.get(); - std::memset(dataOut, 0, compLen); - for (size_t i = 0; i < numMips; ++i) { - switch (colorType) { - case PNG_COLOR_TYPE_GRAY: - EncodeI8(rgbaIn, dataOut, filterWidth, filterHeight); - format = 1; - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - EncodeIA8(rgbaIn, dataOut, filterWidth, filterHeight); - format = 3; - break; - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - EncodeRGBA8(rgbaIn, dataOut, filterWidth, filterHeight); - format = 9; - break; - case PNG_COLOR_TYPE_PALETTE: { - if (nPaletteEntries == 256) { - EncodeC8(pngRead, info, rgbaIn, dataOut, filterWidth, filterHeight); - format = 5; - } else { - EncodeC4(pngRead, info, rgbaIn, dataOut, filterWidth, filterHeight); - format = 4; - } - break; - } - default: - break; - } - rgbaIn += filterWidth * filterHeight * nComps; - dataOut += filterWidth * filterHeight * nComps; - filterWidth /= 2; - filterHeight /= 2; - } - } - - /* Do write out */ - athena::io::FileWriter outf(outPath.getAbsolutePath(), true, false); - if (outf.hasError()) { - Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for writing"), outPath.getAbsolutePath()); - return false; - } - - outf.writeInt32Big(format); - outf.writeInt16Big(width); - outf.writeInt16Big(height); - outf.writeInt32Big(numMips); - outf.writeUBytes(compOut.get(), compLen); - - return true; -} - -bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - auto inf = hecl::FopenUnique(inPath.getAbsolutePath().data(), "rb"); - if (inf == nullptr) { - Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for reading"), inPath.getAbsolutePath()); - return false; - } - - /* Validate PNG */ - char header[8]; - std::fread(header, 1, sizeof(header), inf.get()); - if (png_sig_cmp((png_const_bytep)header, 0, 8)) { - Log.report(logvisor::Error, FMT_STRING("invalid PNG signature in '{}'"), inPath.getAbsolutePath()); - return false; - } - - /* Setup PNG reader */ - png_structp pngRead = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!pngRead) { - Log.report(logvisor::Error, FMT_STRING("unable to initialize libpng")); - return false; - } - png_infop info = png_create_info_struct(pngRead); - if (!info) { - Log.report(logvisor::Error, FMT_STRING("unable to initialize libpng info")); - png_destroy_read_struct(&pngRead, nullptr, nullptr); - return false; - } - - if (setjmp(png_jmpbuf(pngRead))) { - Log.report(logvisor::Error, FMT_STRING("unable to initialize libpng I/O for '{}'"), - inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - png_init_io(pngRead, inf.get()); - png_set_sig_bytes(pngRead, 8); - - png_read_info(pngRead, info); - - const png_uint_32 width = png_get_image_width(pngRead, info); - const png_uint_32 height = png_get_image_height(pngRead, info); - const png_byte colorType = png_get_color_type(pngRead, info); - const png_byte bitDepth = png_get_bit_depth(pngRead, info); - - /* Disable mipmapping if metaforce_nomip embedded */ - bool mipmap = true; - png_text* textStruct; - int numText; - png_get_text(pngRead, info, &textStruct, &numText); - for (int i = 0; i < numText; ++i) { - if (std::strcmp(textStruct[i].key, "metaforce_nomip") == 0) { - mipmap = false; - } - } - if (colorType == PNG_COLOR_TYPE_PALETTE) { - mipmap = false; - } - - /* Compute mipmap levels */ - size_t numMips = 1; - if (mipmap && CountBits(width) == 1 && CountBits(height) == 1) { - size_t index = std::min(width, height); - while (index >>= 1) { - ++numMips; - } - } - - if (bitDepth != 8) { - Log.report(logvisor::Error, FMT_STRING("'{}' is not 8 bits-per-channel"), inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - std::unique_ptr paletteBuf; - size_t paletteSize = 0; - - size_t rowSize = 0; - size_t nComps = 4; - switch (colorType) { - case PNG_COLOR_TYPE_GRAY: - rowSize = width; - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - rowSize = width * 2; - break; - case PNG_COLOR_TYPE_RGB: - rowSize = width * 3; - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - rowSize = width * 4; - break; - case PNG_COLOR_TYPE_PALETTE: - rowSize = width; - nComps = 1; - paletteBuf = ReadPalette(pngRead, info, paletteSize); - break; - default: - Log.report(logvisor::Error, FMT_STRING("unsupported color type in '{}'"), inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - /* Intermediate row-read buf (file components) */ - std::unique_ptr rowBuf(new uint8_t[rowSize]); - - /* Final mipmapped buf (RGBA components) */ - std::unique_ptr bufOut; - size_t bufLen = 0; - if (numMips > 1) - bufLen = ComputeMippedTexelCount(width, height) * nComps; - else - bufLen = width * height * nComps; - bufOut.reset(new uint8_t[bufLen]); - - if (setjmp(png_jmpbuf(pngRead))) { - Log.report(logvisor::Fatal, FMT_STRING("unable to read image in '{}'"), inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - /* Track alpha values for DXT1 eligibility */ - bool doDXT = (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_RGB_ALPHA) && width >= 4 && height >= 4; - bool doDXT3 = false; - - /* Read and make RGBA */ - for (int r = height - 1; r >= 0; --r) { - png_read_row(pngRead, rowBuf.get(), nullptr); - switch (colorType) { - case PNG_COLOR_TYPE_GRAY: - for (unsigned i = 0; i < width; ++i) { - const size_t outbase = (r * width + i) * 4; - bufOut[outbase] = rowBuf[i]; - bufOut[outbase + 1] = rowBuf[i]; - bufOut[outbase + 2] = rowBuf[i]; - bufOut[outbase + 3] = rowBuf[i]; - } - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - for (unsigned i = 0; i < width; ++i) { - const size_t inbase = i * 2; - const size_t outbase = (r * width + i) * 4; - bufOut[outbase] = rowBuf[inbase]; - bufOut[outbase + 1] = rowBuf[inbase]; - bufOut[outbase + 2] = rowBuf[inbase]; - bufOut[outbase + 3] = rowBuf[inbase + 1]; - } - break; - case PNG_COLOR_TYPE_RGB: - for (unsigned i = 0; i < width; ++i) { - const size_t inbase = i * 3; - const size_t outbase = (r * width + i) * 4; - bufOut[outbase] = rowBuf[inbase]; - bufOut[outbase + 1] = rowBuf[inbase + 1]; - bufOut[outbase + 2] = rowBuf[inbase + 2]; - bufOut[outbase + 3] = 0xff; - } - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - for (unsigned i = 0; i < width; ++i) { - const size_t inbase = i * 4; - const size_t outbase = (r * width + i) * 4; - bufOut[outbase] = rowBuf[inbase]; - bufOut[outbase + 1] = rowBuf[inbase + 1]; - bufOut[outbase + 2] = rowBuf[inbase + 2]; - bufOut[outbase + 3] = rowBuf[inbase + 3]; - if (rowBuf[inbase + 3] != 0 && rowBuf[inbase + 3] != 255) - doDXT = false; - else if (rowBuf[inbase + 3] == 0) - doDXT3 = true; - } - break; - case PNG_COLOR_TYPE_PALETTE: - for (unsigned i = 0; i < width; ++i) - bufOut[r * width + i] = rowBuf[i]; - break; - default: - break; - } - } - - png_destroy_read_struct(&pngRead, &info, nullptr); - inf.reset(); - - /* Perform box-filter mipmap */ - if (numMips > 1) { - const uint8_t* filterIn = bufOut.get(); - uint8_t* filterOut = bufOut.get() + width * height * nComps; - unsigned filterWidth = width; - unsigned filterHeight = height; - for (size_t i = 1; i < numMips; ++i) { - BoxFilter(filterIn, nComps, filterWidth, filterHeight, filterOut, doDXT); - filterIn += filterWidth * filterHeight * nComps; - filterWidth /= 2; - filterHeight /= 2; - filterOut += filterWidth * filterHeight * nComps; - } - } - - /* Do DXT compression */ - std::unique_ptr compOut; - size_t compLen = 0; - if (doDXT) { - int compFlags = doDXT3 ? squish::kDxt3 : squish::kDxt1; - int filterWidth = width; - int filterHeight = height; - size_t i; - for (i = 0; i < numMips; ++i) { - compLen += squish::GetStorageRequirements(filterWidth, filterHeight, compFlags); - if (filterWidth == 4 || filterHeight == 4) { - ++i; - break; - } - filterWidth /= 2; - filterHeight /= 2; - } - numMips = i; - - compOut.reset(new uint8_t[compLen]); - - filterWidth = width; - filterHeight = height; - const uint8_t* rgbaIn = bufOut.get(); - uint8_t* blocksOut = compOut.get(); - for (i = 0; i < numMips; ++i) { - const int thisLen = squish::GetStorageRequirements(filterWidth, filterHeight, compFlags); - squish::CompressImage(rgbaIn, filterWidth, filterHeight, blocksOut, compFlags); - rgbaIn += filterWidth * filterHeight * nComps; - blocksOut += thisLen; - filterWidth /= 2; - filterHeight /= 2; - } - } - - /* Do write out */ - athena::io::FileWriter outf(outPath.getAbsolutePath(), true, false); - if (outf.hasError()) { - Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for writing"), outPath.getAbsolutePath()); - return false; - } - - int format; - if (paletteBuf && paletteSize) - format = 17; - else if (compOut) - format = doDXT3 ? 19 : 18; - else - format = 16; - outf.writeInt32Big(format); - outf.writeInt16Big(width); - outf.writeInt16Big(height); - outf.writeInt32Big(numMips); - if (paletteBuf && paletteSize) - outf.writeUBytes(paletteBuf.get(), paletteSize); - if (compOut) - outf.writeUBytes(compOut.get(), compLen); - else - outf.writeUBytes(bufOut.get(), bufLen); - - return true; -} - -template -void DataSpec::TXTR::PaletteMeta::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"format"}, format, s); - Do(athena::io::PropId{"elementCount"}, elementCount, s); - Do(athena::io::PropId{"dolphinHash"}, dolphinHash, s); -} - -AT_SPECIALIZE_DNA_YAML(DataSpec::TXTR::PaletteMeta) - -std::string_view DataSpec::TXTR::PaletteMeta::DNAType() { return "DataSpec::TXTR::PaletteMeta"sv; } - -template -void DataSpec::TXTR::Meta::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"format"}, format, s); - Do(athena::io::PropId{"mips"}, mips, s); - Do(athena::io::PropId{"width"}, width, s); - Do(athena::io::PropId{"height"}, height, s); - Do(athena::io::PropId{"dolphinHash"}, dolphinHash, s); - Do(athena::io::PropId{"hasPalette"}, hasPalette, s); - if (hasPalette) - Do(athena::io::PropId{"palette"}, palette, s); -} - -AT_SPECIALIZE_DNA_YAML(DataSpec::TXTR::Meta) - -std::string_view DataSpec::TXTR::Meta::DNAType() { return "DataSpec::TXTR::Meta"sv; } - -static const atInt32 RetroToDol[11]{0, 1, 2, 3, 8, 9, -1, 4, 5, 6, 14}; - -TXTR::Meta TXTR::GetMetaData(DataSpec::PAKEntryReadStream& rs) { - const atUint32 retroFormat = rs.readUint32Big(); - const atUint32 format = RetroToDol[retroFormat]; - if (format == UINT32_MAX) - return {}; - - Meta meta; - meta.format = retroFormat; - meta.width = rs.readUint16Big(); - meta.height = rs.readUint16Big(); - meta.mips = rs.readUint32Big(); - atUint32 textureSize = meta.width * meta.height; - if (format == 8 || format == 9) { - meta.hasPalette = true; - PaletteMeta& palMeta = meta.palette; - palMeta.format = rs.readUint32Big(); - const atUint16 palWidth = rs.readUint16Big(); - const atUint16 palHeight = rs.readUint16Big(); - palMeta.elementCount = palWidth * palHeight; - const atUint32 palSize = atUint32(palWidth * palHeight * 2); - if (format == 8) - textureSize /= 2; - std::unique_ptr palData(new u8[palSize]); - rs.readUBytesToBuf(palData.get(), palSize); - palMeta.dolphinHash = XXH64(palData.get(), palSize, 0); - } else { - switch (format) { - case 0: // I4 - case 14: // DXT1 - textureSize /= 2; - break; - case 3: - case 4: - case 5: - textureSize *= 2; - break; - case 6: - textureSize *= 4; - break; - default: - break; - } - } - std::unique_ptr textureData(new u8[textureSize]); - rs.readUBytesToBuf(textureData.get(), textureSize); - meta.dolphinHash = XXH64(textureData.get(), textureSize, 0); - - return meta; -} - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/TXTR.hpp b/DataSpec/DNACommon/TXTR.hpp deleted file mode 100644 index 8a69e6efb..000000000 --- a/DataSpec/DNACommon/TXTR.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec { -class PAKEntryReadStream; - -struct TXTR { - struct PaletteMeta : BigDNAVYaml { - AT_DECL_EXPLICIT_DNA_YAMLV - Value format = UINT_MAX; - Value elementCount = 0; - Value dolphinHash = 0; - }; - struct Meta : BigDNAVYaml { - AT_DECL_EXPLICIT_DNA_YAMLV - Value format = UINT_MAX; - Value mips = 0; - Value width = 0; - Value height = 0; - Value dolphinHash = 0; - Value hasPalette = false; - PaletteMeta palette; - }; - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); - static bool CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); - static TXTR::Meta GetMetaData(PAKEntryReadStream& rs); -}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweak.hpp b/DataSpec/DNACommon/Tweaks/ITweak.hpp deleted file mode 100644 index fb732c492..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweak.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace DataSpec { -struct ITweak : BigDNA {}; -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp b/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp deleted file mode 100644 index 0f38c8b7f..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "ITweak.hpp" - -namespace DataSpec { -struct ITweakAutoMapper : public ITweak { -}; -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweakBall.hpp b/DataSpec/DNACommon/Tweaks/ITweakBall.hpp deleted file mode 100644 index 20c9f37b5..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweakBall.hpp +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once - -#include "ITweak.hpp" - -namespace DataSpec { -struct ITweakBall : ITweak { - virtual float GetMaxBallTranslationAcceleration(int s) const = 0; - virtual float GetBallTranslationFriction(int s) const = 0; - virtual float GetBallTranslationMaxSpeed(int s) const = 0; - virtual float GetBallCameraElevation() const = 0; - virtual float GetBallCameraAnglePerSecond() const = 0; - virtual const zeus::CVector3f& GetBallCameraOffset() const = 0; - virtual float GetBallCameraMinSpeedDistance() const = 0; - virtual float GetBallCameraMaxSpeedDistance() const = 0; - virtual float GetBallCameraBackwardsDistance() const = 0; - virtual float GetBallCameraSpringConstant() const = 0; - virtual float GetBallCameraSpringMax() const = 0; - virtual float GetBallCameraSpringTardis() const = 0; - virtual float GetBallCameraCentroidSpringConstant() const = 0; - virtual float GetBallCameraCentroidSpringMax() const = 0; - virtual float GetBallCameraCentroidSpringTardis() const = 0; - virtual float GetBallCameraCentroidDistanceSpringConstant() const = 0; - virtual float GetBallCameraCentroidDistanceSpringMax() const = 0; - virtual float GetBallCameraCentroidDistanceSpringTardis() const = 0; - virtual float GetBallCameraLookAtSpringConstant() const = 0; - virtual float GetBallCameraLookAtSpringMax() const = 0; - virtual float GetBallCameraLookAtSpringTardis() const = 0; - virtual float GetBallForwardBrakingAcceleration(int s) const = 0; - virtual float GetBallGravity() const = 0; - virtual float GetBallWaterGravity() const = 0; - virtual float GetBallSlipFactor(int s) const = 0; - virtual float GetConservativeDoorCameraDistance() const = 0; - virtual float GetBallCameraChaseElevation() const = 0; - virtual float GetBallCameraChaseDampenAngle() const = 0; - virtual float GetBallCameraChaseDistance() const = 0; - virtual float GetBallCameraChaseYawSpeed() const = 0; - virtual float GetBallCameraChaseAnglePerSecond() const = 0; - virtual const zeus::CVector3f& GetBallCameraChaseLookAtOffset() const = 0; - virtual float GetBallCameraChaseSpringConstant() const = 0; - virtual float GetBallCameraChaseSpringMax() const = 0; - virtual float GetBallCameraChaseSpringTardis() const = 0; - virtual float GetBallCameraBoostElevation() const = 0; - virtual float GetBallCameraBoostDampenAngle() const = 0; - virtual float GetBallCameraBoostDistance() const = 0; - virtual float GetBallCameraBoostYawSpeed() const = 0; - virtual float GetBallCameraBoostAnglePerSecond() const = 0; - virtual const zeus::CVector3f& GetBallCameraBoostLookAtOffset() const = 0; - virtual float GetBallCameraBoostSpringConstant() const = 0; - virtual float GetBallCameraBoostSpringMax() const = 0; - virtual float GetBallCameraBoostSpringTardis() const = 0; - virtual float GetMinimumAlignmentSpeed() const = 0; - virtual float GetTireness() const = 0; - virtual float GetMaxLeanAngle() const = 0; - virtual float GetTireToMarbleThresholdSpeed() const = 0; - virtual float GetMarbleToTireThresholdSpeed() const = 0; - virtual float GetForceToLeanGain() const = 0; - virtual float GetLeanTrackingGain() const = 0; - virtual float GetBallCameraControlDistance() const = 0; - virtual float GetLeftStickDivisor() const = 0; - virtual float GetRightStickDivisor() const = 0; - virtual float GetBallTouchRadius() const = 0; - virtual float GetBoostBallDrainTime() const = 0; - virtual float GetBoostBallMaxChargeTime() const = 0; - virtual float GetBoostBallMinChargeTime() const = 0; - virtual float GetBoostBallMinRelativeSpeedForDamage() const = 0; - virtual float GetBoostBallChargeTimeTable(int i) const = 0; - virtual float GetBoostBallIncrementalSpeedTable(int i) const = 0; -}; -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweakGame.hpp b/DataSpec/DNACommon/Tweaks/ITweakGame.hpp deleted file mode 100644 index 494f92043..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweakGame.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "ITweak.hpp" - -namespace DataSpec { - -struct ITweakGame : ITweak {}; -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweakGui.hpp b/DataSpec/DNACommon/Tweaks/ITweakGui.hpp deleted file mode 100644 index 5f3b260e7..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweakGui.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "ITweak.hpp" -#include "zeus/CVector2f.hpp" - -namespace DataSpec { - -struct ITweakGui : ITweak { - enum class EHudVisMode : atUint32 { Zero, One, Two, Three }; - enum class EHelmetVisMode : atUint32 { ReducedUpdate, NotVisible, Deco, HelmetDeco, GlowHelmetDeco, HelmetOnly }; -}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweakGuiColors.hpp b/DataSpec/DNACommon/Tweaks/ITweakGuiColors.hpp deleted file mode 100644 index 3238d8b5e..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweakGuiColors.hpp +++ /dev/null @@ -1,102 +0,0 @@ -#pragma once - -#include "ITweak.hpp" - -namespace DataSpec { -struct ITweakGuiColors : ITweak { - struct VisorEnergyInitColors { - const zeus::CColor& tankFilled; - const zeus::CColor& tankEmpty; - const zeus::CColor& digitsFont; - const zeus::CColor& digitsOutline; - }; - - struct VisorEnergyBarColors { - const zeus::CColor& filled; - const zeus::CColor& empty; - const zeus::CColor& shadow; - }; - - virtual const zeus::CColor& GetPauseBlurFilterColor() const = 0; - virtual const zeus::CColor& GetRadarStuffColor() const = 0; - virtual const zeus::CColor& GetRadarPlayerPaintColor() const = 0; - virtual const zeus::CColor& GetRadarEnemyPaintColor() const = 0; - virtual const zeus::CColor& GetHudMessageFill() const = 0; - virtual const zeus::CColor& GetHudMessageOutline() const = 0; - virtual const zeus::CColor& GetHudFrameColor() const = 0; - virtual const zeus::CColor& GetMissileIconColorActive() const = 0; - virtual const zeus::CColor& GetVisorBeamMenuItemActive() const = 0; - virtual const zeus::CColor& GetVisorBeamMenuItemInactive() const = 0; - virtual const zeus::CColor& GetEnergyBarFilledLowEnergy() const = 0; - virtual const zeus::CColor& GetEnergyBarShadowLowEnergy() const = 0; - virtual const zeus::CColor& GetEnergyBarEmptyLowEnergy() const = 0; - virtual const zeus::CColor& GetHudDamageLightColor() const = 0; - virtual const zeus::CColor& GetVisorMenuTextFont() const = 0; - virtual const zeus::CColor& GetVisorMenuTextOutline() const = 0; - virtual const zeus::CColor& GetBeamMenuTextFont() const = 0; - virtual const zeus::CColor& GetBeamMenuTextOutline() const = 0; - virtual const zeus::CColor& GetEnergyWarningFont() const = 0; - virtual const zeus::CColor& GetThreatWarningFont() const = 0; - virtual const zeus::CColor& GetMissileWarningFont() const = 0; - virtual const zeus::CColor& GetThreatBarFilled() const = 0; - virtual const zeus::CColor& GetThreatBarShadow() const = 0; - virtual const zeus::CColor& GetThreatBarEmpty() const = 0; - virtual const zeus::CColor& GetMissileBarFilled() const = 0; - virtual const zeus::CColor& GetMissileBarShadow() const = 0; - virtual const zeus::CColor& GetMissileBarEmpty() const = 0; - virtual const zeus::CColor& GetThreatIconColor() const = 0; - virtual const zeus::CColor& GetTickDecoColor() const = 0; - virtual const zeus::CColor& GetHelmetLightColor() const = 0; - virtual const zeus::CColor& GetThreatIconSafeColor() const = 0; - virtual const zeus::CColor& GetMissileIconColorInactive() const = 0; - virtual const zeus::CColor& GetMissileIconColorChargedCanAlt() const = 0; - virtual const zeus::CColor& GetMissileIconColorChargedNoAlt() const = 0; - virtual const zeus::CColor& GetMissileIconColorDepleteAlt() const = 0; - virtual const zeus::CColor& GetVisorBeamMenuLozColor() const = 0; - virtual const zeus::CColor& GetEnergyWarningOutline() const = 0; - virtual const zeus::CColor& GetThreatWarningOutline() const = 0; - virtual const zeus::CColor& GetMissileWarningOutline() const = 0; - virtual const zeus::CColor& GetDamageAmbientColor() const = 0; - virtual const zeus::CColor& GetScanFrameInactiveColor() const = 0; - virtual const zeus::CColor& GetScanFrameActiveColor() const = 0; - virtual const zeus::CColor& GetScanFrameImpulseColor() const = 0; - virtual const zeus::CColor& GetScanVisorHudLightMultiply() const = 0; - virtual const zeus::CColor& GetScanVisorScreenDimColor() const = 0; - virtual const zeus::CColor& GetThermalVisorHudLightMultiply() const = 0; - virtual const zeus::CColor& GetEnergyDrainFilterColor() const = 0; - virtual const zeus::CColor& GetDamageAmbientPulseColor() const = 0; - virtual const zeus::CColor& GetEnergyBarFlashColor() const = 0; - virtual const zeus::CColor& GetXRayEnergyDecoColor() const = 0; - virtual const zeus::CColor& GetScanDataDotColor() const = 0; - virtual const zeus::CColor& GetPowerBombDigitAvailableFont() const = 0; - virtual const zeus::CColor& GetPowerBombDigitAvailableOutline() const = 0; - virtual const zeus::CColor& GetBallBombFilledColor() const = 0; - virtual const zeus::CColor& GetBallBombEmptyColor() const = 0; - virtual const zeus::CColor& GetPowerBombIconAvailableColor() const = 0; - virtual const zeus::CColor& GetBallBombEnergyColor() const = 0; - virtual const zeus::CColor& GetBallBombDecoColor() const = 0; - virtual const zeus::CColor& GetPowerBombDigitDelpetedFont() const = 0; - virtual const zeus::CColor& GetPowerBombDigitDelpetedOutline() const = 0; - virtual const zeus::CColor& GetPowerBombIconDepletedColor() const = 0; - virtual const zeus::CColor& GetScanDisplayImagePaneColor() const = 0; - virtual const zeus::CColor& GetThreatIconWarningColor() const = 0; - virtual const zeus::CColor& GetHudCounterFill() const = 0; - virtual const zeus::CColor& GetHudCounterOutline() const = 0; - virtual const zeus::CColor& GetScanIconCriticalColor() const = 0; - virtual const zeus::CColor& GetScanIconCriticalDimColor() const = 0; - virtual const zeus::CColor& GetScanIconNoncriticalColor() const = 0; - virtual const zeus::CColor& GetScanIconNoncriticalDimColor() const = 0; - virtual const zeus::CColor& GetScanReticuleColor() const = 0; - virtual const zeus::CColor& GetThreatDigitsFont() const = 0; - virtual const zeus::CColor& GetThreatDigitsOutline() const = 0; - virtual const zeus::CColor& GetMissileDigitsFont() const = 0; - virtual const zeus::CColor& GetMissileDigitsOutline() const = 0; - virtual const zeus::CColor& GetThermalDecoColor() const = 0; - virtual const zeus::CColor& GetThermalOutlinesColor() const = 0; - virtual const zeus::CColor& GetThermalLockColor() const = 0; - virtual const zeus::CColor& GetPauseItemAmberColor() const = 0; - virtual const zeus::CColor& GetPauseItemBlueColor() const = 0; - virtual VisorEnergyInitColors GetVisorEnergyInitColors(int idx) const = 0; - virtual VisorEnergyBarColors GetVisorEnergyBarColors(int idx) const = 0; -}; -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweakGunRes.hpp b/DataSpec/DNACommon/Tweaks/ITweakGunRes.hpp deleted file mode 100644 index 4583cd02b..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweakGunRes.hpp +++ /dev/null @@ -1,142 +0,0 @@ -#pragma once - -#include - -#include "ITweak.hpp" -#include "Runtime/IFactory.hpp" -#include "Runtime/CPlayerState.hpp" - -namespace DataSpec { - -struct ITweakGunRes : ITweak { - using ResId = metaforce::CAssetId; - using EBeamId = metaforce::CPlayerState::EBeamId; - - ResId x4_gunMotion; - ResId x8_grappleArm; - ResId xc_rightHand; - - ResId x10_powerBeam; - ResId x14_iceBeam; - ResId x18_waveBeam; - ResId x1c_plasmaBeam; - ResId x20_phazonBeam; - - ResId x24_holoTransition; - - ResId x28_bombSet; - ResId x2c_bombExplode; - ResId x30_powerBombExplode; - - /* Power, Ice, Wave, Plasma, Phazon / Beam, Ball */ - using WeaponPair = std::array; - std::array x34_weapons; - std::array x84_muzzle; - std::array x94_charge; - std::array xa4_auxMuzzle; - - ResId xb4_grappleSegment; - ResId xb8_grappleClaw; - ResId xbc_grappleHit; - ResId xc0_grappleMuzzle; - ResId xc4_grappleSwoosh; - - ResId GetBeamModel(EBeamId beam) const { - auto b = int(beam); - if (b < 0 || b > 4) - b = 0; - switch (EBeamId(b)) { - default: - case EBeamId::Power: - return x10_powerBeam; - case EBeamId::Ice: - return x14_iceBeam; - case EBeamId::Wave: - return x18_waveBeam; - case EBeamId::Plasma: - return x1c_plasmaBeam; - case EBeamId::Phazon: - return x20_phazonBeam; - } - } - - const WeaponPair& GetWeaponPair(EBeamId beam) const { - const auto b = int(beam); - if (b < 0 || b > 4) { - return x34_weapons[0]; - } - return x34_weapons[b]; - } - - void ResolveResources(const metaforce::IFactory& factory) { - x4_gunMotion = factory.GetResourceIdByName(GetGunMotion())->id; - x8_grappleArm = factory.GetResourceIdByName(GetGrappleArm())->id; - xc_rightHand = factory.GetResourceIdByName(GetRightHand())->id; - - x10_powerBeam = factory.GetResourceIdByName(GetPowerBeam())->id; - x14_iceBeam = factory.GetResourceIdByName(GetIceBeam())->id; - x18_waveBeam = factory.GetResourceIdByName(GetWaveBeam())->id; - x1c_plasmaBeam = factory.GetResourceIdByName(GetPlasmaBeam())->id; - x20_phazonBeam = factory.GetResourceIdByName(GetPhazonBeam())->id; - - x24_holoTransition = factory.GetResourceIdByName(GetHoloTransition())->id; - - x28_bombSet = factory.GetResourceIdByName(GetBombSet())->id; - x2c_bombExplode = factory.GetResourceIdByName(GetBombExplode())->id; - x30_powerBombExplode = factory.GetResourceIdByName(GetPowerBombExplode())->id; - - for (size_t i = 0; i < x34_weapons.size(); ++i) { - for (size_t j = 0; j < x34_weapons[i].size(); ++j) { - x34_weapons[i][j] = factory.GetResourceIdByName(GetWeapon(i, j != 0))->id; - } - } - - for (size_t i = 0; i < x84_muzzle.size(); ++i) { - x84_muzzle[i] = factory.GetResourceIdByName(GetMuzzleParticle(i))->id; - } - - for (size_t i = 0; i < x94_charge.size(); ++i) { - x94_charge[i] = factory.GetResourceIdByName(GetChargeParticle(i))->id; - } - - for (size_t i = 0; i < xa4_auxMuzzle.size(); ++i) { - xa4_auxMuzzle[i] = factory.GetResourceIdByName(GetAuxMuzzleParticle(i))->id; - } - - xb4_grappleSegment = factory.GetResourceIdByName(GetGrappleSegmentParticle())->id; - xb8_grappleClaw = factory.GetResourceIdByName(GetGrappleClawParticle())->id; - xbc_grappleHit = factory.GetResourceIdByName(GetGrappleHitParticle())->id; - xc0_grappleMuzzle = factory.GetResourceIdByName(GetGrappleMuzzleParticle())->id; - xc4_grappleSwoosh = factory.GetResourceIdByName(GetGrappleSwooshParticle())->id; - } - -protected: - virtual const std::string& GetGunMotion() const = 0; - virtual const std::string& GetGrappleArm() const = 0; - virtual const std::string& GetRightHand() const = 0; - - virtual const std::string& GetPowerBeam() const = 0; - virtual const std::string& GetIceBeam() const = 0; - virtual const std::string& GetWaveBeam() const = 0; - virtual const std::string& GetPlasmaBeam() const = 0; - virtual const std::string& GetPhazonBeam() const = 0; - - virtual const std::string& GetHoloTransition() const = 0; - - virtual const std::string& GetBombSet() const = 0; - virtual const std::string& GetBombExplode() const = 0; - virtual const std::string& GetPowerBombExplode() const = 0; - - virtual const std::string& GetWeapon(size_t idx, bool ball) const = 0; - virtual const std::string& GetMuzzleParticle(size_t idx) const = 0; - virtual const std::string& GetChargeParticle(size_t idx) const = 0; - virtual const std::string& GetAuxMuzzleParticle(size_t idx) const = 0; - - virtual const std::string& GetGrappleSegmentParticle() const = 0; - virtual const std::string& GetGrappleClawParticle() const = 0; - virtual const std::string& GetGrappleHitParticle() const = 0; - virtual const std::string& GetGrappleMuzzleParticle() const = 0; - virtual const std::string& GetGrappleSwooshParticle() const = 0; -}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweakParticle.hpp b/DataSpec/DNACommon/Tweaks/ITweakParticle.hpp deleted file mode 100644 index 80a7dceb0..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweakParticle.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "ITweak.hpp" - -namespace DataSpec { - -struct ITweakParticle : ITweak {}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweakPlayer.hpp b/DataSpec/DNACommon/Tweaks/ITweakPlayer.hpp deleted file mode 100644 index 220cb5e8e..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweakPlayer.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "ITweak.hpp" -#include "zeus/CAABox.hpp" - -namespace DataSpec { - -struct ITweakPlayer : ITweak {}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweakPlayerControl.hpp b/DataSpec/DNACommon/Tweaks/ITweakPlayerControl.hpp deleted file mode 100644 index 58b9c5c39..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweakPlayerControl.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "ITweak.hpp" - -namespace DataSpec { - -struct ITweakPlayerControl : ITweak {}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweakPlayerGun.hpp b/DataSpec/DNACommon/Tweaks/ITweakPlayerGun.hpp deleted file mode 100644 index 1a4c3fbca..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweakPlayerGun.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include "ITweak.hpp" -#include "zeus/CAABox.hpp" - -namespace DataSpec { -/* Same as CDamageInfo */ -struct SShotParam : BigDNA { - AT_DECL_DNA_YAML - Value weaponType = -1; - bool charged : 1; - bool combo : 1; - bool instaKill : 1; - Value damage = 0.f; - Value radiusDamage = 0.f; - Value radius = 0.f; - Value knockback = 0.f; - bool noImmunity : 1; - SShotParam() { - charged = false; - combo = false; - instaKill = false; - noImmunity = false; - } -}; - -struct SComboShotParam : SShotParam { - AT_DECL_DNA_YAML - SComboShotParam() { combo = true; } -}; - -struct SChargedShotParam : SShotParam { - AT_DECL_DNA_YAML - SChargedShotParam() { charged = true; } -}; - -struct SWeaponInfo : BigDNA { - AT_DECL_DNA_YAML - Value x0_coolDown = 0.1f; - SShotParam x4_normal; - SChargedShotParam x20_charged; -}; - -struct ITweakPlayerGun : ITweak { - AT_DECL_DNA_YAML -}; -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweakPlayerRes.hpp b/DataSpec/DNACommon/Tweaks/ITweakPlayerRes.hpp deleted file mode 100644 index 6e0b689d3..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweakPlayerRes.hpp +++ /dev/null @@ -1,176 +0,0 @@ -#pragma once - -#include - -#include "ITweak.hpp" -#include "Runtime/IFactory.hpp" -#include "Runtime/CPlayerState.hpp" - -namespace DataSpec { - -struct ITweakPlayerRes : ITweak { - using ResId = metaforce::CAssetId; - using EBeamId = metaforce::CPlayerState::EBeamId; - - ResId x4_saveStationIcon; - ResId x8_missileStationIcon; - ResId xc_elevatorIcon; - - ResId x10_minesBreakFirstTopIcon; - ResId x14_minesBreakFirstBottomIcon; - ResId x18_minesBreakSecondTopIcon; - ResId x1c_minesBreakSecondBottomIcon; - - ResId rs5_mapArrowUp; - ResId rs5_mapArrowDown; - - /* N, U, UL, L, DL, D, DR, R, UR */ - std::array x24_lStick; - std::array x4c_cStick; - - /* Out, In */ - std::array x74_lTrigger; - std::array x80_rTrigger; - std::array x8c_startButton; - std::array x98_aButton; - std::array xa4_bButton; - std::array xb0_xButton; - std::array xbc_yButton; - - ResId xc4_ballTransitionsANCS; - - /* Power, Ice, Wave, Plasma, Phazon */ - std::array xc8_ballTransitions; - std::array xdc_cineGun; - - float xf0_cinematicMoveOutofIntoPlayerDistance; - - ResId GetBeamBallTransitionModel(EBeamId beam) const { - auto b = size_t(beam); - if (b >= xc8_ballTransitions.size()) { - b = 0; - } - switch (EBeamId(b)) { - case EBeamId::Power: - default: - return xc8_ballTransitions[0]; - case EBeamId::Ice: - return xc8_ballTransitions[1]; - case EBeamId::Wave: - return xc8_ballTransitions[2]; - case EBeamId::Plasma: - return xc8_ballTransitions[3]; - case EBeamId::Phazon: - return xc8_ballTransitions[4]; - } - } - - ResId GetBeamCineModel(EBeamId beam) const { - auto b = size_t(beam); - if (b >= xdc_cineGun.size()) { - b = 0; - } - switch (EBeamId(b)) { - case EBeamId::Power: - default: - return xdc_cineGun[0]; - case EBeamId::Ice: - return xdc_cineGun[1]; - case EBeamId::Wave: - return xdc_cineGun[2]; - case EBeamId::Plasma: - return xdc_cineGun[3]; - case EBeamId::Phazon: - return xdc_cineGun[4]; - } - } - - void ResolveResources(const metaforce::IFactory& factory) { - x4_saveStationIcon = factory.GetResourceIdByName(_GetSaveStationIcon())->id; - x8_missileStationIcon = factory.GetResourceIdByName(_GetMissileStationIcon())->id; - xc_elevatorIcon = factory.GetResourceIdByName(_GetElevatorIcon())->id; - - x10_minesBreakFirstTopIcon = factory.GetResourceIdByName(_GetMinesBreakFirstTopIcon())->id; - x14_minesBreakFirstBottomIcon = factory.GetResourceIdByName(_GetMinesBreakFirstBottomIcon())->id; - x18_minesBreakSecondTopIcon = factory.GetResourceIdByName(_GetMinesBreakSecondTopIcon())->id; - x1c_minesBreakSecondBottomIcon = factory.GetResourceIdByName(_GetMinesBreakSecondBottomIcon())->id; - - for (size_t i = 0; i < x24_lStick.size(); ++i) { - x24_lStick[i] = factory.GetResourceIdByName(_GetLStick(i))->id; - } - - for (size_t i = 0; i < x4c_cStick.size(); ++i) { - x4c_cStick[i] = factory.GetResourceIdByName(_GetCStick(i))->id; - } - - for (size_t i = 0; i < x74_lTrigger.size(); ++i) { - x74_lTrigger[i] = factory.GetResourceIdByName(_GetLTrigger(i))->id; - } - - for (size_t i = 0; i < x80_rTrigger.size(); ++i) { - x80_rTrigger[i] = factory.GetResourceIdByName(_GetRTrigger(i))->id; - } - - for (size_t i = 0; i < x8c_startButton.size(); ++i) { - x8c_startButton[i] = factory.GetResourceIdByName(_GetStartButton(i))->id; - } - - for (size_t i = 0; i < x98_aButton.size(); ++i) { - x98_aButton[i] = factory.GetResourceIdByName(_GetAButton(i))->id; - } - - for (size_t i = 0; i < xa4_bButton.size(); ++i) { - xa4_bButton[i] = factory.GetResourceIdByName(_GetBButton(i))->id; - } - - for (size_t i = 0; i < xb0_xButton.size(); ++i) { - xb0_xButton[i] = factory.GetResourceIdByName(_GetXButton(i))->id; - } - - for (size_t i = 0; i < xbc_yButton.size(); ++i) { - xbc_yButton[i] = factory.GetResourceIdByName(_GetYButton(i))->id; - } - - xc4_ballTransitionsANCS = factory.GetResourceIdByName(_GetBallTransitionsANCS())->id; - - for (size_t i = 0; i < xc8_ballTransitions.size(); ++i) { - xc8_ballTransitions[i] = factory.GetResourceIdByName(_GetBallTransitionBeamRes(i))->id; - } - - for (size_t i = 0; i < xdc_cineGun.size(); ++i) { - xdc_cineGun[i] = factory.GetResourceIdByName(_GetBeamCineModel(i))->id; - } - - xf0_cinematicMoveOutofIntoPlayerDistance = _GetCinematicMoveOutofIntoPlayerDistance(); - } - -protected: - virtual std::string_view _GetSaveStationIcon() const = 0; - virtual std::string_view _GetMissileStationIcon() const = 0; - virtual std::string_view _GetElevatorIcon() const = 0; - - virtual std::string_view _GetMinesBreakFirstTopIcon() const = 0; - virtual std::string_view _GetMinesBreakFirstBottomIcon() const = 0; - virtual std::string_view _GetMinesBreakSecondTopIcon() const = 0; - virtual std::string_view _GetMinesBreakSecondBottomIcon() const = 0; - - virtual std::string_view _GetLStick(size_t idx) const = 0; - virtual std::string_view _GetCStick(size_t idx) const = 0; - - virtual std::string_view _GetLTrigger(size_t idx) const = 0; - virtual std::string_view _GetRTrigger(size_t idx) const = 0; - virtual std::string_view _GetStartButton(size_t idx) const = 0; - virtual std::string_view _GetAButton(size_t idx) const = 0; - virtual std::string_view _GetBButton(size_t idx) const = 0; - virtual std::string_view _GetXButton(size_t idx) const = 0; - virtual std::string_view _GetYButton(size_t idx) const = 0; - - virtual std::string_view _GetBallTransitionsANCS() const = 0; - - virtual std::string_view _GetBallTransitionBeamRes(size_t idx) const = 0; - virtual std::string_view _GetBeamCineModel(size_t idx) const = 0; - - virtual float _GetCinematicMoveOutofIntoPlayerDistance() const = 0; -}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweakSlideShow.hpp b/DataSpec/DNACommon/Tweaks/ITweakSlideShow.hpp deleted file mode 100644 index ab506b4e4..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweakSlideShow.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "ITweak.hpp" - -namespace DataSpec { - -struct ITweakSlideShow : ITweak { - virtual std::string_view GetFont() const = 0; - virtual const zeus::CColor& GetFontColor() const = 0; - virtual const zeus::CColor& GetOutlineColor() const = 0; - virtual float GetScanPercentInterval() const = 0; - virtual float GetX54() const = 0; -}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweakTargeting.hpp b/DataSpec/DNACommon/Tweaks/ITweakTargeting.hpp deleted file mode 100644 index 69042fc30..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweakTargeting.hpp +++ /dev/null @@ -1,95 +0,0 @@ -#pragma once - -#include "ITweak.hpp" -namespace DataSpec { -struct ITweakTargeting : public ITweak { - virtual atUint32 GetTargetRadiusMode() const = 0; - virtual float GetCurrLockOnExitDuration() const = 0; - virtual float GetCurrLockOnEnterDuration() const = 0; - virtual float GetCurrLockOnSwitchDuration() const = 0; - virtual float GetLockConfirmScale() const = 0; - virtual float GetNextLockOnEnterDuration() const = 0; - virtual float GetNextLockOnExitDuration() const = 0; - virtual float GetNextLockOnSwitchDuration() const = 0; - virtual float GetSeekerScale() const = 0; - virtual float GetSeekerAngleSpeed() const = 0; - virtual float GetXRayRetAngleSpeed() const = 0; - virtual float GetOrbitPointZOffset() const = 0; - virtual float GetOrbitPointInTime() const = 0; - virtual float GetOrbitPointOutTime() const = 0; - virtual const zeus::CColor& GetThermalReticuleColor() const = 0; - virtual float GetTargetFlowerScale() const = 0; - virtual const zeus::CColor& GetTargetFlowerColor() const = 0; - virtual float GetMissileBracketDuration() const = 0; - virtual float GetMissileBracketScaleStart() const = 0; - virtual float GetMissileBracketScaleEnd() const = 0; - virtual float GetMissileBracketScaleDuration() const = 0; - virtual const zeus::CColor& GetMissileBracketColor() const = 0; - virtual float GetChargeGaugeOvershootOffset() const = 0; - virtual float GetChargeGaugeOvershootDuration() const = 0; - virtual float GetOuterBeamSquaresScale() const = 0; - virtual const zeus::CColor& GetOuterBeamSquareColor() const = 0; - virtual float GetLockonDuration() const = 0; - virtual float GetInnerBeamScale() const = 0; - virtual const zeus::CColor& GetInnerBeamColorPower() const = 0; - virtual const zeus::CColor& GetInnerBeamColorIce() const = 0; - virtual const zeus::CColor& GetInnerBeamColorWave() const = 0; - virtual const zeus::CColor& GetInnerBeamColorPlasma() const = 0; - virtual const float* GetOuterBeamSquareAngles(int i) const = 0; - virtual float GetChargeGaugeAngle(int i) const = 0; - virtual float GetChargeGaugeScale() const = 0; - virtual const zeus::CColor& GetChargeGaugeNonFullColor() const = 0; - virtual atUint32 GetChargeTickCount() const = 0; - virtual float GetChargeTickAnglePitch() const = 0; - virtual float GetLockFireScale() const = 0; - virtual float GetLockFireDuration() const = 0; - virtual const zeus::CColor& GetLockFireColor() const = 0; - virtual float GetLockDaggerScaleStart() const = 0; - virtual float GetLockDaggerScaleEnd() const = 0; - virtual const zeus::CColor& GetLockDaggerColor() const = 0; - virtual float GetLockDaggerAngle0() const = 0; - virtual float GetLockDaggerAngle1() const = 0; - virtual float GetLockDaggerAngle2() const = 0; - virtual const zeus::CColor& GetLockConfirmColor() const = 0; - virtual const zeus::CColor& GetSeekerColor() const = 0; - virtual float GetLockConfirmClampMin() const = 0; - virtual float GetLockConfirmClampMax() const = 0; - virtual float GetTargetFlowerClampMin() const = 0; - virtual float GetTargetFlowerClampMax() const = 0; - virtual float GetSeekerClampMin() const = 0; - virtual float GetSeekerClampMax() const = 0; - virtual float GetMissileBracketClampMin() const = 0; - virtual float GetMissileBracketClampMax() const = 0; - virtual float GetInnerBeamClampMin() const = 0; - virtual float GetInnerBeamClampMax() const = 0; - virtual float GetChargeGaugeClampMin() const = 0; - virtual float GetChargeGaugeClampMax() const = 0; - virtual float GetLockFireClampMin() const = 0; - virtual float GetLockFireClampMax() const = 0; - virtual float GetLockDaggerClampMin() const = 0; - virtual float GetLockDaggerClampMax() const = 0; - virtual float GetGrappleSelectScale() const = 0; - virtual float GetGrappleScale() const = 0; - virtual float GetGrappleClampMin() const = 0; - virtual float GetGrappleClampMax() const = 0; - virtual const zeus::CColor& GetGrapplePointSelectColor() const = 0; - virtual const zeus::CColor& GetGrapplePointColor() const = 0; - virtual const zeus::CColor& GetLockedGrapplePointSelectColor() const = 0; - virtual float GetGrappleMinClampScale() const = 0; - virtual const zeus::CColor& GetChargeGaugePulseColorHigh() const = 0; - virtual float GetFullChargeFadeDuration() const = 0; - virtual const zeus::CColor& GetOrbitPointColor() const = 0; - virtual const zeus::CColor& GetCrosshairsColor() const = 0; - virtual float GetCrosshairsScaleDuration() const = 0; - virtual bool DrawOrbitPoint() const = 0; - virtual const zeus::CColor& GetChargeGaugePulseColorLow() const = 0; - virtual float GetChargeGaugePulsePeriod() const = 0; - virtual float GetReticuleClampMin() const = 0; - virtual float GetReticuleClampMax() const = 0; - virtual const zeus::CColor& GetXRayRetRingColor() const = 0; - virtual float GetReticuleScale() const = 0; - virtual float GetScanTargetClampMin() const = 0; - virtual float GetScanTargetClampMax() const = 0; - virtual float GetAngularLagSpeed() const = 0; -}; -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/TweakWriter.hpp b/DataSpec/DNACommon/Tweaks/TweakWriter.hpp deleted file mode 100644 index fd09d4c3e..000000000 --- a/DataSpec/DNACommon/Tweaks/TweakWriter.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "../PAK.hpp" - -namespace DataSpec { - -template -bool WriteTweak(const T& tweak, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - tweak.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} - -template -bool ExtractTweak(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - T tweak; - tweak.read(rs); - athena::io::ToYAMLStream(tweak, writer); - return true; - } - return false; -} - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/WPSC.cpp b/DataSpec/DNACommon/WPSC.cpp deleted file mode 100644 index c801d8789..000000000 --- a/DataSpec/DNACommon/WPSC.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "DataSpec/DNACommon/WPSC.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAParticle { - -template struct PPImpl<_WPSM>; -template struct PPImpl<_WPSM>; - -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_WPSM>) -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_WPSM>) - -template <> -std::string_view WPSM::DNAType() { - return "WPSM"sv; -} - -template <> -std::string_view WPSM::DNAType() { - return "WPSM"sv; -} - -template -bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - WPSM wpsm; - wpsm.read(rs); - athena::io::ToYAMLStream(wpsm, writer); - return true; - } - return false; -} -template bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteWPSM(const WPSM& wpsm, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - wpsm.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteWPSM(const WPSM& wpsm, const hecl::ProjectPath& outPath); -template bool WriteWPSM(const WPSM& wpsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/WPSC.def b/DataSpec/DNACommon/WPSC.def deleted file mode 100644 index 04b6ce33f..000000000 --- a/DataSpec/DNACommon/WPSC.def +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef ENTRY -#define ENTRY(name, identifier) -#endif - -#ifndef INT_ENTRY -#define INT_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef U32_ENTRY -#define U32_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef REAL_ENTRY -#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef VECTOR_ENTRY -#define VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef MOD_VECTOR_ENTRY -#define MOD_VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef COLOR_ENTRY -#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef UV_ENTRY -#define UV_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef RES_ENTRY -#define RES_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef BOOL_ENTRY -#define BOOL_ENTRY(name, identifier, def) ENTRY(name, identifier) -#endif - -VECTOR_ENTRY('IORN', x0_IORN) -VECTOR_ENTRY('IVEC', x4_IVEC) -VECTOR_ENTRY('PSOV', x8_PSOV) -MOD_VECTOR_ENTRY('PSVM', xc_PSVM) -INT_ENTRY('PSLT', x14_PSLT) -VECTOR_ENTRY('PSCL', x18_PSCL) -COLOR_ENTRY('PCOL', x1c_PCOL) -VECTOR_ENTRY('POFS', x20_POFS) -VECTOR_ENTRY('OFST', x24_OFST) - -REAL_ENTRY('TRAT', x30_TRAT) -RES_ENTRY('APSM', x34_APSM) -RES_ENTRY('APS2', x44_APS2) -RES_ENTRY('ASW1', x54_ASW1) -RES_ENTRY('ASW2', x64_ASW2) -RES_ENTRY('ASW3', x74_ASW3) -RES_ENTRY('OHEF', x84_OHEF) -RES_ENTRY('COLR', x94_COLR) -U32_ENTRY('PJFX', xa8_PJFX) -REAL_ENTRY('RNGE', xac_RNGE) -REAL_ENTRY('FOFF', xb0_FOFF) - -BOOL_ENTRY('VMD2', x10_VMD2, false) -BOOL_ENTRY('APSO', x28_APSO, false) -BOOL_ENTRY('HOMG', x29_HOMG, false) -BOOL_ENTRY('AP11', x2a_AP11, false) -BOOL_ENTRY('AP21', x2b_AP21, false) -BOOL_ENTRY('AS11', x2c_AS11, false) -BOOL_ENTRY('AS12', x2d_AS12, false) -BOOL_ENTRY('AS13', x2e_AS13, false) -BOOL_ENTRY('EWTR', xa4_EWTR, true) -BOOL_ENTRY('LWTR', xa5_LWTR, true) -BOOL_ENTRY('SWTR', xa6_SWTR, true) -BOOL_ENTRY('FC60', xunk_FC60, false) -BOOL_ENTRY('SPS1', xunk_SPS1, false) -BOOL_ENTRY('SPS2', xunk_SPS2, false) - -#undef ENTRY -#undef INT_ENTRY -#undef U32_ENTRY -#undef REAL_ENTRY -#undef VECTOR_ENTRY -#undef MOD_VECTOR_ENTRY -#undef COLOR_ENTRY -#undef UV_ENTRY -#undef RES_ENTRY -#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/WPSC.hpp b/DataSpec/DNACommon/WPSC.hpp deleted file mode 100644 index 8b1490b02..000000000 --- a/DataSpec/DNACommon/WPSC.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ParticleCommon.hpp" - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAParticle { - -template -struct _WPSM { - static constexpr ParticleType Type = ParticleType::WPSM; - -#define INT_ENTRY(name, identifier) IntElementFactory identifier; -#define U32_ENTRY(name, identifier) uint32_t identifier = ~0; -#define REAL_ENTRY(name, identifier) RealElementFactory identifier; -#define VECTOR_ENTRY(name, identifier) VectorElementFactory identifier; -#define MOD_VECTOR_ENTRY(name, identifier) ModVectorElementFactory identifier; -#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; -#define UV_ENTRY(name, identifier) UVElementFactory identifier; -#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; -#define BOOL_ENTRY(name, identifier, def) bool identifier = def; -#include "WPSC.def" - - template - void constexpr Enumerate(_Func f) { -#define ENTRY(name, identifier) f(FOURCC(name), identifier); -#define BOOL_ENTRY(name, identifier, def) f(FOURCC(name), identifier, def); -#include "WPSC.def" - } - - template - bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { -#define ENTRY(name, identifier) \ - case SBIG(name): \ - f(identifier); \ - return true; -#include "WPSC.def" - default: - return false; - } - } -}; -template -using WPSM = PPImpl<_WPSM>; - -template -bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteWPSM(const WPSM& wpsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNAMP1/AFSM.cpp b/DataSpec/DNAMP1/AFSM.cpp deleted file mode 100644 index 8ddefe59c..000000000 --- a/DataSpec/DNAMP1/AFSM.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "AFSM.hpp" - -namespace DataSpec::DNAMP1 { - -template <> -void AFSM::State::Transition::Enumerate(typename Read::StreamT& r) { - triggerCount = r.readUint32Big(); - int i = 0; - r.enumerate(triggers, triggerCount, [&](athena::io::IStreamReader& in, Trigger& tr) { - tr.first = i == 0; - tr.read(in); - i++; - }); -} - -template <> -void AFSM::State::Transition::Enumerate(typename Write::StreamT& w) { - w.writeInt32Big(triggerCount); - w.enumerate(triggers); -} - -template <> -void AFSM::State::Transition::Enumerate(typename ReadYaml::StreamT& r) { - int i = 0; - /* triggers */ - triggerCount = r.enumerate("triggers", triggers, [&](athena::io::YAMLDocReader& in, Trigger& tr) { - tr.first = i == 0; - tr.read(in); - i++; - }); -} - -template <> -void AFSM::State::Transition::Enumerate(typename WriteYaml::StreamT& w) { - /* triggers */ - w.enumerate("triggers", triggers); -} - -template <> -void AFSM::State::Transition::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - for (const Trigger& trig : triggers) - trig.binarySize(s); -} - -std::string_view AFSM::State::Transition::DNAType() { return "DNAMP1::AFSM::Transition"sv; } - -template <> -void AFSM::State::Transition::Trigger::Enumerate(athena::io::IStreamReader& __dna_reader) { - /* name */ - name = __dna_reader.readString(-1); - /* parameter */ - parameter = __dna_reader.readFloatBig(); - if (first) { - /* targetState */ - targetState = __dna_reader.readUint32Big(); - } -} - -template <> -void AFSM::State::Transition::Trigger::Enumerate(athena::io::IStreamWriter& __dna_writer) { - /* name */ - __dna_writer.writeString(name, -1); - /* parameter */ - __dna_writer.writeFloatBig(parameter); - if (first) { - /* targetState */ - __dna_writer.writeUint32Big(targetState); - } -} - -template <> -void AFSM::State::Transition::Trigger::Enumerate(athena::io::YAMLDocReader& __dna_docin) { - /* name */ - name = __dna_docin.readString("name"); - /* parameter */ - parameter = __dna_docin.readFloat("parameter"); - if (first) { - /* targetState */ - targetState = __dna_docin.readUint32("targetState"); - } -} - -template <> -void AFSM::State::Transition::Trigger::Enumerate(athena::io::YAMLDocWriter& __dna_docout) { - /* name */ - __dna_docout.writeString("name", name); - /* parameter */ - __dna_docout.writeFloat("parameter", parameter); - if (first) { - /* targetState */ - __dna_docout.writeUint32("targetState", targetState); - } -} - -template <> -void AFSM::State::Transition::Trigger::Enumerate(size_t& __isz) { - __isz += name.size() + 1; - __isz += (first ? 8 : 4); -} - -std::string_view AFSM::State::Transition::Trigger::DNAType() { return "DNAMP1::AFSM::State::Transition::Trigger"sv; } - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/AFSM.hpp b/DataSpec/DNAMP1/AFSM.hpp deleted file mode 100644 index 5dd6e2684..000000000 --- a/DataSpec/DNAMP1/AFSM.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { -struct AFSM : public BigDNA { - AT_DECL_DNA_YAML - Value stateCount; - Vector, AT_DNA_COUNT(stateCount)> stateNames; - Value triggerCount; - - struct State : public BigDNA { - AT_DECL_DNA_YAML - Value transitionCount; - struct Transition : public BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - Value triggerCount; - - struct Trigger : public BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - bool first = false; - String<-1> name; - Value parameter; - Value targetState; - }; - Vector triggers; - }; - Vector transitions; - }; - Vector states; - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - AFSM afsm; - afsm.read(rs); - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(afsm, writer); - return true; - } - - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - AFSM afsm; - athena::io::FileReader reader(inPath.getAbsolutePath()); - athena::io::FromYAMLStream(afsm, reader); - athena::io::FileWriter ws(outPath.getAbsolutePath()); - afsm.write(ws); - return true; - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/AGSC.cpp b/DataSpec/DNAMP1/AGSC.cpp deleted file mode 100644 index 0078f94eb..000000000 --- a/DataSpec/DNAMP1/AGSC.cpp +++ /dev/null @@ -1,266 +0,0 @@ -#include "AGSC.hpp" -#include "amuse/AudioGroup.hpp" -#include "amuse/AudioGroupData.hpp" - -extern "C" const uint8_t Atomic_H[]; -extern "C" const uint8_t BetaBeetle_H[]; -extern "C" const uint8_t Bird_H[]; -extern "C" const uint8_t BloodFlower_H[]; -extern "C" const uint8_t Burrower_H[]; -extern "C" const uint8_t ChozoGhost_H[]; -extern "C" const uint8_t ChubbWeed_H[]; -extern "C" const uint8_t CineBoots_H[]; -extern "C" const uint8_t CineGeneral_H[]; -extern "C" const uint8_t CineGun_H[]; -extern "C" const uint8_t CineMorphball_H[]; -extern "C" const uint8_t CineSuit_H[]; -extern "C" const uint8_t CineVisor_H[]; -extern "C" const uint8_t Crater_H[]; -extern "C" const uint8_t Crystallite_H[]; -extern "C" const uint8_t Drones_H[]; -extern "C" const uint8_t EliteSpacePirate_H[]; -extern "C" const uint8_t FireFlea_H[]; -extern "C" const uint8_t Flaaghra_H[]; -extern "C" const uint8_t FlickerBat_H[]; -extern "C" const uint8_t FlyingPirate_H[]; -extern "C" const uint8_t FrontEnd_H[]; -extern "C" const uint8_t GagantuanBeatle_H[]; -extern "C" const uint8_t Gnats_H[]; -extern "C" const uint8_t Gryzbee_H[]; -extern "C" const uint8_t IceCrack_H[]; -extern "C" const uint8_t IceWorld_H[]; -extern "C" const uint8_t InjuredPirates_H[]; -extern "C" const uint8_t IntroBoss_H[]; -extern "C" const uint8_t IntroWorld_H[]; -extern "C" const uint8_t JellyZap_H[]; -extern "C" const uint8_t LavaWorld_H[]; -extern "C" const uint8_t Magdolite_H[]; -extern "C" const uint8_t Metaree_H[]; -extern "C" const uint8_t MetroidPrime_H[]; -extern "C" const uint8_t Metroid_H[]; -extern "C" const uint8_t MinesWorld_H[]; -extern "C" const uint8_t MiscSamus_H[]; -extern "C" const uint8_t Misc_H[]; -extern "C" const uint8_t OmegaPirate_H[]; -extern "C" const uint8_t OverWorld_H[]; -extern "C" const uint8_t Parasite_H[]; -extern "C" const uint8_t PhazonGun_H[]; -extern "C" const uint8_t Phazon_H[]; -extern "C" const uint8_t PuddleSpore_H[]; -extern "C" const uint8_t PuddleToad_H[]; -extern "C" const uint8_t Puffer_H[]; -extern "C" const uint8_t ReactorDoor_H[]; -extern "C" const uint8_t Ridley_H[]; -extern "C" const uint8_t Ripper_H[]; -extern "C" const uint8_t RuinsWorld_H[]; -extern "C" const uint8_t SamusShip_H[]; -extern "C" const uint8_t Scarab_H[]; -extern "C" const uint8_t Seedling_H[]; -extern "C" const uint8_t SheeGoth_H[]; -extern "C" const uint8_t SnakeWeed_H[]; -extern "C" const uint8_t Sova_H[]; -extern "C" const uint8_t SpacePirate_H[]; -extern "C" const uint8_t SpankWeed_H[]; -extern "C" const uint8_t Thardus_H[]; -extern "C" const uint8_t TheEnd_H[]; -extern "C" const uint8_t Torobyte_H[]; -extern "C" const uint8_t Triclops_H[]; -extern "C" const uint8_t Turret_H[]; -extern "C" const uint8_t UI_H[]; -extern "C" const uint8_t WarWasp_H[]; -extern "C" const uint8_t Weapons_H[]; -extern "C" const uint8_t ZZZ_H[]; -extern "C" const uint8_t Zoomer_H[]; -extern "C" const uint8_t lumigek_H[]; -extern "C" const uint8_t test_H[]; - -namespace DataSpec::DNAMP1 { - -using namespace std::literals; - -static const std::pair Headers[] = {{"Atomic"sv, Atomic_H}, - {"BetaBeetle"sv, BetaBeetle_H}, - {"Bird"sv, Bird_H}, - {"BloodFlower"sv, BloodFlower_H}, - {"Burrower"sv, Burrower_H}, - {"ChozoGhost"sv, ChozoGhost_H}, - {"ChubbWeed"sv, ChubbWeed_H}, - {"CineBoots"sv, CineBoots_H}, - {"CineGeneral"sv, CineGeneral_H}, - {"CineGun"sv, CineGun_H}, - {"CineMorphball"sv, CineMorphball_H}, - {"CineSuit"sv, CineSuit_H}, - {"CineVisor"sv, CineVisor_H}, - {"Crater"sv, Crater_H}, - {"Crystallite"sv, Crystallite_H}, - {"Drones"sv, Drones_H}, - {"EliteSpacePirate"sv, EliteSpacePirate_H}, - {"FireFlea"sv, FireFlea_H}, - {"Flaaghra"sv, Flaaghra_H}, - {"FlickerBat"sv, FlickerBat_H}, - {"FlyingPirate"sv, FlyingPirate_H}, - {"FrontEnd"sv, FrontEnd_H}, - {"GagantuanBeatle"sv, GagantuanBeatle_H}, - {"Gnats"sv, Gnats_H}, - {"Gryzbee"sv, Gryzbee_H}, - {"IceCrack"sv, IceCrack_H}, - {"IceWorld"sv, IceWorld_H}, - {"InjuredPirates"sv, InjuredPirates_H}, - {"IntroBoss"sv, IntroBoss_H}, - {"IntroWorld"sv, IntroWorld_H}, - {"JellyZap"sv, JellyZap_H}, - {"LavaWorld"sv, LavaWorld_H}, - {"Magdolite"sv, Magdolite_H}, - {"Metaree"sv, Metaree_H}, - {"MetroidPrime"sv, MetroidPrime_H}, - {"Metroid"sv, Metroid_H}, - {"MinesWorld"sv, MinesWorld_H}, - {"MiscSamus"sv, MiscSamus_H}, - {"Misc"sv, Misc_H}, - {"OmegaPirate"sv, OmegaPirate_H}, - {"OverWorld"sv, OverWorld_H}, - {"Parasite"sv, Parasite_H}, - {"Phazon"sv, Phazon_H}, - {"PhazonGun"sv, PhazonGun_H}, - {"PuddleSpore"sv, PuddleSpore_H}, - {"PuddleToad"sv, PuddleToad_H}, - {"Puffer"sv, Puffer_H}, - {"ReactorDoor"sv, ReactorDoor_H}, - {"Ridley"sv, Ridley_H}, - {"Ripper"sv, Ripper_H}, - {"RuinsWorld"sv, RuinsWorld_H}, - {"SamusShip"sv, SamusShip_H}, - {"Scarab"sv, Scarab_H}, - {"Seedling"sv, Seedling_H}, - {"SheeGoth"sv, SheeGoth_H}, - {"SnakeWeed"sv, SnakeWeed_H}, - {"Sova"sv, Sova_H}, - {"SpacePirate"sv, SpacePirate_H}, - {"SpankWeed"sv, SpankWeed_H}, - {"Thardus"sv, Thardus_H}, - {"TheEnd"sv, TheEnd_H}, - {"Torobyte"sv, Torobyte_H}, - {"Triclops"sv, Triclops_H}, - {"Turret"sv, Turret_H}, - {"UI"sv, UI_H}, - {"WarWasp"sv, WarWasp_H}, - {"Weapons"sv, Weapons_H}, - {"ZZZ"sv, ZZZ_H}, - {"Zoomer"sv, Zoomer_H}, - {"lumigek"sv, lumigek_H}, - {"test"sv, test_H}}; - -bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir) { - dir.makeDirChain(true); - - Header head; - head.read(rs); - - uint32_t poolLen = rs.readUint32Big(); - auto pool = rs.readUBytes(poolLen); - - uint32_t projLen = rs.readUint32Big(); - auto proj = rs.readUBytes(projLen); - - uint32_t sampLen = rs.readUint32Big(); - auto samp = rs.readUBytes(sampLen); - - uint32_t sdirLen = rs.readUint32Big(); - auto sdir = rs.readUBytes(sdirLen); - - amuse::AudioGroupData data(proj.get(), projLen, pool.get(), poolLen, sdir.get(), sdirLen, samp.get(), sampLen, - amuse::GCNDataTag{}); - - /* Load into amuse representation */ - amuse::ProjectDatabase projDb; - projDb.setIdDatabases(); - amuse::AudioGroupDatabase group(data); - group.setGroupPath(dir.getAbsolutePath()); - - /* Extract samples */ - group.getSdir().extractAllCompressed(dir.getAbsolutePath(), data.getSamp()); - - /* Import C headers */ - auto search = std::lower_bound(std::cbegin(Headers), std::cend(Headers), head.groupName, - [](const auto& a, const auto& b) { return a.first < b; }); - if (search != std::cend(Headers) && search->first == head.groupName) - group.importCHeader((char*)search->second); - - /* Write out project/pool */ - { - auto projd = group.getProj().toYAML(); - athena::io::FileWriter fo(hecl::ProjectPath(dir, "!project.yaml").getAbsolutePath()); - if (fo.hasError()) - return false; - fo.writeUBytes(projd.data(), projd.size()); - } - - { - auto poold = group.getPool().toYAML(); - athena::io::FileWriter fo(hecl::ProjectPath(dir, "!pool.yaml").getAbsolutePath()); - if (fo.hasError()) - return false; - fo.writeUBytes(poold.data(), poold.size()); - } - - return true; -} - -static std::atomic_bool DidCook = {false}; - -bool AGSC::Cook(const hecl::ProjectPath& dir, const hecl::ProjectPath& refOutPath) { - /* This will cook all AGSCs in the local directory, ensuring unique ObjectIDs - * across all Amuse subprojects */ - if (DidCook.exchange(true)) - return true; /* We've already cooked all AGSCs */ - - amuse::ProjectDatabase projDb; - projDb.setIdDatabases(); - - auto parentDir = dir.getParentPath(); - auto outParentDir = refOutPath.getParentPath(); - for (const auto& ent : dir.getParentPath().enumerateDir()) { - if (!ent.m_isDir) - continue; - hecl::ProjectPath path(parentDir, ent.m_name); - if (IsPathAudioGroup(path)) { - hecl::ProjectPath outPath(outParentDir, ent.m_name); - athena::io::FileWriter w(outPath.getAbsolutePath()); - if (w.hasError()) - return false; - - Header head; - head.audioDir = "Audio/"sv; - auto lastComp = path.getLastComponent(); - auto str = fmt::format(FMT_STRING("_{:8X}"), path.parsedHash32()); - auto it = lastComp.rfind(str); - if (it != std::string_view::npos) { - lastComp = lastComp.substr(0, it); - } - head.groupName = lastComp; - head.write(w); - - amuse::AudioGroupDatabase group(path.getAbsolutePath()); - - auto proj = group.getProj().toGCNData(group.getPool(), group.getSdir()); - auto pool = group.getPool().toData(); - auto sdirSamp = group.getSdir().toGCNData(group); - - w.writeUint32Big(pool.size()); - w.writeUBytes(pool.data(), pool.size()); - - w.writeUint32Big(proj.size()); - w.writeUBytes(proj.data(), proj.size()); - - w.writeUint32Big(sdirSamp.second.size()); - w.writeUBytes(sdirSamp.second.data(), sdirSamp.second.size()); - - w.writeUint32Big(sdirSamp.first.size()); - w.writeUBytes(sdirSamp.first.data(), sdirSamp.first.size()); - } - } - - return true; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/AGSC.hpp b/DataSpec/DNAMP1/AGSC.hpp deleted file mode 100644 index 7c480e5e5..000000000 --- a/DataSpec/DNAMP1/AGSC.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -class AGSC { -public: - struct Header : BigDNA { - AT_DECL_DNA - String<-1> audioDir; - String<-1> groupName; - }; - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ANCS.cpp b/DataSpec/DNAMP1/ANCS.cpp deleted file mode 100644 index 3de05dd7d..000000000 --- a/DataSpec/DNAMP1/ANCS.cpp +++ /dev/null @@ -1,1442 +0,0 @@ -#include "ANCS.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec { -extern hecl::Database::DataSpecEntry SpecEntMP1; -extern hecl::Database::DataSpecEntry SpecEntMP1PC; - -namespace DNAMP1 { - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::Enumerate( - athena::io::IStreamReader& reader) { - parmType = reader.readUint32Big(); - weightFunction = reader.readUint32Big(); - weight = reader.readFloatBig(); - switch (DataType(parmType)) { - case DataType::Int32: - range[0].int32 = reader.readInt32Big(); - range[1].int32 = reader.readInt32Big(); - break; - case DataType::UInt32: - case DataType::Enum: - range[0].uint32 = reader.readUint32Big(); - range[1].uint32 = reader.readUint32Big(); - break; - case DataType::Float: - range[0].float32 = reader.readFloatBig(); - range[1].float32 = reader.readFloatBig(); - break; - case DataType::Bool: - range[0].bool1 = reader.readBool(); - range[1].bool1 = reader.readBool(); - break; - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::Enumerate( - athena::io::IStreamWriter& writer) { - writer.writeUint32Big(parmType); - writer.writeUint32Big(weightFunction); - writer.writeFloatBig(weight); - switch (DataType(parmType)) { - case DataType::Int32: - writer.writeInt32Big(range[0].int32); - writer.writeInt32Big(range[1].int32); - break; - case DataType::UInt32: - case DataType::Enum: - writer.writeUint32Big(range[0].uint32); - writer.writeUint32Big(range[1].uint32); - break; - case DataType::Float: - writer.writeFloatBig(range[0].float32); - writer.writeFloatBig(range[1].float32); - break; - case DataType::Bool: - writer.writeBool(range[0].bool1); - writer.writeBool(range[1].bool1); - break; - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::Enumerate(size_t& __isz) { - __isz += 12; - switch (DataType(parmType)) { - case DataType::Int32: - case DataType::UInt32: - case DataType::Enum: - case DataType::Float: - __isz += 8; - break; - case DataType::Bool: - __isz += 2; - break; - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::Enumerate( - athena::io::YAMLDocReader& reader) { - parmType = reader.readUint32("parmType"); - weightFunction = reader.readUint32("weightFunction"); - weight = reader.readFloat("weight"); - size_t parmValCount; - if (auto v = reader.enterSubVector("range", parmValCount)) { - switch (DataType(parmType)) { - case DataType::Int32: - range[0].int32 = reader.readInt32(); - range[1].int32 = reader.readInt32(); - break; - case DataType::UInt32: - case DataType::Enum: - range[0].uint32 = reader.readUint32(); - range[1].uint32 = reader.readUint32(); - break; - case DataType::Float: - range[0].float32 = reader.readFloat(); - range[1].float32 = reader.readFloat(); - break; - case DataType::Bool: - range[0].bool1 = reader.readBool(); - range[1].bool1 = reader.readBool(); - break; - default: - break; - } - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::Enumerate( - athena::io::YAMLDocWriter& writer) { - writer.writeUint32("parmType", parmType); - writer.writeUint32("weightFunction", weightFunction); - writer.writeFloat("weight", weight); - if (auto v = writer.enterSubVector("range")) { - switch (DataType(parmType)) { - case DataType::Int32: - writer.writeInt32(range[0].int32); - writer.writeInt32(range[1].int32); - break; - case DataType::UInt32: - case DataType::Enum: - writer.writeUint32(range[0].uint32); - writer.writeUint32(range[1].uint32); - break; - case DataType::Float: - writer.writeFloat(range[0].float32); - writer.writeFloat(range[1].float32); - break; - case DataType::Bool: - writer.writeBool(range[0].bool1); - writer.writeBool(range[1].bool1); - break; - } - } -} - -std::string_view ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::DNAType() { - return "DNAMP1::ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo"sv; -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::Enumerate( - athena::io::IStreamReader& reader) { - id = reader.readUint32Big(); - atUint32 parmInfoCount = reader.readUint32Big(); - atUint32 animInfoCount = reader.readUint32Big(); - - reader.enumerate(parmInfos, parmInfoCount); - - animInfos.clear(); - animInfos.reserve(animInfoCount); - reader.enumerate(animInfos, animInfoCount, - [this, parmInfoCount](athena::io::IStreamReader& reader, AnimInfo& ai) { - ai.id = reader.readUint32Big(); - ai.parmVals.reserve(parmInfoCount); - for (const ParmInfo& pi : parmInfos) { - switch (ParmInfo::DataType(pi.parmType)) { - case ParmInfo::DataType::Int32: - ai.parmVals.emplace_back(reader.readInt32Big()); - break; - case ParmInfo::DataType::UInt32: - case ParmInfo::DataType::Enum: - ai.parmVals.emplace_back(reader.readUint32Big()); - break; - case ParmInfo::DataType::Float: - ai.parmVals.emplace_back(reader.readFloatBig()); - break; - case ParmInfo::DataType::Bool: - ai.parmVals.emplace_back(reader.readBool()); - break; - default: - break; - } - } - }); -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::Enumerate( - athena::io::IStreamWriter& writer) { - writer.writeUint32Big(id); - writer.writeUint32Big(parmInfos.size()); - writer.writeUint32Big(animInfos.size()); - - for (const ParmInfo& pi : parmInfos) - pi.write(writer); - - for (const AnimInfo& ai : animInfos) { - writer.writeUint32Big(ai.id); - auto it = ai.parmVals.begin(); - for (const ParmInfo& pi : parmInfos) { - ParmInfo::Parm pVal; - if (it != ai.parmVals.end()) - pVal = *it++; - switch (ParmInfo::DataType(pi.parmType)) { - case ParmInfo::DataType::Int32: - writer.writeInt32Big(pVal.int32); - break; - case ParmInfo::DataType::UInt32: - case ParmInfo::DataType::Enum: - writer.writeUint32Big(pVal.uint32); - break; - case ParmInfo::DataType::Float: - writer.writeFloatBig(pVal.float32); - break; - case ParmInfo::DataType::Bool: - writer.writeBool(pVal.bool1); - break; - default: - break; - } - } - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::Enumerate(size_t& __isz) { - __isz += 12; - for (const ParmInfo& pi : parmInfos) - pi.binarySize(__isz); - - __isz += animInfos.size() * 4; - for (const ParmInfo& pi : parmInfos) { - switch (ParmInfo::DataType(pi.parmType)) { - case ParmInfo::DataType::Int32: - case ParmInfo::DataType::UInt32: - case ParmInfo::DataType::Enum: - case ParmInfo::DataType::Float: - __isz += animInfos.size() * 4; - break; - case ParmInfo::DataType::Bool: - __isz += animInfos.size(); - break; - default: - break; - } - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::Enumerate( - athena::io::YAMLDocReader& reader) { - id = reader.readUint32("id"); - - size_t parmInfoCount = reader.enumerate("parmInfos", parmInfos); - - reader.enumerate("animInfos", animInfos, - [this, parmInfoCount](athena::io::YAMLDocReader& reader, AnimInfo& ai) { - ai.id = reader.readUint32("id"); - ai.parmVals.reserve(parmInfoCount); - size_t parmValCount; - if (auto v = reader.enterSubVector("parms", parmValCount)) { - for (const ParmInfo& pi : parmInfos) { - switch (ParmInfo::DataType(pi.parmType)) { - case ParmInfo::DataType::Int32: - ai.parmVals.emplace_back(reader.readInt32()); - break; - case ParmInfo::DataType::UInt32: - case ParmInfo::DataType::Enum: - ai.parmVals.emplace_back(reader.readUint32()); - break; - case ParmInfo::DataType::Float: - ai.parmVals.emplace_back(reader.readFloat()); - break; - case ParmInfo::DataType::Bool: - ai.parmVals.emplace_back(reader.readBool()); - break; - default: - break; - } - } - } - }); -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::Enumerate( - athena::io::YAMLDocWriter& writer) { - writer.writeUint32("id", id); - - writer.enumerate("parmInfos", parmInfos); - - writer.enumerate("animInfos", animInfos, [this](athena::io::YAMLDocWriter& writer, const AnimInfo& ai) { - writer.writeUint32("id", ai.id); - auto it = ai.parmVals.begin(); - if (auto v = writer.enterSubVector("parms")) { - for (const ParmInfo& pi : parmInfos) { - ParmInfo::Parm pVal; - if (it != ai.parmVals.end()) - pVal = *it++; - switch (ParmInfo::DataType(pi.parmType)) { - case ParmInfo::DataType::Int32: - writer.writeInt32(pVal.int32); - break; - case ParmInfo::DataType::UInt32: - case ParmInfo::DataType::Enum: - writer.writeUint32(pVal.uint32); - break; - case ParmInfo::DataType::Float: - writer.writeFloat(pVal.float32); - break; - case ParmInfo::DataType::Bool: - writer.writeBool(pVal.bool1); - break; - default: - break; - } - } - } - }); -} - -std::string_view ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::DNAType() { - return "DNAMP1::ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState"sv; -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(athena::io::IStreamReader& reader) { - idx = reader.readUint32Big(); - atUint16 sectionCount = reader.readUint16Big(); - name = reader.readString(); - cmdl.read(reader); - cskr.read(reader); - cinf.read(reader); - - atUint32 animationCount = reader.readUint32Big(); - reader.enumerate(animations, animationCount); - - pasDatabase.read(reader); - - atUint32 partCount = reader.readUint32Big(); - reader.enumerate(partResData.part, partCount); - - atUint32 swhcCount = reader.readUint32Big(); - reader.enumerate(partResData.swhc, swhcCount); - - atUint32 unkCount = reader.readUint32Big(); - reader.enumerate(partResData.unk, unkCount); - - partResData.elsc.clear(); - if (sectionCount > 5) { - atUint32 elscCount = reader.readUint32Big(); - reader.enumerate(partResData.elsc, elscCount); - } - - unk1 = reader.readUint32Big(); - - animAABBs.clear(); - if (sectionCount > 1) { - atUint32 aabbCount = reader.readUint32Big(); - reader.enumerate(animAABBs, aabbCount); - } - - effects.clear(); - if (sectionCount > 2) { - atUint32 effectCount = reader.readUint32Big(); - reader.enumerate(effects, effectCount); - } - - if (sectionCount > 3) { - cmdlIce.read(reader); - cskrIce.read(reader); - } - - animIdxs.clear(); - if (sectionCount > 4) { - atUint32 aidxCount = reader.readUint32Big(); - reader.enumerateBig(animIdxs, aidxCount); - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(athena::io::IStreamWriter& writer) { - writer.writeUint32Big(idx); - - atUint16 sectionCount; - if (partResData.elsc.size()) - sectionCount = 6; - else if (animIdxs.size()) - sectionCount = 5; - else if (cmdlIce.isValid()) - sectionCount = 4; - else if (effects.size()) - sectionCount = 3; - else if (animAABBs.size()) - sectionCount = 2; - else - sectionCount = 1; - writer.writeUint16Big(sectionCount); - - writer.writeString(name); - cmdl.write(writer); - cskr.write(writer); - cinf.write(writer); - - writer.writeUint32Big(animations.size()); - writer.enumerate(animations); - - pasDatabase.write(writer); - - writer.writeUint32Big(partResData.part.size()); - writer.enumerate(partResData.part); - - writer.writeUint32Big(partResData.swhc.size()); - writer.enumerate(partResData.swhc); - - writer.writeUint32Big(partResData.unk.size()); - writer.enumerate(partResData.unk); - - if (sectionCount > 5) { - writer.writeUint32Big(partResData.elsc.size()); - writer.enumerate(partResData.elsc); - } - - writer.writeUint32Big(unk1); - - if (sectionCount > 1) { - writer.writeUint32Big(animAABBs.size()); - writer.enumerate(animAABBs); - } - - if (sectionCount > 2) { - writer.writeUint32Big(effects.size()); - writer.enumerate(effects); - } - - if (sectionCount > 3) { - cmdlIce.write(writer); - cskrIce.write(writer); - } - - if (sectionCount > 4) { - writer.writeUint32Big(animIdxs.size()); - for (atUint32 idx : animIdxs) - writer.writeUint32Big(idx); - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(size_t& __isz) { - __isz += 6; - - atUint16 sectionCount; - if (partResData.elsc.size()) - sectionCount = 6; - else if (animIdxs.size()) - sectionCount = 5; - else if (cmdlIce.isValid()) - sectionCount = 4; - else if (effects.size()) - sectionCount = 3; - else if (animAABBs.size()) - sectionCount = 2; - else - sectionCount = 1; - - __isz += name.size() + 1; - __isz += 12; - - __isz += 4; - for (const Animation& a : animations) - a.binarySize(__isz); - - pasDatabase.binarySize(__isz); - - __isz += 4; - for (const UniqueID32& id : partResData.part) - id.binarySize(__isz); - - __isz += 4; - for (const UniqueID32& id : partResData.swhc) - id.binarySize(__isz); - - __isz += 4; - for (const UniqueID32& id : partResData.unk) - id.binarySize(__isz); - - if (sectionCount > 5) { - __isz += 4; - for (const UniqueID32& id : partResData.elsc) - id.binarySize(__isz); - } - - __isz += 4; - - if (sectionCount > 1) { - __isz += 4; - for (const ActionAABB& aabb : animAABBs) - aabb.binarySize(__isz); - } - - if (sectionCount > 2) { - __isz += 4; - for (const Effect& e : effects) - e.binarySize(__isz); - } - - if (sectionCount > 3) - __isz += 8; - - if (sectionCount > 4) - __isz += 4 + animIdxs.size() * 4; -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(athena::io::YAMLDocReader& reader) { - idx = reader.readUint32("idx"); - atUint16 sectionCount = reader.readUint16("sectionCount"); - name = reader.readString("name"); - reader.enumerate("cmdl", cmdl); - - reader.enumerate("animations", animations); - - reader.enumerate("pasDatabase", pasDatabase); - - reader.enumerate("part", partResData.part); - - reader.enumerate("swhc", partResData.swhc); - - reader.enumerate("unk", partResData.unk); - - partResData.elsc.clear(); - if (sectionCount > 5) { - reader.enumerate("elsc", partResData.elsc); - } - - unk1 = reader.readUint32("unk1"); - - animAABBs.clear(); - if (sectionCount > 1) { - reader.enumerate("part", animAABBs); - } - - effects.clear(); - if (sectionCount > 2) { - reader.enumerate("effects", effects); - } - - if (sectionCount > 3) { - reader.enumerate("cmdlIce", cmdlIce); - } - - animIdxs.clear(); - if (sectionCount > 4) { - reader.enumerate("animIdxs", animIdxs); - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(athena::io::YAMLDocWriter& writer) { - writer.writeUint32("idx", idx); - - atUint16 sectionCount; - if (partResData.elsc.size()) - sectionCount = 6; - else if (animIdxs.size()) - sectionCount = 5; - else if (cmdlIce.isValid()) - sectionCount = 4; - else if (effects.size()) - sectionCount = 3; - else if (animAABBs.size()) - sectionCount = 2; - else - sectionCount = 1; - writer.writeUint16("sectionCount", sectionCount); - - writer.writeString("name", name); - writer.enumerate("cmdl", cmdl); - - writer.enumerate("animations", animations); - - writer.enumerate("pasDatabase", pasDatabase); - - writer.enumerate("part", partResData.part); - - writer.enumerate("swhc", partResData.swhc); - - writer.enumerate("unk", partResData.unk); - - if (sectionCount > 5) { - writer.enumerate("elsc", partResData.elsc); - } - - writer.writeUint32("unk1", unk1); - - if (sectionCount > 1) { - writer.enumerate("animAABBs", animAABBs); - } - - if (sectionCount > 2) { - writer.enumerate("effects", effects); - } - - if (sectionCount > 3) { - writer.enumerate("cmdlIce", cmdlIce); - } - - if (sectionCount > 4) { - writer.enumerate("animIdxs", animIdxs); - } -} - -std::string_view ANCS::CharacterSet::CharacterInfo::DNAType() { return "DNAMP1::ANCS::CharacterSet::CharacterInfo"sv; } - -template <> -void ANCS::AnimationSet::MetaAnimFactory::Enumerate(athena::io::IStreamReader& reader) { - const auto type = IMetaAnim::Type(reader.readUint32Big()); - switch (type) { - case IMetaAnim::Type::Primitive: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::Blend: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::PhaseBlend: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::Random: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::Sequence: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - default: - m_anim.reset(); - break; - } -} - -template <> -void ANCS::AnimationSet::MetaAnimFactory::Enumerate(athena::io::IStreamWriter& writer) { - if (!m_anim) - return; - writer.writeInt32Big(atUint32(m_anim->m_type)); - m_anim->write(writer); -} - -template <> -void ANCS::AnimationSet::MetaAnimFactory::Enumerate(size_t& __isz) { - if (!m_anim) - return; - __isz += 4; - m_anim->binarySize(__isz); -} - -template <> -void ANCS::AnimationSet::MetaAnimFactory::Enumerate(athena::io::YAMLDocReader& reader) { - std::string type = reader.readString("type"); - std::transform(type.begin(), type.end(), type.begin(), tolower); - if (type == "primitive") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "blend") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "phaseblend") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "random") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "sequence") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else { - m_anim.reset(); - } -} - -template <> -void ANCS::AnimationSet::MetaAnimFactory::Enumerate(athena::io::YAMLDocWriter& writer) { - if (!m_anim) - return; - writer.writeString("type", m_anim->m_typeStr); - m_anim->write(writer); -} - -std::string_view ANCS::AnimationSet::MetaAnimFactory::DNAType() { - return "DNAMP1::ANCS::AnimationSet::MetaAnimFactory"sv; -} - -template <> -void ANCS::AnimationSet::MetaTransFactory::Enumerate(athena::io::IStreamReader& reader) { - IMetaTrans::Type type(IMetaTrans::Type(reader.readUint32Big())); - switch (type) { - case IMetaTrans::Type::MetaAnim: - m_trans = std::make_unique(); - m_trans->read(reader); - break; - case IMetaTrans::Type::Trans: - m_trans = std::make_unique(); - m_trans->read(reader); - break; - case IMetaTrans::Type::PhaseTrans: - m_trans = std::make_unique(); - m_trans->read(reader); - break; - case IMetaTrans::Type::NoTrans: - default: - m_trans.reset(); - break; - } -} - -template <> -void ANCS::AnimationSet::MetaTransFactory::Enumerate(athena::io::IStreamWriter& writer) { - if (!m_trans) { - writer.writeInt32Big(atUint32(IMetaTrans::Type::NoTrans)); - return; - } - writer.writeInt32Big(atUint32(m_trans->m_type)); - m_trans->write(writer); -} - -template <> -void ANCS::AnimationSet::MetaTransFactory::Enumerate(size_t& __isz) { - __isz += 4; - if (!m_trans) - return; - m_trans->binarySize(__isz); -} - -template <> -void ANCS::AnimationSet::MetaTransFactory::Enumerate(athena::io::YAMLDocReader& reader) { - std::string type = reader.readString("type"); - std::transform(type.begin(), type.end(), type.begin(), tolower); - if (type == "metaanim") { - m_trans = std::make_unique(); - m_trans->read(reader); - } else if (type == "trans") { - m_trans = std::make_unique(); - m_trans->read(reader); - } else if (type == "phasetrans") { - m_trans = std::make_unique(); - m_trans->read(reader); - } else { - m_trans.reset(); - } -} - -template <> -void ANCS::AnimationSet::MetaTransFactory::Enumerate(athena::io::YAMLDocWriter& writer) { - if (!m_trans) { - writer.writeString("type", "NoTrans"); - return; - } - writer.writeString("type", m_trans->m_typeStr ? m_trans->m_typeStr : "NoTrans"); - m_trans->write(writer); -} - -std::string_view ANCS::AnimationSet::MetaTransFactory::DNAType() { - return "DNAMP1::ANCS::AnimationSet::MetaTransFactory"sv; -} - -template <> -void ANCS::AnimationSet::Enumerate(athena::io::IStreamReader& reader) { - atUint16 sectionCount = reader.readUint16Big(); - - atUint32 animationCount = reader.readUint32Big(); - reader.enumerate(animations, animationCount); - - atUint32 transitionCount = reader.readUint32Big(); - reader.enumerate(transitions, transitionCount); - defaultTransition.read(reader); - - additiveAnims.clear(); - if (sectionCount > 1) { - atUint32 additiveAnimCount = reader.readUint32Big(); - reader.enumerate(additiveAnims, additiveAnimCount); - additiveDefaultFadeInDur = reader.readFloatBig(); - additiveDefaultFadeOutDur = reader.readFloatBig(); - } - - halfTransitions.clear(); - if (sectionCount > 2) { - atUint32 halfTransitionCount = reader.readUint32Big(); - reader.enumerate(halfTransitions, halfTransitionCount); - } - - animResources.clear(); - if (sectionCount > 3) { - atUint32 animResourcesCount = reader.readUint32Big(); - reader.enumerate(animResources, animResourcesCount); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(athena::io::IStreamWriter& writer) { - atUint16 sectionCount; - if (animResources.size()) - sectionCount = 4; - else if (halfTransitions.size()) - sectionCount = 3; - else if (additiveAnims.size()) - sectionCount = 2; - else - sectionCount = 1; - - writer.writeUint16Big(sectionCount); - - writer.writeUint32Big(animations.size()); - writer.enumerate(animations); - - writer.writeUint32Big(transitions.size()); - writer.enumerate(transitions); - defaultTransition.write(writer); - - if (sectionCount > 1) { - writer.writeUint32Big(additiveAnims.size()); - writer.enumerate(additiveAnims); - writer.writeFloatBig(additiveDefaultFadeInDur); - writer.writeFloatBig(additiveDefaultFadeOutDur); - } - - if (sectionCount > 2) { - writer.writeUint32Big(halfTransitions.size()); - writer.enumerate(halfTransitions); - } - - if (sectionCount > 3) { - writer.writeUint32Big(animResources.size()); - writer.enumerate(animResources); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(size_t& __isz) { - atUint16 sectionCount; - if (animResources.size()) - sectionCount = 4; - else if (halfTransitions.size()) - sectionCount = 3; - else if (additiveAnims.size()) - sectionCount = 2; - else - sectionCount = 1; - - __isz += 6; - for (const Animation& a : animations) - a.binarySize(__isz); - - __isz += 4; - for (const Transition& t : transitions) - t.binarySize(__isz); - defaultTransition.binarySize(__isz); - - if (sectionCount > 1) { - __isz += 4; - for (const AdditiveAnimationInfo& aa : additiveAnims) - aa.binarySize(__isz); - __isz += 8; - } - - if (sectionCount > 2) { - __isz += 4; - for (const HalfTransition& ht : halfTransitions) - ht.binarySize(__isz); - } - - if (sectionCount > 3) { - __isz += 4; - for (const AnimationResources& ar : animResources) - ar.binarySize(__isz); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(athena::io::YAMLDocReader& reader) { - atUint16 sectionCount = reader.readUint16("sectionCount"); - - reader.enumerate("animations", animations); - - reader.enumerate("transitions", transitions); - reader.enumerate("defaultTransition", defaultTransition); - - additiveAnims.clear(); - if (sectionCount > 1) { - reader.enumerate("additiveAnims", additiveAnims); - additiveDefaultFadeInDur = reader.readFloat("additiveDefaultFadeInDur"); - additiveDefaultFadeOutDur = reader.readFloat("additiveDefaultFadeOutDur"); - } - - halfTransitions.clear(); - if (sectionCount > 2) { - reader.enumerate("halfTransitions", halfTransitions); - } - - animResources.clear(); - if (sectionCount > 3) { - reader.enumerate("animResources", animResources); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(athena::io::YAMLDocWriter& writer) { - atUint16 sectionCount; - if (animResources.size()) - sectionCount = 4; - else if (halfTransitions.size()) - sectionCount = 3; - else if (additiveAnims.size()) - sectionCount = 2; - else - sectionCount = 1; - - writer.writeUint16("sectionCount", sectionCount); - - writer.enumerate("animations", animations); - - writer.enumerate("transitions", transitions); - writer.enumerate("defaultTransition", defaultTransition); - - if (sectionCount > 1) { - writer.enumerate("additiveAnims", additiveAnims); - writer.writeFloat("additiveDefaultFadeInDur", additiveDefaultFadeInDur); - writer.writeFloat("additiveDefaultFadeOutDur", additiveDefaultFadeOutDur); - } - - if (sectionCount > 2) { - writer.enumerate("halfTransitions", halfTransitions); - } - - if (sectionCount > 3) { - writer.enumerate("animResources", animResources); - } -} - -void ANCS::AnimationSet::MetaAnimPrimitive::gatherPrimitives( - PAKRouter* pakRouter, std::map>& out) { - if (!pakRouter) { - out[animIdx] = {animName, animId, UniqueID32(), false}; - return; - } - - const nod::Node* node; - const PAK::Entry* entry = pakRouter->lookupEntry(animId, &node, true); - if (!entry) { - out[animIdx] = {animName, animId, UniqueID32(), false}; - return; - } - - PAKEntryReadStream rs = entry->beginReadStream(*node); - out[animIdx] = {animName, animId, ANIM::GetEVNTId(rs), false}; -} - -std::string_view ANCS::AnimationSet::DNAType() { return "DNAMP1::ANCS::AnimationSet"sv; } - -bool ANCS::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - hecl::ProjectPath yamlPath = outPath.getWithExtension(".yaml", true); - hecl::ProjectPath::Type yamlType = yamlPath.getPathType(); - hecl::ProjectPath blendPath = outPath.getWithExtension(".blend", true); - hecl::ProjectPath::Type blendType = blendPath.getPathType(); - - ANCS ancs; - ancs.read(rs); - - if (force || yamlType == hecl::ProjectPath::Type::None || blendType == hecl::ProjectPath::Type::None) { - if (force || yamlType == hecl::ProjectPath::Type::None) { - athena::io::FileWriter writer(yamlPath.getAbsolutePath()); - athena::io::ToYAMLStream(ancs, writer); - } - - if (force || blendType == hecl::ProjectPath::Type::None) { - DNAANCS::ReadANCSToBlender, ANCS, MaterialSet, DNACMDL::SurfaceHeader_1, 2>( - btok, ancs, blendPath, pakRouter, entry, dataSpec, fileChanged, force); - } - } - - return true; -} - -bool ANCS::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor) { - /* Search for yaml */ - hecl::ProjectPath yamlPath = inPath.getWithExtension(".yaml", true); - if (!yamlPath.isFile()) - Log.report(logvisor::Fatal, FMT_STRING("'{}' not found as file"), yamlPath.getRelativePath()); - - athena::io::FileReader reader(yamlPath.getAbsolutePath()); - if (!reader.isOpen()) - Log.report(logvisor::Fatal, FMT_STRING("can't open '{}' for reading"), yamlPath.getRelativePath()); - - if (!athena::io::ValidateFromYAMLStream(reader)) { - Log.report(logvisor::Fatal, FMT_STRING("'{}' is not DNAMP1::ANCS type"), yamlPath.getRelativePath()); - } - - athena::io::YAMLDocReader yamlReader; - if (!yamlReader.parse(&reader)) { - Log.report(logvisor::Fatal, FMT_STRING("unable to parse '{}'"), yamlPath.getRelativePath()); - } - ANCS ancs; - ancs.read(yamlReader); - - /* Set Character Resource IDs */ - for (ANCS::CharacterSet::CharacterInfo& ch : ancs.characterSet.characters) { - ch.cmdl = UniqueID32{}; - ch.cskr = UniqueID32{}; - ch.cinf = UniqueID32{}; - ch.cmdlIce = UniqueID32Zero{}; - ch.cskrIce = UniqueID32Zero{}; - - int subtypeIdx = 0; - ch.animAABBs.clear(); - for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) { - if (sub.name == ch.name) { - if (!sub.cskrId.empty()) { - ch.cskr = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.CSKR"), ch.name, sub.cskrId)); - } else { - ch.cskr = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}.CSKR"), ch.name)); - } - - /* Add subtype AABBs */ - ch.animAABBs.reserve(actor.actions.size()); - for (const DNAANCS::Action& act : actor.actions) { - const auto& sourceAABB = act.subtypeAABBs[subtypeIdx]; - ch.animAABBs.emplace_back(); - auto& destAABB = ch.animAABBs.back(); - destAABB.name = act.name; - destAABB.aabb[0] = sourceAABB.first.val; - destAABB.aabb[1] = sourceAABB.second.val; - } - - if (sub.armature >= 0) { - const DNAANCS::Armature& arm = actor.armatures[sub.armature]; - ch.cinf = arm.path; - ch.cmdl = sub.mesh; - auto search = std::find_if(sub.overlayMeshes.cbegin(), sub.overlayMeshes.cend(), - [](const auto& p) { return p.name == "ICE"; }); - if (search != sub.overlayMeshes.cend()) { - ch.cmdlIce = search->mesh; - if (!search->cskrId.empty()) { - ch.cskrIce = inPath.ensureAuxInfo( - fmt::format(FMT_STRING("{}.{}_{}.CSKR"), ch.name, search->name, search->cskrId)); - } else { - ch.cskrIce = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}.{}.CSKR"), ch.name, search->name)); - } - } - } - - break; - } - ++subtypeIdx; - } - - std::sort(ch.animAABBs.begin(), ch.animAABBs.end(), - [](const ANCS::CharacterSet::CharacterInfo::ActionAABB& a, - const ANCS::CharacterSet::CharacterInfo::ActionAABB& b) { return a.name < b.name; }); - } - - /* Set Animation Resource IDs */ - ancs.enumeratePrimitives([&](AnimationSet::MetaAnimPrimitive& prim) { - for (const DNAANCS::Action& act : actor.actions) { - if (act.name == prim.animName) { - hecl::ProjectPath pathOut; - if (!act.animId.empty()) { - pathOut = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.ANIM"), prim.animName, act.animId)); - } else { - inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}.ANIM"), prim.animName)); - } - prim.animId = pathOut; - break; - } - } - return true; - }); - - /* Gather ANIM resources */ - hecl::DirectoryEnumerator dEnum(inPath.getParentPath().getAbsolutePath()); - ancs.animationSet.animResources.reserve(actor.actions.size()); - for (const DNAANCS::Action& act : actor.actions) { - hecl::ProjectPath pathOut; - if (!act.animId.empty()) { - pathOut = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.ANIM"), act.name, act.animId)); - } else { - pathOut = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}.ANIM"), act.name)); - } - - ancs.animationSet.animResources.emplace_back(); - ancs.animationSet.animResources.back().animId = pathOut; - - /* Check for associated EVNT YAML */ - std::string testPrefix( - inPath.getWithExtension(fmt::format(FMT_STRING(".{}_"), act.name).c_str(), true).getLastComponent()); - hecl::ProjectPath evntYamlPath; - for (const auto& ent : dEnum) { - if (hecl::StringUtils::BeginsWith(ent.m_name, testPrefix.c_str()) && - hecl::StringUtils::EndsWith(ent.m_name, ".evnt.yaml")) { - evntYamlPath = hecl::ProjectPath(inPath.getParentPath(), ent.m_name); - break; - } - } - if (evntYamlPath.isFile()) { - evntYamlPath = evntYamlPath.ensureAuxInfo(""); - ancs.animationSet.animResources.back().evntId = evntYamlPath; - } - } - - /* Write out ANCS */ - athena::io::TransactionalFileWriter w(outPath.getAbsolutePath()); - ancs.write(w); - - return true; -} - -static const std::regex regCskrNameId(R"((.*)_[0-9a-fA-F]{8}\.CSKR)", - std::regex::ECMAScript | std::regex::optimize); -static const std::regex regCskrName(R"((.*)\.CSKR)", std::regex::ECMAScript | std::regex::optimize); - -bool ANCS::CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, - const std::function& modelCookFunc) { - auto auxInfo = inPath.getAuxInfo(); - std::match_results match; - if (!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrNameId) && - !std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrName)) - return false; - - std::string subName = match[1].str(); - std::string overName; - auto dotPos = subName.rfind('.'); - if (dotPos != std::string::npos) { - overName = std::string(subName.begin() + dotPos + 1, subName.end()); - subName = std::string(subName.begin(), subName.begin() + dotPos); - } - - /* Build bone ID map */ - std::unordered_map boneIdMap; - for (const DNAANCS::Armature& arm : actor.armatures) { - CINF cinf(*arm.armature, boneIdMap); - } - - const DNAANCS::Actor::Subtype* subtype = nullptr; - if (subName != "ATTACH") { - for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) { - if (sub.name == subName) { - subtype = ⊂ - break; - } - } - if (!subtype) - Log.report(logvisor::Fatal, FMT_STRING("unable to find subtype '{}'"), subName); - } - - const hecl::ProjectPath* modelPath = nullptr; - if (subName == "ATTACH") { - const DNAANCS::Actor::Attachment* attachment = nullptr; - for (const DNAANCS::Actor::Attachment& att : actor.attachments) { - if (att.name == overName) { - attachment = &att; - break; - } - } - if (!attachment) - Log.report(logvisor::Fatal, FMT_STRING("unable to find attachment '{}'"), overName); - modelPath = &attachment->mesh; - } else if (overName.empty()) { - modelPath = &subtype->mesh; - } else { - for (const auto& overlay : subtype->overlayMeshes) - if (overlay.name == overName) { - modelPath = &overlay.mesh; - break; - } - } - if (!modelPath) - Log.report(logvisor::Fatal, FMT_STRING("unable to resolve model path of {}:{}"), subName, overName); - - if (!modelPath->isFile()) - Log.report(logvisor::Fatal, FMT_STRING("unable to resolve '{}'"), modelPath->getRelativePath()); - - hecl::ProjectPath skinIntPath = modelPath->getCookedPath(SpecEntMP1).getWithExtension(".skinint"); - if (!skinIntPath.isFileOrGlob() || skinIntPath.getModtime() < modelPath->getModtime()) - if (!modelCookFunc(*modelPath)) - Log.report(logvisor::Fatal, FMT_STRING("unable to cook '{}'"), modelPath->getRelativePath()); - - std::vector>, uint32_t>> skins; - uint32_t posCount = 0; - uint32_t normCount = 0; - athena::io::FileReader skinIO(skinIntPath.getAbsolutePath(), 1024 * 32, false); - if (!skinIO.hasError()) { - std::vector boneNames; - uint32_t boneNameCount = skinIO.readUint32Big(); - boneNames.reserve(boneNameCount); - for (uint32_t i = 0; i < boneNameCount; ++i) - boneNames.push_back(skinIO.readString()); - - uint32_t skinCount = skinIO.readUint32Big(); - skins.resize(skinCount); - for (uint32_t i = 0; i < skinCount; ++i) { - std::pair>, uint32_t>& virtualBone = skins[i]; - uint32_t bindCount = skinIO.readUint32Big(); - virtualBone.first.reserve(bindCount); - for (uint32_t j = 0; j < bindCount; ++j) { - uint32_t bIdx = skinIO.readUint32Big(); - float weight = skinIO.readFloatBig(); - const std::string& name = boneNames[bIdx]; - auto search = boneIdMap.find(name); - if (search == boneIdMap.cend()) - Log.report(logvisor::Fatal, FMT_STRING("unable to find bone '{}' in {}"), name, inPath.getRelativePath()); - virtualBone.first.emplace_back(search->second, weight); - } - virtualBone.second = skinIO.readUint32Big(); - } - - posCount = skinIO.readUint32Big(); - normCount = skinIO.readUint32Big(); - - skinIO.close(); - } - - athena::io::TransactionalFileWriter skinOut(outPath.getAbsolutePath()); - - skinOut.writeUint32Big(skins.size()); - for (auto& virtuaBone : skins) { - skinOut.writeUint32Big(virtuaBone.first.size()); - for (auto& bind : virtuaBone.first) { - skinOut.writeUint32Big(bind.first); - skinOut.writeFloatBig(bind.second); - } - skinOut.writeUint32Big(virtuaBone.second); - } - - skinOut.writeUint32Big(0xffffffff); - skinOut.writeUint32Big(posCount); - skinOut.writeUint32Big(0xffffffff); - skinOut.writeUint32Big(normCount); - - return true; -} - -bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, - const std::function& modelCookFunc) { - auto auxInfo = inPath.getAuxInfo(); - std::match_results match; - if (!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrNameId) && - !std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrName)) - return false; - - std::string subName = match[1].str(); - std::string overName; - auto dotPos = subName.rfind('.'); - if (dotPos != std::string::npos) { - overName = std::string(subName.begin() + dotPos + 1, subName.end()); - subName = std::string(subName.begin(), subName.begin() + dotPos); - } - - /* Build bone ID map */ - std::unordered_map boneIdMap; - for (const DNAANCS::Armature& arm : actor.armatures) { - CINF cinf(*arm.armature, boneIdMap); - } - - const DNAANCS::Actor::Subtype* subtype = nullptr; - if (subName != "ATTACH") { - for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) { - if (sub.name == subName) { - subtype = ⊂ - break; - } - } - if (!subtype) - Log.report(logvisor::Fatal, FMT_STRING("unable to find subtype '{}'"), subName); - } - - const hecl::ProjectPath* modelPath = nullptr; - if (subName == "ATTACH") { - const DNAANCS::Actor::Attachment* attachment = nullptr; - for (const DNAANCS::Actor::Attachment& att : actor.attachments) { - if (att.name == overName) { - attachment = &att; - break; - } - } - if (!attachment) - Log.report(logvisor::Fatal, FMT_STRING("unable to find attachment '{}'"), overName); - modelPath = &attachment->mesh; - } else if (overName.empty()) { - modelPath = &subtype->mesh; - } else { - for (const auto& overlay : subtype->overlayMeshes) - if (overlay.name == overName) { - modelPath = &overlay.mesh; - break; - } - } - if (!modelPath) - Log.report(logvisor::Fatal, FMT_STRING("unable to resolve model path of {}:{}"), subName, overName); - - if (!modelPath->isFile()) - Log.report(logvisor::Fatal, FMT_STRING("unable to resolve '{}'"), modelPath->getRelativePath()); - - hecl::ProjectPath skinIntPath = modelPath->getCookedPath(SpecEntMP1PC).getWithExtension(".skinint"); - if (!skinIntPath.isFileOrGlob() || skinIntPath.getModtime() < modelPath->getModtime()) - if (!modelCookFunc(*modelPath)) - Log.report(logvisor::Fatal, FMT_STRING("unable to cook '{}'"), modelPath->getRelativePath()); - - uint32_t bankCount = 0; - std::vector> skinBanks; - std::vector boneNames; - std::vector>> skins; - atUint64 uniquePoolIndexLen = 0; - std::unique_ptr uniquePoolIndexData; - athena::io::FileReader skinIO(skinIntPath.getAbsolutePath(), 1024 * 32, false); - if (!skinIO.hasError()) { - bankCount = skinIO.readUint32Big(); - skinBanks.reserve(bankCount); - for (uint32_t i = 0; i < bankCount; ++i) { - skinBanks.emplace_back(); - std::vector& bonesOut = skinBanks.back(); - uint32_t boneCount = skinIO.readUint32Big(); - bonesOut.reserve(boneCount); - for (uint32_t j = 0; j < boneCount; ++j) { - uint32_t idx = skinIO.readUint32Big(); - bonesOut.push_back(idx); - } - } - - uint32_t boneNameCount = skinIO.readUint32Big(); - boneNames.reserve(boneNameCount); - for (uint32_t i = 0; i < boneNameCount; ++i) - boneNames.push_back(skinIO.readString()); - - uint32_t skinCount = skinIO.readUint32Big(); - skins.resize(skinCount); - for (uint32_t i = 0; i < skinCount; ++i) { - std::vector>& virtualBone = skins[i]; - uint32_t bindCount = skinIO.readUint32Big(); - virtualBone.reserve(bindCount); - for (uint32_t j = 0; j < bindCount; ++j) { - uint32_t bIdx = skinIO.readUint32Big(); - float weight = skinIO.readFloatBig(); - const std::string& name = boneNames[bIdx]; - auto search = boneIdMap.find(name); - if (search == boneIdMap.cend()) - Log.report(logvisor::Fatal, FMT_STRING("unable to find bone '{}' in {}"), name, inPath.getRelativePath()); - virtualBone.emplace_back(search->second, weight); - } - } - - uniquePoolIndexLen = skinIO.length() - skinIO.position(); - uniquePoolIndexData = skinIO.readUBytes(uniquePoolIndexLen); - - skinIO.close(); - } - - athena::io::TransactionalFileWriter skinOut(outPath.getAbsolutePath()); - - skinOut.writeUint32Big(bankCount); - for (const std::vector& bank : skinBanks) { - skinOut.writeUint32Big(bank.size()); - for (uint32_t bIdx : bank) { - const std::string& name = boneNames[bIdx]; - auto search = boneIdMap.find(name); - if (search == boneIdMap.cend()) - Log.report(logvisor::Fatal, FMT_STRING("unable to find bone '{}' in {}"), name, inPath.getRelativePath()); - skinOut.writeUint32Big(search->second); - } - } - - skinOut.writeUint32Big(skins.size()); - for (auto& virtuaBone : skins) { - skinOut.writeUint32Big(virtuaBone.size()); - for (auto& bind : virtuaBone) { - skinOut.writeUint32Big(bind.first); - skinOut.writeFloatBig(bind.second); - } - } - - if (uniquePoolIndexLen) - skinOut.writeUBytes(uniquePoolIndexData.get(), uniquePoolIndexLen); - - return true; -} - -static const std::regex regAnimNameId(R"((.*)_[0-9a-fA-F]{8}\.ANIM)", - std::regex::ECMAScript | std::regex::optimize); -static const std::regex regAnimName(R"((.*)\.ANIM)", std::regex::ECMAScript | std::regex::optimize); - -bool ANCS::CookANIM(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, - hecl::blender::DataStream& ds, bool pc) { - auto auxInfo = inPath.getAuxInfo(); - std::match_results match; - if (!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regAnimNameId) && - !std::regex_search(auxInfo.begin(), auxInfo.end(), match, regAnimName)) - return false; - - std::string actName = match[1].str(); - DNAANCS::Action action = ds.compileActionChannelsOnly(actName); - - if (!actor.armatures.size()) - Log.report(logvisor::Fatal, FMT_STRING("0 armatures in {}"), inPath.getRelativePath()); - - /* Build bone ID map */ - std::unordered_map boneIdMap; - std::optional rigCinf; - std::optional> rigInv; - for (const DNAANCS::Armature& arm : actor.armatures) { - if (!rigInv) { - rigCinf.emplace(*arm.armature, boneIdMap); - auto matrices = ds.getBoneMatrices(arm.name); - rigInv.emplace(*rigCinf, matrices); - } else { - CINF cinf(*arm.armature, boneIdMap); - } - } - - ANIM anim(action, boneIdMap, *rigInv, pc); - - /* Check for associated EVNT YAML */ - std::string testPrefix( - inPath.getWithExtension(fmt::format(FMT_STRING(".{}_"), actName).c_str(), true).getLastComponent()); - hecl::ProjectPath evntYamlPath; - for (const auto& ent : hecl::DirectoryEnumerator(inPath.getParentPath().getAbsolutePath())) { - if (hecl::StringUtils::BeginsWith(ent.m_name, testPrefix.c_str()) && - hecl::StringUtils::EndsWith(ent.m_name, ".evnt.yaml")) { - evntYamlPath = hecl::ProjectPath(inPath.getParentPath(), ent.m_name); - break; - } - } - if (evntYamlPath.isFile()) { - evntYamlPath = evntYamlPath.ensureAuxInfo(""); - anim.m_anim->evnt = evntYamlPath; - } - - /* Write out ANIM resource */ - athena::io::TransactionalFileWriter w(outPath.getAbsolutePath()); - anim.write(w); - return true; -} - -} // namespace DNAMP1 -} // namespace DataSpec diff --git a/DataSpec/DNAMP1/ANCS.hpp b/DataSpec/DNAMP1/ANCS.hpp deleted file mode 100644 index 9e00da1e4..000000000 --- a/DataSpec/DNAMP1/ANCS.hpp +++ /dev/null @@ -1,420 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ANCS.hpp" -#include "CMDLMaterials.hpp" -#include "CINF.hpp" -#include "CSKR.hpp" -#include "ANIM.hpp" -#include "EVNT.hpp" -#include "athena/FileReader.hpp" - -namespace DataSpec::DNAMP1 { - -struct ANCS : BigDNA { - using CINFType = CINF; - using CSKRType = CSKR; - using ANIMType = ANIM; - - AT_DECL_DNA_YAML - Value version; - - struct CharacterSet : BigDNA { - AT_DECL_DNA_YAML - Value version; - Value characterCount; - struct CharacterInfo : BigDNA { - AT_DECL_DNA_YAML - Delete expl; - - atUint32 idx; - std::string name; - UniqueID32 cmdl; - UniqueID32 cskr; - UniqueID32 cinf; - - struct Animation : BigDNA { - AT_DECL_DNA_YAML - Value animIdx; - String<-1> strA; - String<-1> strB; - }; - std::vector animations; - - struct PASDatabase : BigDNA { - AT_DECL_DNA_YAML - Value magic; - Value animStateCount; - Value defaultState; - struct AnimState : BigDNA { - AT_DECL_DNA_YAML - Delete expl; - atUint32 id; - - struct ParmInfo : BigDNA { - AT_DECL_DNA_YAML - Delete expl; - enum class DataType { Int32 = 0, UInt32 = 1, Float = 2, Bool = 3, Enum = 4 }; - union Parm { - atInt32 int32; - atUint32 uint32; - float float32; - bool bool1; - Parm() : int32(0) {} - Parm(atInt32 val) : int32(val) {} - Parm(atUint32 val) : uint32(val) {} - Parm(float val) : float32(val) {} - Parm(bool val) : bool1(val) {} - }; - - atUint32 parmType; - atUint32 weightFunction; - float weight; - Parm range[2]; - }; - std::vector parmInfos; - - struct AnimInfo { - atUint32 id; - std::vector parmVals; - }; - std::vector animInfos; - }; - Vector animStates; - } pasDatabase; - - struct ParticleResData { - std::vector part; - std::vector swhc; - std::vector unk; - std::vector elsc; - } partResData; - - atUint32 unk1 = 0; - - struct ActionAABB : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value aabb[2]; - }; - std::vector animAABBs; - - struct Effect : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value compCount; - struct EffectComponent : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - DNAFourCC type; - UniqueID32 id; - String<-1> locator; - Value scale; - Value parentMode; - Value flags; - }; - Vector comps; - }; - std::vector effects; - - UniqueID32Zero cmdlIce; - UniqueID32Zero cskrIce; - - std::vector animIdxs; - }; - Vector characters; - } characterSet; - - struct AnimationSet : BigDNA { - AT_DECL_DNA_YAML - Delete expl; - - struct MetaAnimPrimitive; - struct IMetaAnim : BigDNAVYaml { - Delete expl; - enum class Type { Primitive = 0, Blend = 1, PhaseBlend = 2, Random = 3, Sequence = 4 } m_type; - const char* m_typeStr; - IMetaAnim(Type type, const char* typeStr) : m_type(type), m_typeStr(typeStr) {} - virtual void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) = 0; - virtual bool enumeratePrimitives(const std::function& func) = 0; - }; - struct MetaAnimFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - std::unique_ptr m_anim; - }; - struct MetaAnimPrimitive : IMetaAnim { - AT_DECL_DNA_YAMLV - MetaAnimPrimitive() : IMetaAnim(Type::Primitive, "Primitive") {} - - UniqueID32 animId; - Value animIdx; - String<-1> animName; - Value unk1; - Value unk2; - - void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) override; - - bool enumeratePrimitives(const std::function& func) override { - return func(*this); - } - }; - struct MetaAnimBlend : IMetaAnim { - MetaAnimBlend() : IMetaAnim(Type::Blend, "Blend") {} - AT_DECL_DNA_YAMLV - MetaAnimFactory animA; - MetaAnimFactory animB; - Value unkFloat; - Value unk; - - void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) override { - animA.m_anim->gatherPrimitives(pakRouter, out); - animB.m_anim->gatherPrimitives(pakRouter, out); - } - - bool enumeratePrimitives(const std::function& func) override { - if (!animA.m_anim->enumeratePrimitives(func)) - return false; - if (!animB.m_anim->enumeratePrimitives(func)) - return false; - return true; - } - }; - struct MetaAnimPhaseBlend : IMetaAnim { - MetaAnimPhaseBlend() : IMetaAnim(Type::PhaseBlend, "PhaseBlend") {} - AT_DECL_DNA_YAMLV - MetaAnimFactory animA; - MetaAnimFactory animB; - Value unkFloat; - Value unk; - - void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) override { - animA.m_anim->gatherPrimitives(pakRouter, out); - animB.m_anim->gatherPrimitives(pakRouter, out); - } - - bool enumeratePrimitives(const std::function& func) override { - if (!animA.m_anim->enumeratePrimitives(func)) - return false; - if (!animB.m_anim->enumeratePrimitives(func)) - return false; - return true; - } - }; - struct MetaAnimRandom : IMetaAnim { - MetaAnimRandom() : IMetaAnim(Type::Random, "Random") {} - AT_DECL_DNA_YAMLV - Value animCount; - struct Child : BigDNA { - AT_DECL_DNA - MetaAnimFactory anim; - Value probability; - }; - Vector children; - - void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) override { - for (const auto& child : children) - child.anim.m_anim->gatherPrimitives(pakRouter, out); - } - - bool enumeratePrimitives(const std::function& func) override { - for (auto& child : children) - if (!child.anim.m_anim->enumeratePrimitives(func)) - return false; - return true; - } - }; - struct MetaAnimSequence : IMetaAnim { - MetaAnimSequence() : IMetaAnim(Type::Sequence, "Sequence") {} - AT_DECL_DNA_YAMLV - Value animCount; - Vector children; - - void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) override { - for (const auto& child : children) - child.m_anim->gatherPrimitives(pakRouter, out); - } - - bool enumeratePrimitives(const std::function& func) override { - for (auto& child : children) - if (!child.m_anim->enumeratePrimitives(func)) - return false; - return true; - } - }; - - struct Animation : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - MetaAnimFactory metaAnim; - }; - std::vector animations; - - struct IMetaTrans : BigDNAVYaml { - Delete expl; - enum class Type { - MetaAnim = 0, - Trans = 1, - PhaseTrans = 2, - NoTrans = 3, - } m_type; - const char* m_typeStr; - IMetaTrans(Type type, const char* typeStr) : m_type(type), m_typeStr(typeStr) {} - virtual void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) {} - virtual bool enumeratePrimitives(const std::function& func) { return true; } - }; - struct MetaTransFactory : BigDNA { - AT_DECL_DNA_YAML - Delete expl; - std::unique_ptr m_trans; - }; - struct MetaTransMetaAnim : IMetaTrans { - MetaTransMetaAnim() : IMetaTrans(Type::MetaAnim, "MetaAnim") {} - AT_DECL_DNA_YAMLV - MetaAnimFactory anim; - - void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) override { - anim.m_anim->gatherPrimitives(pakRouter, out); - } - - bool enumeratePrimitives(const std::function& func) override { - return anim.m_anim->enumeratePrimitives(func); - } - }; - struct MetaTransTrans : IMetaTrans { - MetaTransTrans() : IMetaTrans(Type::Trans, "Trans") {} - AT_DECL_DNA_YAMLV - Value transDurTime; - Value transDurTimeMode; - Value unk2; - Value runA; - Value flags; - }; - struct MetaTransPhaseTrans : IMetaTrans { - MetaTransPhaseTrans() : IMetaTrans(Type::PhaseTrans, "PhaseTrans") {} - AT_DECL_DNA_YAMLV - Value transDurTime; - Value transDurTimeMode; - Value unk2; - Value runA; - Value flags; - }; - - struct Transition : BigDNA { - AT_DECL_DNA_YAML - Value unk; - Value animIdxA; - Value animIdxB; - MetaTransFactory metaTrans; - }; - std::vector transitions; - MetaTransFactory defaultTransition; - - struct AdditiveAnimationInfo : BigDNA { - AT_DECL_DNA_YAML - Value animIdx; - Value fadeInDur; - Value fadeOutDur; - }; - std::vector additiveAnims; - - float additiveDefaultFadeInDur = 0.0; - float additiveDefaultFadeOutDur = 0.0; - - struct HalfTransition : BigDNA { - AT_DECL_DNA_YAML - Value animIdx; - MetaTransFactory metaTrans; - }; - std::vector halfTransitions; - - struct AnimationResources : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 animId; - UniqueID32 evntId; - }; - std::vector animResources; - } animationSet; - - void getCharacterResInfo(std::vector>& out) const { - out.clear(); - out.reserve(characterSet.characters.size()); - for (const CharacterSet::CharacterInfo& ci : characterSet.characters) { - out.emplace_back(); - DNAANCS::CharacterResInfo& chOut = out.back(); - chOut.name = ci.name; - chOut.cmdl = ci.cmdl; - chOut.cskr = ci.cskr; - chOut.cinf = ci.cinf; - - if (ci.cmdlIce.isValid()) - chOut.overlays.emplace_back("ICE", std::make_pair(ci.cmdlIce, ci.cskrIce)); - } - } - - void getAnimationResInfo(PAKRouter* pakRouter, - std::map>& out) const { - out.clear(); - for (const AnimationSet::Animation& ai : animationSet.animations) - if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get()) - anim->gatherPrimitives(pakRouter, out); - for (const AnimationSet::Transition& ti : animationSet.transitions) - if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get()) - trans->gatherPrimitives(pakRouter, out); - if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get()) - trans->gatherPrimitives(pakRouter, out); - } - - void enumeratePrimitives(const std::function& func) { - for (const AnimationSet::Animation& ai : animationSet.animations) - if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get()) - anim->enumeratePrimitives(func); - for (const AnimationSet::Transition& ti : animationSet.transitions) - if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get()) - trans->enumeratePrimitives(func); - if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get()) - trans->enumeratePrimitives(func); - } - - void gatherDependencies(std::vector& pathsOut, int charIdx) const { - auto doCi = [&](const CharacterSet::CharacterInfo& ci) { - for (const auto& id : ci.partResData.part) - g_curSpec->flattenDependencies(id, pathsOut); - for (const auto& id : ci.partResData.swhc) - g_curSpec->flattenDependencies(id, pathsOut); - for (const auto& id : ci.partResData.unk) - g_curSpec->flattenDependencies(id, pathsOut); - for (const auto& id : ci.partResData.elsc) - g_curSpec->flattenDependencies(id, pathsOut); - }; - if (charIdx < 0) - for (const CharacterSet::CharacterInfo& ci : characterSet.characters) - doCi(ci); - else if (charIdx < characterSet.characters.size()) - doCi(characterSet.characters[charIdx]); - } - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged); - - static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor); - - static bool CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, - const std::function& modelCookFunc); - static bool CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, - const std::function& modelCookFunc); - - static bool CookANIM(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, - hecl::blender::DataStream& ds, bool pc); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ANIM.cpp b/DataSpec/DNAMP1/ANIM.cpp deleted file mode 100644 index 7768ec25c..000000000 --- a/DataSpec/DNAMP1/ANIM.cpp +++ /dev/null @@ -1,624 +0,0 @@ -#include "ANIM.hpp" -#include "zeus/CVector3f.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -using ANIMOutStream = hecl::blender::ANIMOutStream; - -void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter& rig) const { - os.format(FMT_STRING("act.hecl_fps = round({})\n" - "act.hecl_looping = {}\n"), - (1.0f / mainInterval), looping ? "True" : "False"); - - auto kit = chanKeys.begin(); - - std::vector fixedRotKeys; - std::vector fixedTransKeys; - - for (const std::pair& bone : bones) { - const std::string* bName = rig.getCINF().getBoneNameFromId(bone.first); - if (!bName) { - ++kit; - if (bone.second) - ++kit; - continue; - } - - os.format(FMT_STRING("bone_string = '{}'\n"), *bName); - os << "action_group = act.groups.new(bone_string)\n" - "\n" - "rotCurves = []\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=0, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=1, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=2, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=3, " - "action_group=bone_string))\n" - "\n"; - - if (bone.second) - os << "transCurves = []\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=0, " - "action_group=bone_string))\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=1, " - "action_group=bone_string))\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=2, " - "action_group=bone_string))\n" - "\n"; - - ANIMOutStream ao = os.beginANIMCurve(); - - { - const std::vector& rotKeys = *kit++; - fixedRotKeys.clear(); - fixedRotKeys.resize(rotKeys.size()); - - for (int c = 0; c < 4; ++c) { - size_t idx = 0; - for (const DNAANIM::Value& val : rotKeys) - fixedRotKeys[idx++][c] = val.simd[c]; - } - - for (zeus::CQuaternion& rot : fixedRotKeys) - rot = rig.invertRotation(bone.first, rot); - - for (int c = 0; c < 4; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Rotate, c, rotKeys.size()); - for (const zeus::CQuaternion& val : fixedRotKeys) - ao.write(*frameit++, val[c]); - } - } - - if (bone.second) { - const std::vector& transKeys = *kit++; - fixedTransKeys.clear(); - fixedTransKeys.resize(transKeys.size()); - - for (int c = 0; c < 3; ++c) { - size_t idx = 0; - for (const DNAANIM::Value& val : transKeys) - fixedTransKeys[idx++][c] = val.simd[c]; - } - - for (zeus::CVector3f& t : fixedTransKeys) - t = rig.invertPosition(bone.first, t, true); - - for (int c = 0; c < 3; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Translate, c, fixedTransKeys.size()); - for (const zeus::CVector3f& val : fixedTransKeys) - ao.write(*frameit++, val[c]); - } - } - } -} - -UniqueID32 ANIM::GetEVNTId(athena::io::IStreamReader& reader) { - atUint32 version = reader.readUint32Big(); - switch (version) { - case 0: { - ANIM0 anim0; - anim0.read(reader); - return anim0.evnt; - } - case 2: - case 3: - reader.seek(4); - return reader.readUint32Big(); - default: - Log.report(logvisor::Error, FMT_STRING("unrecognized ANIM version")); - break; - } - return {}; -} - -template <> -void ANIM::Enumerate(typename Read::StreamT& reader) { - atUint32 version = reader.readUint32Big(); - switch (version) { - case 0: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case 2: - m_anim = std::make_unique(false); - m_anim->read(reader); - break; - case 3: - m_anim = std::make_unique(true); - m_anim->read(reader); - break; - default: - Log.report(logvisor::Error, FMT_STRING("unrecognized ANIM version")); - break; - } -} - -template <> -void ANIM::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(m_anim->m_version); - m_anim->write(writer); -} - -template <> -void ANIM::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - m_anim->binarySize(s); -} - -std::string_view ANIM::ANIM0::DNAType() { return "ANIM0"sv; } - -template <> -void ANIM::ANIM0::Enumerate(athena::io::IStreamReader& reader) { - Header head; - head.read(reader); - mainInterval = head.interval; - - frames.clear(); - frames.reserve(head.keyCount); - for (size_t k = 0; k < head.keyCount; ++k) - frames.push_back(k); - - std::map boneMap; - for (size_t b = 0; b < head.boneSlotCount; ++b) { - atUint8 idx = reader.readUByte(); - if (idx == 0xff) - continue; - boneMap[idx] = b; - } - - atUint32 boneCount = reader.readUint32Big(); - bones.clear(); - bones.reserve(boneCount); - channels.clear(); - for (size_t b = 0; b < boneCount; ++b) { - bones.emplace_back(boneMap[b], false); - atUint8 idx = reader.readUByte(); - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Rotation; - if (idx != 0xff) { - bones.back().second = true; - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Translation; - } - } - - reader.readUint32Big(); - chanKeys.clear(); - chanKeys.reserve(channels.size()); - for (const std::pair& bone : bones) { - chanKeys.emplace_back(); - std::vector& keys = chanKeys.back(); - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec4fBig()); - - if (bone.second) - chanKeys.emplace_back(); - } - - reader.readUint32Big(); - auto kit = chanKeys.begin(); - for (const std::pair& bone : bones) { - ++kit; - if (bone.second) { - std::vector& keys = *kit++; - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec3fBig()); - } - } - - evnt.read(reader); -} - -template <> -void ANIM::ANIM0::Enumerate(athena::io::IStreamWriter& writer) { - Header head; - head.unk0 = 0; - head.unk1 = 0; - head.unk2 = 0; - head.keyCount = frames.size(); - head.duration = head.keyCount * mainInterval; - head.interval = mainInterval; - - atUint32 maxId = 0; - for (const std::pair& bone : bones) - maxId = std::max(maxId, bone.first); - head.boneSlotCount = maxId + 1; - head.write(writer); - - for (size_t s = 0; s < head.boneSlotCount; ++s) { - size_t boneIdx = 0; - bool found = false; - for (const std::pair& bone : bones) { - if (s == bone.first) { - writer.writeUByte(boneIdx); - found = true; - break; - } - ++boneIdx; - } - if (!found) - writer.writeUByte(0xff); - } - - writer.writeUint32Big(bones.size()); - size_t boneIdx = 0; - for (const std::pair& bone : bones) { - if (bone.second) - writer.writeUByte(boneIdx); - else - writer.writeUByte(0xff); - ++boneIdx; - } - - writer.writeUint32Big(bones.size() * head.keyCount); - auto cit = chanKeys.begin(); - atUint32 transKeyCount = 0; - for (const std::pair& bone : bones) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec4fBig(atVec4f{(*kit++).simd}); - if (bone.second) { - transKeyCount += head.keyCount; - ++cit; - } - } - - writer.writeUint32Big(transKeyCount); - cit = chanKeys.begin(); - for (const std::pair& bone : bones) { - ++cit; - if (bone.second) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec3fBig(atVec3f{(*kit++).simd}); - } - } - - evnt.write(writer); -} - -template <> -void ANIM::ANIM0::Enumerate(size_t& __isz) { - Header head; - - atUint32 maxId = 0; - for (const std::pair& bone : bones) - maxId = std::max(maxId, bone.first); - - head.binarySize(__isz); - __isz += maxId + 1; - __isz += bones.size() + 4; - - __isz += 8; - for (const std::pair& bone : bones) { - __isz += head.keyCount * 16; - if (bone.second) - __isz += head.keyCount * 12; - } - - __isz += 4; -} - -std::string_view ANIM::ANIM2::DNAType() { return "ANIM2"sv; } - -template <> -void ANIM::ANIM2::Enumerate(athena::io::IStreamReader& reader) { - Header head; - head.read(reader); - evnt = head.evnt; - mainInterval = head.interval; - looping = bool(head.looping); - - WordBitmap keyBmp; - keyBmp.read(reader, head.keyBitmapBitCount); - frames.clear(); - atUint32 frameAccum = 0; - for (bool bit : keyBmp) { - if (bit) - frames.push_back(frameAccum); - ++frameAccum; - } - reader.seek(8); - - bones.clear(); - bones.reserve(head.boneChannelCount); - channels.clear(); - channels.reserve(head.boneChannelCount); - atUint32 keyframeCount = 0; - - if (m_version == 3) { - for (size_t b = 0; b < head.boneChannelCount; ++b) { - ChannelDescPC desc; - desc.read(reader); - bones.emplace_back(desc.id, desc.keyCount2 != 0); - - if (desc.keyCount1) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Rotation; - chan.id = desc.id; - chan.i[0] = atInt32(desc.QinitRX) >> 8; - chan.q[0] = desc.QinitRX & 0xff; - chan.i[1] = atInt32(desc.QinitRY) >> 8; - chan.q[1] = desc.QinitRY & 0xff; - chan.i[2] = atInt32(desc.QinitRZ) >> 8; - chan.q[2] = desc.QinitRZ & 0xff; - } - keyframeCount = std::max(keyframeCount, desc.keyCount1); - - if (desc.keyCount2) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Translation; - chan.id = desc.id; - chan.i[0] = atInt32(desc.QinitTX) >> 8; - chan.q[0] = desc.QinitTX & 0xff; - chan.i[1] = atInt32(desc.QinitTY) >> 8; - chan.q[1] = desc.QinitTY & 0xff; - chan.i[2] = atInt32(desc.QinitTZ) >> 8; - chan.q[2] = desc.QinitTZ & 0xff; - } - } - } else { - for (size_t b = 0; b < head.boneChannelCount; ++b) { - ChannelDesc desc; - desc.read(reader); - bones.emplace_back(desc.id, desc.keyCount2 != 0); - - if (desc.keyCount1) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Rotation; - chan.id = desc.id; - chan.i[0] = desc.initRX; - chan.q[0] = desc.qRX; - chan.i[1] = desc.initRY; - chan.q[1] = desc.qRY; - chan.i[2] = desc.initRZ; - chan.q[2] = desc.qRZ; - } - keyframeCount = std::max(keyframeCount, atUint32(desc.keyCount1)); - - if (desc.keyCount2) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Translation; - chan.id = desc.id; - chan.i[0] = desc.initTX; - chan.q[0] = desc.qTX; - chan.i[1] = desc.initTY; - chan.q[1] = desc.qTY; - chan.i[2] = desc.initTZ; - chan.q[2] = desc.qTZ; - } - } - } - - size_t bsSize = DNAANIM::ComputeBitstreamSize(keyframeCount, channels); - std::unique_ptr bsData = reader.readUBytes(bsSize); - DNAANIM::BitstreamReader bsReader; - chanKeys = bsReader.read(bsData.get(), keyframeCount, channels, head.rotDiv, head.translationMult, 0.f); -} - -template <> -void ANIM::ANIM2::Enumerate(athena::io::IStreamWriter& writer) { - Header head; - head.evnt = evnt; - head.unk0 = 1; - head.interval = mainInterval; - head.rootBoneId = 3; - head.looping = looping; - head.unk3 = 1; - - WordBitmap keyBmp; - size_t frameCount = 0; - for (atUint32 frame : frames) { - if (!keyBmp.getBit(frame)) { - keyBmp.setBit(frame); - frameCount += 1; - } - } - head.keyBitmapBitCount = keyBmp.getBitCount(); - head.duration = frames.back() * mainInterval; - head.boneChannelCount = bones.size(); - - size_t keyframeCount = frameCount - 1; - std::vector qChannels = channels; - DNAANIM::BitstreamWriter bsWriter; - size_t bsSize; - float scaleMult; - std::unique_ptr bsData = - bsWriter.write(chanKeys, keyframeCount, qChannels, m_version == 3 ? 0x7fffff : 0x7fff, head.rotDiv, - head.translationMult, scaleMult, bsSize); - - /* Tally up buffer size */ - size_t scratchSize = 0; - head.binarySize(scratchSize); - keyBmp.binarySize(scratchSize); - scratchSize += bsSize; - if (m_version == 3) { - for (const std::pair& bone : bones) { - ChannelDescPC desc; - desc.keyCount1 = keyframeCount; - if (bone.second) - desc.keyCount2 = keyframeCount; - desc.binarySize(scratchSize); - } - } else { - for (const std::pair& bone : bones) { - ChannelDesc desc; - desc.keyCount1 = keyframeCount; - if (bone.second) - desc.keyCount2 = keyframeCount; - desc.binarySize(scratchSize); - } - } - head.scratchSize = scratchSize; - - head.write(writer); - keyBmp.write(writer); - writer.writeUint32Big(head.boneChannelCount); - writer.writeUint32Big(head.boneChannelCount); - auto cit = qChannels.begin(); - - if (m_version == 3) { - for (const std::pair& bone : bones) { - ChannelDescPC desc; - desc.id = bone.first; - DNAANIM::Channel& chan = *cit++; - desc.keyCount1 = keyframeCount; - desc.QinitRX = (chan.i[0] << 8) | chan.q[0]; - desc.QinitRY = (chan.i[1] << 8) | chan.q[1]; - desc.QinitRZ = (chan.i[2] << 8) | chan.q[2]; - if (bone.second) { - DNAANIM::Channel& chan = *cit++; - desc.keyCount2 = keyframeCount; - desc.QinitTX = (chan.i[0] << 8) | chan.q[0]; - desc.QinitTY = (chan.i[1] << 8) | chan.q[1]; - desc.QinitTZ = (chan.i[2] << 8) | chan.q[2]; - } - desc.write(writer); - } - } else { - for (const std::pair& bone : bones) { - ChannelDesc desc; - desc.id = bone.first; - DNAANIM::Channel& chan = *cit++; - desc.keyCount1 = keyframeCount; - desc.initRX = chan.i[0]; - desc.qRX = chan.q[0]; - desc.initRY = chan.i[1]; - desc.qRY = chan.q[1]; - desc.initRZ = chan.i[2]; - desc.qRZ = chan.q[2]; - if (bone.second) { - DNAANIM::Channel& chan = *cit++; - desc.keyCount2 = keyframeCount; - desc.initTX = chan.i[0]; - desc.qTX = chan.q[0]; - desc.initTY = chan.i[1]; - desc.qTY = chan.q[1]; - desc.initTZ = chan.i[2]; - desc.qTZ = chan.q[2]; - } - desc.write(writer); - } - } - - writer.writeUBytes(bsData.get(), bsSize); -} - -template <> -void ANIM::ANIM2::Enumerate(size_t& __isz) { - Header head; - - WordBitmap keyBmp; - for (atUint32 frame : frames) - keyBmp.setBit(frame); - - head.binarySize(__isz); - keyBmp.binarySize(__isz); - __isz += 8; - if (m_version == 3) { - for (const std::pair& bone : bones) { - __isz += 24; - if (bone.second) - __isz += 12; - } - } else { - for (const std::pair& bone : bones) { - __isz += 17; - if (bone.second) - __isz += 9; - } - } - - __isz += DNAANIM::ComputeBitstreamSize(frames.size(), channels); -} - -ANIM::ANIM(const BlenderAction& act, const std::unordered_map& idMap, - const DNAANIM::RigInverter& rig, bool pc) { - m_anim = std::make_unique(pc); - IANIM& newAnim = *m_anim; - newAnim.looping = act.looping; - - newAnim.bones.reserve(act.channels.size()); - size_t extChanCount = 0; - std::unordered_set addedBones; - addedBones.reserve(act.channels.size()); - for (const BlenderAction::Channel& chan : act.channels) { - auto search = idMap.find(chan.boneName); - if (search == idMap.cend()) { - Log.report(logvisor::Warning, FMT_STRING("unable to find id for bone '{}'"), chan.boneName); - continue; - } - if (addedBones.find(search->second) != addedBones.cend()) - continue; - addedBones.insert(search->second); - - extChanCount += std::max(zeus::PopCount(chan.attrMask), 2); - newAnim.bones.emplace_back(search->second, (chan.attrMask & 0x2) != 0); - } - - newAnim.frames.reserve(act.frames.size()); - for (int32_t frame : act.frames) - newAnim.frames.push_back(frame); - - newAnim.channels.reserve(extChanCount); - newAnim.chanKeys.reserve(extChanCount); - - for (const BlenderAction::Channel& chan : act.channels) { - auto search = idMap.find(chan.boneName); - if (search == idMap.cend()) - continue; - - newAnim.channels.emplace_back(); - DNAANIM::Channel& newChan = newAnim.channels.back(); - newChan.type = DNAANIM::Channel::Type::Rotation; - newChan.id = search->second; - - newAnim.chanKeys.emplace_back(); - std::vector& rotVals = newAnim.chanKeys.back(); - rotVals.reserve(chan.keys.size()); - float sign = 0.f; - for (const BlenderAction::Channel::Key& key : chan.keys) { - zeus::CQuaternion q(key.rotation.val); - q = rig.restoreRotation(newChan.id, q); - if (sign == 0.f) - sign = q.w() < 0.f ? -1.f : 1.f; - q *= sign; - q.normalize(); - rotVals.emplace_back(q.mSimd); - } - - if (chan.attrMask & 0x2) { - newAnim.channels.emplace_back(); - DNAANIM::Channel& newChan = newAnim.channels.back(); - newChan.type = DNAANIM::Channel::Type::Translation; - newChan.id = search->second; - - newAnim.chanKeys.emplace_back(); - std::vector& transVals = newAnim.chanKeys.back(); - transVals.reserve(chan.keys.size()); - for (const BlenderAction::Channel::Key& key : chan.keys) { - zeus::CVector3f pos(key.position.val); - pos = rig.restorePosition(newChan.id, pos, true); - transVals.emplace_back(pos.mSimd); - } - } - } - - /* Retro's original data uses microsecond precision */ - newAnim.mainInterval = std::trunc(act.interval * 1000000.0) / 1000000.0; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ANIM.hpp b/DataSpec/DNAMP1/ANIM.hpp deleted file mode 100644 index e1983ebe5..000000000 --- a/DataSpec/DNAMP1/ANIM.hpp +++ /dev/null @@ -1,214 +0,0 @@ -#pragma once - -#include "DNAMP1.hpp" -#include "DataSpec/DNACommon/ANIM.hpp" -#include "DataSpec/DNACommon/RigInverter.hpp" -#include "CINF.hpp" -#include "EVNT.hpp" -#include "DataSpec/DNACommon/ANCS.hpp" - -namespace DataSpec::DNAMP1 { - -struct ANIM : BigDNA { - AT_DECL_EXPLICIT_DNA - - static UniqueID32 GetEVNTId(athena::io::IStreamReader& r); - - struct IANIM : BigDNAV { - Delete expl; - atUint32 m_version; - IANIM(atUint32 version) : m_version(version) {} - - std::vector> bones; - std::vector frames; - std::vector channels; - std::vector> chanKeys; - float mainInterval = 0.0; - UniqueID32Zero evnt; - bool looping = false; - - void sendANIMToBlender(hecl::blender::PyOutStream&, const DNAANIM::RigInverter& rig) const; - }; - - struct ANIM0 : IANIM { - AT_DECL_EXPLICIT_DNAV - ANIM0() : IANIM(0) {} - - struct Header : BigDNA { - AT_DECL_DNA - Value duration; - Value unk0; - Value interval; - Value unk1; - Value keyCount; - Value unk2; - Value boneSlotCount; - }; - }; - - struct ANIM2 : IANIM { - AT_DECL_EXPLICIT_DNAV - ANIM2(bool pc) : IANIM(pc ? 3 : 2) {} - - struct Header : BigDNA { - AT_DECL_DNA - Value scratchSize; - UniqueID32Zero evnt; - Value unk0 = 1; - Value duration; - Value interval; - Value rootBoneId = 3; - Value looping = 0; - Value rotDiv; - Value translationMult; - Value boneChannelCount; - Value unk3; - Value keyBitmapBitCount; - }; - - struct ChannelDesc : BigDNA { - Delete expl; - Value id = 0; - Value keyCount1 = 0; - Value initRX = 0; - Value qRX = 0; - Value initRY = 0; - Value qRY = 0; - Value initRZ = 0; - Value qRZ = 0; - Value keyCount2 = 0; - Value initTX = 0; - Value qTX = 0; - Value initTY = 0; - Value qTY = 0; - Value initTZ = 0; - Value qTZ = 0; - - void read(athena::io::IStreamReader& reader) { - id = reader.readUint32Big(); - keyCount1 = reader.readUint16Big(); - initRX = reader.readInt16Big(); - qRX = reader.readUByte(); - initRY = reader.readInt16Big(); - qRY = reader.readUByte(); - initRZ = reader.readInt16Big(); - qRZ = reader.readUByte(); - keyCount2 = reader.readUint16Big(); - if (keyCount2) { - initTX = reader.readInt16Big(); - qTX = reader.readUByte(); - initTY = reader.readInt16Big(); - qTY = reader.readUByte(); - initTZ = reader.readInt16Big(); - qTZ = reader.readUByte(); - } - } - void write(athena::io::IStreamWriter& writer) const { - writer.writeUint32Big(id); - writer.writeUint16Big(keyCount1); - writer.writeInt16Big(initRX); - writer.writeUByte(qRX); - writer.writeInt16Big(initRY); - writer.writeUByte(qRY); - writer.writeInt16Big(initRZ); - writer.writeUByte(qRZ); - writer.writeUint16Big(keyCount2); - if (keyCount2) { - writer.writeInt16Big(initTX); - writer.writeUByte(qTX); - writer.writeInt16Big(initTY); - writer.writeUByte(qTY); - writer.writeInt16Big(initTZ); - writer.writeUByte(qTZ); - } - } - void binarySize(size_t& __isz) const { - __isz += 17; - if (keyCount2) - __isz += 9; - } - }; - - struct ChannelDescPC : BigDNA { - Delete expl; - Value id = 0; - Value keyCount1 = 0; - Value QinitRX = 0; - Value QinitRY = 0; - Value QinitRZ = 0; - Value keyCount2 = 0; - Value QinitTX = 0; - Value QinitTY = 0; - Value QinitTZ = 0; - - void read(athena::io::IStreamReader& reader) { - id = reader.readUint32Big(); - keyCount1 = reader.readUint32Big(); - QinitRX = reader.readUint32Big(); - QinitRY = reader.readUint32Big(); - QinitRZ = reader.readUint32Big(); - keyCount2 = reader.readUint32Big(); - if (keyCount2) { - QinitTX = reader.readUint32Big(); - QinitTY = reader.readUint32Big(); - QinitTZ = reader.readUint32Big(); - } - } - void write(athena::io::IStreamWriter& writer) const { - writer.writeUint32Big(id); - writer.writeUint32Big(keyCount1); - writer.writeUint32Big(QinitRX); - writer.writeUint32Big(QinitRY); - writer.writeUint32Big(QinitRZ); - writer.writeUint32Big(keyCount2); - if (keyCount2) { - writer.writeUint32Big(QinitTX); - writer.writeUint32Big(QinitTY); - writer.writeUint32Big(QinitTZ); - } - } - void binarySize(size_t& __isz) const { - __isz += 24; - if (keyCount2) - __isz += 12; - } - }; - }; - - std::unique_ptr m_anim; - - void sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter& rig, bool) const { - m_anim->sendANIMToBlender(os, rig); - } - - bool isLooping() const { - if (!m_anim) - return false; - return m_anim->looping; - } - - void extractEVNT(const DNAANCS::AnimationResInfo& animInfo, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, bool force) const { - if (m_anim->evnt.isValid()) { - hecl::ProjectPath evntYamlPath = outPath.getWithExtension( - fmt::format(FMT_STRING(".{}_{}.evnt.yaml"), animInfo.name, m_anim->evnt).c_str(), true); - hecl::ProjectPath::Type evntYamlType = evntYamlPath.getPathType(); - - if (force || evntYamlType == hecl::ProjectPath::Type::None) { - EVNT evnt; - if (pakRouter.lookupAndReadDNA(m_anim->evnt, evnt, true)) { - athena::io::FileWriter writer(evntYamlPath.getAbsolutePath()); - athena::io::ToYAMLStream(evnt, writer); - } - } - } - } - - using BlenderAction = hecl::blender::Action; - - ANIM() = default; - ANIM(const BlenderAction& act, const std::unordered_map& idMap, - const DNAANIM::RigInverter& rig, bool pc); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CINF.cpp b/DataSpec/DNAMP1/CINF.cpp deleted file mode 100644 index 4a4773147..000000000 --- a/DataSpec/DNAMP1/CINF.cpp +++ /dev/null @@ -1,198 +0,0 @@ -#include "CINF.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -atUint32 CINF::getInternalBoneIdxFromId(atUint32 id) const { - atUint32 idx = 0; - for (const Bone& b : bones) { - if (b.id == id) - return idx; - ++idx; - } - return -1; -} - -atUint32 CINF::getBoneIdxFromId(atUint32 id) const { - atUint32 idx = 0; - for (atUint32 bid : boneIds) { - if (bid == id) - return idx; - ++idx; - } - return 0; -} - -const std::string* CINF::getBoneNameFromId(atUint32 id) const { - for (const Name& name : names) - if (id == name.boneId) - return &name.name; - return nullptr; -} - -void CINF::sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const { - for (atUint32 bid : boneIds) { - for (const Name& name : names) { - if (name.boneId == bid) { - os.format(FMT_STRING("obj.vertex_groups.new(name='{}')\n"), name.name); - break; - } - } - } -} - -void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& cinfId) const { - DNAANIM::RigInverter inverter(*this); - - os.format(FMT_STRING("arm = bpy.data.armatures.new('CINF_{}')\n" - "arm_obj = bpy.data.objects.new(arm.name, arm)\n" - "bpy.context.scene.collection.objects.link(arm_obj)\n" - "bpy.context.view_layer.objects.active = arm_obj\n" - "bpy.ops.object.mode_set(mode='EDIT')\n" - "arm_bone_table = {{}}\n"), - cinfId); - - for (const DNAANIM::RigInverter::Bone& bone : inverter.getBones()) { - zeus::simd_floats originF(bone.m_origBone.origin.simd); - zeus::simd_floats tailF(bone.m_tail.mSimd); - os.format(FMT_STRING("bone = arm.edit_bones.new('{}')\n" - "bone.head = ({},{},{})\n" - "bone.tail = ({},{},{})\n" - "bone.use_inherit_scale = False\n" - "arm_bone_table[{}] = bone\n"), - *getBoneNameFromId(bone.m_origBone.id), originF[0], originF[1], originF[2], tailF[0], tailF[1], tailF[2], - bone.m_origBone.id); - } - - for (const Bone& bone : bones) - if (bone.parentId != 2) - os.format(FMT_STRING("arm_bone_table[{}].parent = arm_bone_table[{}]\n"), bone.id, bone.parentId); - - os << "bpy.ops.object.mode_set(mode='OBJECT')\n"; - - for (const DNAANIM::RigInverter::Bone& bone : inverter.getBones()) - os.format(FMT_STRING("arm_obj.pose.bones['{}'].rotation_mode = 'QUATERNION'\n"), - *getBoneNameFromId(bone.m_origBone.id)); -} - -std::string CINF::GetCINFArmatureName(const UniqueID32& cinfId) { return fmt::format(FMT_STRING("CINF_{}"), cinfId); } - -int CINF::RecursiveAddArmatureBone(const Armature& armature, const BlenderBone* bone, int parent, int& curId, - std::unordered_map& idMap, - std::map& nameMap) { - int selId; - auto search = idMap.find(bone->name); - if (search == idMap.end()) { - selId = curId++; - idMap.emplace(std::make_pair(bone->name, selId)); - } else - selId = search->second; - - bones.emplace_back(); - Bone& boneOut = bones.back(); - nameMap[bone->name] = selId; - boneOut.id = selId; - boneOut.parentId = parent; - boneOut.origin = bone->origin; - boneOut.linkedCount = bone->children.size() + 1; - boneOut.linked.reserve(boneOut.linkedCount); - - const BlenderBone* child; - boneOut.linked.push_back(parent); - for (size_t i = 0; (child = armature.getChild(bone, i)); ++i) - boneOut.linked.push_back(RecursiveAddArmatureBone(armature, child, boneOut.id, curId, idMap, nameMap)); - - return boneOut.id; -} - -CINF::CINF(const Armature& armature, std::unordered_map& idMap) { - idMap.reserve(armature.bones.size()); - bones.reserve(armature.bones.size()); - - std::map nameMap; - - const BlenderBone* bone = armature.getRoot(); - if (bone) { - if (bone->children.size()) { - int curId = 4; - const BlenderBone* child; - for (size_t i = 0; (child = armature.getChild(bone, i)); ++i) - RecursiveAddArmatureBone(armature, child, 3, curId, idMap, nameMap); - } - - bones.emplace_back(); - Bone& boneOut = bones.back(); - nameMap[bone->name] = 3; - boneOut.id = 3; - boneOut.parentId = 2; - boneOut.origin = bone->origin; - idMap.emplace(std::make_pair(bone->name, 3)); - - if (bone->children.size()) { - boneOut.linkedCount = 2; - boneOut.linked = {2, 4}; - } else { - boneOut.linkedCount = 1; - boneOut.linked = {2}; - } - } - - boneCount = bones.size(); - - names.reserve(nameMap.size()); - nameCount = nameMap.size(); - for (const auto& name : nameMap) { - names.emplace_back(); - Name& nameOut = names.back(); - nameOut.name = name.first; - nameOut.boneId = name.second; - } - - boneIdCount = boneCount; - boneIds.reserve(boneIdCount); - for (auto it = bones.crbegin(); it != bones.crend(); ++it) - boneIds.push_back(it->id); -} - -bool CINF::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - if (!force && outPath.isFile()) - return true; - - auto& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Armature)) - return false; - auto os = conn.beginPythonOut(true); - - os.format(FMT_STRING("import bpy\n" - "from mathutils import Vector\n" - "bpy.context.scene.name = 'CINF_{}'\n" - "bpy.context.scene.hecl_arm_obj = bpy.context.scene.name\n" - "\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n"), - entry.id); - - CINF cinf; - cinf.read(rs); - cinf.sendCINFToBlender(os, entry.id); - os.centerView(); - os.close(); - return conn.saveBlend(); -} - -bool CINF::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, - const hecl::blender::Armature& armature) { - std::unordered_map boneIdMap; - CINF cinf(armature, boneIdMap); - - /* Write out CINF resource */ - athena::io::TransactionalFileWriter w(outPath.getAbsolutePath()); - cinf.write(w); - return true; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CINF.hpp b/DataSpec/DNAMP1/CINF.hpp deleted file mode 100644 index 877b401c2..000000000 --- a/DataSpec/DNAMP1/CINF.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/RigInverter.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -struct CINF : BigDNA { - AT_DECL_DNA - Value boneCount; - struct Bone : BigDNA { - AT_DECL_DNA - Value id; - Value parentId; - Value origin; - Value linkedCount; - Vector linked; - }; - Vector bones; - - Value boneIdCount; - Vector boneIds; - - Value nameCount; - struct Name : BigDNA { - AT_DECL_DNA - String<-1> name; - Value boneId; - }; - Vector names; - - atUint32 getInternalBoneIdxFromId(atUint32 id) const; - atUint32 getBoneIdxFromId(atUint32 id) const; - const std::string* getBoneNameFromId(atUint32 id) const; - void sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const; - void sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& cinfId) const; - static std::string GetCINFArmatureName(const UniqueID32& cinfId); - - CINF() = default; - using Armature = hecl::blender::Armature; - using BlenderBone = hecl::blender::Bone; - - int RecursiveAddArmatureBone(const Armature& armature, const BlenderBone* bone, int parent, int& curId, - std::unordered_map& idMap, std::map& nameMap); - - CINF(const Armature& armature, std::unordered_map& idMap); - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged); - - static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, - const hecl::blender::Armature& armature); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CMDL.cpp b/DataSpec/DNAMP1/CMDL.cpp deleted file mode 100644 index caae1808f..000000000 --- a/DataSpec/DNAMP1/CMDL.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#include "CMDL.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - /* Check for RigPair */ - CINF cinf; - CSKR cskr; - using RigPair = std::pair, std::pair>; - RigPair loadRp = {}; - if (const typename CharacterAssociations::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id)) { - pakRouter.lookupAndReadDNA(rp->cskr, cskr); - pakRouter.lookupAndReadDNA(rp->cinf, cinf); - loadRp.first = {rp->cskr, &cskr}; - loadRp.second = {rp->cinf, &cinf}; - } - - /* Do extract */ - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh)) - return false; - DNACMDL::ReadCMDLToBlender, MaterialSet, RigPair, DNACMDL::SurfaceHeader_1, 2>( - conn, rs, pakRouter, entry, dataSpec, loadRp); - conn.saveBlend(); - -#if 0 - /* Cook and re-extract test */ - hecl::ProjectPath tempOut = outPath.getWithExtension(".recook", true); - hecl::blender::Connection::DataStream ds = conn.beginData(); - DNACMDL::Mesh mesh = ds.compileMesh(hecl::TopologyTriStrips, -1); - ds.close(); - DNACMDL::WriteCMDL(tempOut, outPath, mesh); - - athena::io::FileReader reader(tempOut.getAbsolutePath()); - hecl::ProjectPath tempBlend = outPath.getWithExtension(".recook.blend", true); - if (!conn.createBlend(tempBlend, hecl::blender::Connection::TypeMesh)) - return false; - DNACMDL::ReadCMDLToBlender, MaterialSet, std::pair, DNACMDL::SurfaceHeader_1_2, 2> - (conn, reader, pakRouter, entry, dataSpec, loadRp); - return conn.saveBlend(); -#elif 0 - /* HMDL cook test */ - hecl::ProjectPath tempOut = outPath.getWithExtension(".recook", true); - hecl::blender::Connection::DataStream ds = conn.beginData(); - DNACMDL::Mesh mesh = ds.compileMesh(hecl::HMDLTopology::TriStrips, 16); - ds.close(); - DNACMDL::WriteHMDLCMDL(tempOut, outPath, mesh); -#endif - - return true; -} - -bool CMDL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh) { - if (!mesh.skins.empty()) { - DNACMDL::Mesh skinMesh = mesh.getContiguousSkinningVersion(); - if (!DNACMDL::WriteCMDL(outPath, inPath, skinMesh)) - return false; - - /* Output skinning intermediate */ - auto vertCountIt = skinMesh.contiguousSkinVertCounts.cbegin(); - athena::io::FileWriter writer(outPath.getWithExtension(".skinint").getAbsolutePath()); - writer.writeUint32Big(skinMesh.boneNames.size()); - for (const std::string& boneName : skinMesh.boneNames) - writer.writeString(boneName); - - writer.writeUint32Big(skinMesh.skins.size()); - for (const auto& skin : skinMesh.skins) { - size_t numBinds = skinMesh.countSkinBinds(skin); - writer.writeUint32Big(numBinds); - for (size_t i = 0; i < numBinds; ++i) { - writer.writeUint32Big(skin[i].vg_idx); - writer.writeFloatBig(skin[i].weight); - } - writer.writeUint32Big(*vertCountIt++); - } - writer.writeUint32Big(skinMesh.pos.size()); - writer.writeUint32Big(skinMesh.norm.size()); - } else if (!DNACMDL::WriteCMDL(outPath, inPath, mesh)) - return false; - return true; -} - -bool CMDL::HMDLCook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh) { - hecl::blender::PoolSkinIndex poolSkinIndex; - if (mesh.skins.size()) { - if (!DNACMDL::WriteHMDLCMDL(outPath, inPath, mesh, poolSkinIndex)) - return false; - - /* Output skinning intermediate */ - athena::io::FileWriter writer(outPath.getWithExtension(".skinint").getAbsolutePath()); - writer.writeUint32Big(mesh.skinBanks.banks.size()); - for (const DNACMDL::Mesh::SkinBanks::Bank& sb : mesh.skinBanks.banks) { - writer.writeUint32Big(sb.m_boneIdxs.size()); - for (uint32_t bind : sb.m_boneIdxs) - writer.writeUint32Big(bind); - } - writer.writeUint32Big(mesh.boneNames.size()); - for (const std::string& boneName : mesh.boneNames) - writer.writeString(boneName); - - /* CVirtualBone structure just like original (for CPU skinning) */ - writer.writeUint32Big(mesh.skins.size()); - for (auto& s : mesh.skins) { - size_t numBinds = mesh.countSkinBinds(s); - writer.writeUint32Big(numBinds); - for (size_t i = 0; i < numBinds; ++i) { - writer.writeUint32Big(s[i].vg_idx); - writer.writeFloatBig(s[i].weight); - } - } - - /* Write indirection table mapping pool verts to CVirtualBones */ - writer.writeUint32Big(poolSkinIndex.m_poolSz); - for (uint32_t i = 0; i < poolSkinIndex.m_poolSz; ++i) - writer.writeUint32Big(poolSkinIndex.m_poolToSkinIndex[i]); - } else if (!DNACMDL::WriteHMDLCMDL(outPath, inPath, mesh, - poolSkinIndex)) - return false; - return true; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CMDL.hpp b/DataSpec/DNAMP1/CMDL.hpp deleted file mode 100644 index a176b2d6d..000000000 --- a/DataSpec/DNAMP1/CMDL.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/CMDL.hpp" -#include "CMDLMaterials.hpp" -#include "DNAMP1.hpp" -#include "CINF.hpp" -#include "CSKR.hpp" - -#include - -namespace DataSpec::DNAMP1 { - -struct CMDL { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged); - - static void Name(const SpecBase& dataSpec, PAKEntryReadStream& rs, PAKRouter& pakRouter, - PAK::Entry& entry) { - DNACMDL::NameCMDL, MaterialSet>(rs, pakRouter, entry, dataSpec); - } - - static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh); - - static bool HMDLCook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CMDLMaterials.cpp b/DataSpec/DNAMP1/CMDLMaterials.cpp deleted file mode 100644 index 85738eb55..000000000 --- a/DataSpec/DNAMP1/CMDLMaterials.cpp +++ /dev/null @@ -1,1240 +0,0 @@ -#include "CMDLMaterials.hpp" -#include "../DNAMP2/CMDLMaterials.hpp" -#include "hecl/Blender/Connection.hpp" - -using Stream = hecl::blender::PyOutStream; - -namespace DataSpec::DNAMP1 { -using Material = MaterialSet::Material; - -void MaterialSet::RegisterMaterialProps(Stream& out) { - out << "bpy.types.Material.retro_depth_sort = bpy.props.BoolProperty(name='Retro: Transparent Depth Sort')\n" - "bpy.types.Material.retro_alpha_test = bpy.props.BoolProperty(name='Retro: Punchthrough Alpha')\n" - "bpy.types.Material.retro_samus_reflection = bpy.props.BoolProperty(name='Retro: Samus Reflection')\n" - "bpy.types.Material.retro_depth_write = bpy.props.BoolProperty(name='Retro: Depth Write')\n" - "bpy.types.Material.retro_samus_reflection_persp = bpy.props.BoolProperty(name='Retro: Samus Reflection " - "Perspective')\n" - "bpy.types.Material.retro_shadow_occluder = bpy.props.BoolProperty(name='Retro: Shadow Occluder')\n" - "bpy.types.Material.retro_samus_reflection_indirect = bpy.props.BoolProperty(name='Retro: Samus Reflection " - "Indirect Texture')\n" - "bpy.types.Material.retro_lightmapped = bpy.props.BoolProperty(name='Retro: Lightmapped')\n" - "\n"; -} - -void Material::AddTexture(Stream& out, GX::TexGenSrc type, int mtxIdx, uint32_t texIdx, bool diffuse) { - std::string mtxLabel; - if (mtxIdx == -1) - mtxLabel = "IDENTITY"; - else - mtxLabel = fmt::format(FMT_STRING("MTX_{}"), mtxIdx); - - std::string texLabel; - if (diffuse) - texLabel = "Diffuse"; - else - texLabel = "Texture"; - - out.format(FMT_STRING("# Texture\n" - "tex_node = new_nodetree.nodes.new('ShaderNodeTexImage')\n" - "tex_node.label = '{} {}'\n" - "texture_nodes.append(tex_node)\n"), - texLabel, texIdx); - - if (texIdx != 0xff) - out.format(FMT_STRING("tex_node.image = tex_maps[{}]\n"), texIdx); - - if (type == GX::TG_POS) - out << "tex_uv_node = new_nodetree.nodes.new('ShaderNodeTexCoord')\n" - "tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['Window'], tex_node.inputs['Vector']))\n"; - else if (type == GX::TG_NRM) - out << "tex_uv_node = new_nodetree.nodes.new('ShaderNodeTexCoord')\n" - "tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['Normal'], tex_node.inputs['Vector']))\n"; - else if (type >= GX::TG_TEX0 && type <= GX::TG_TEX7) { - uint8_t texIdx = type - GX::TG_TEX0; - out.format( - FMT_STRING("tex_uv_node = new_nodetree.nodes.new('ShaderNodeUVMap')\n" - "tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['UV'], tex_node.inputs['Vector']))\n" - "tex_uv_node.uv_map = 'UV_{}'\n"), - texIdx); - } - - out.format(FMT_STRING("tex_uv_node.label = '{}'\n"), mtxLabel); - - out << "gridder.place_node(tex_uv_node, 0)\n" - "gridder.place_node(tex_node, 0)\n" - "tex_uv_node.location[0] -= 120\n" - "tex_node.location[0] += 120\n" - "tex_node.location[1] += 176\n" - "\n"; -} - -void Material::AddTextureAnim(Stream& out, UVAnimation::Mode type, unsigned idx, const float* vals) { - switch (type) { - case UVAnimation::Mode::MvInvNoTranslation: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode0NodeN']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx); - break; - case UVAnimation::Mode::MvInv: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode1NodeN']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx); - break; - case UVAnimation::Mode::Scroll: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode2Node']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " node.inputs[1].default_value = ({},{},0)\n" - " node.inputs[2].default_value = ({},{},0)\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx, vals[0], vals[1], vals[2], vals[3]); - break; - case UVAnimation::Mode::Rotation: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode3Node']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " node.inputs[1].default_value = {}\n" - " node.inputs[2].default_value = {}\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx, vals[0], vals[1]); - break; - case UVAnimation::Mode::HStrip: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode4Node']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " node.inputs[1].default_value = {}\n" - " node.inputs[2].default_value = {}\n" - " node.inputs[3].default_value = {}\n" - " node.inputs[4].default_value = {}\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx, vals[0], vals[1], vals[2], vals[3]); - break; - case UVAnimation::Mode::VStrip: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode5Node']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " node.inputs[1].default_value = {}\n" - " node.inputs[2].default_value = {}\n" - " node.inputs[3].default_value = {}\n" - " node.inputs[4].default_value = {}\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx, vals[0], vals[1], vals[2], vals[3]); - break; - case UVAnimation::Mode::Model: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode6NodeN']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx); - break; - case UVAnimation::Mode::CylinderEnvironment: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode7NodeN']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " node.inputs[1].default_value = {}\n" - " node.inputs[2].default_value = {}\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx, vals[0], vals[1]); - break; - case UVAnimation::Mode::Eight: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode8Node']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " node.inputs[1].default_value = {}\n" - " node.inputs[2].default_value = {}\n" - " node.inputs[3].default_value = {}\n" - " node.inputs[4].default_value = {}\n" - " node.inputs[5].default_value = {}\n" - " node.inputs[6].default_value = {}\n" - " node.inputs[7].default_value = {}\n" - " node.inputs[8].default_value = {}\n" - " node.inputs[9].default_value = {}\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx, vals[0], vals[1], vals[2], vals[3], vals[4], vals[5], vals[6], vals[7], vals[8]); - break; - default: - break; - } -} - -void Material::AddKcolor(Stream& out, const GX::Color& col, unsigned idx) { - out.format(FMT_STRING("kcolors[{}] = ({}, {}, {}, {})\n" - "kalphas[{}] = {}\n" - "\n"), - idx, (float)col.color[0] / (float)0xff, (float)col.color[1] / (float)0xff, - (float)col.color[2] / (float)0xff, (float)col.color[3] / (float)0xff, idx, - (float)col.color[3] / (float)0xff); -} - -template -static uint32_t _HashTextureConfig(const MAT& mat) { - XXH32_state_t xxHash; - XXH32_reset(&xxHash, 0); - for (uint32_t i = 0; i < mat.tevStageCount; ++i) { - const auto& stage = mat.tevStages[i]; - XXH32_update(&xxHash, &stage.ciFlags, sizeof(stage.ciFlags)); - XXH32_update(&xxHash, &stage.aiFlags, sizeof(stage.aiFlags)); - XXH32_update(&xxHash, &stage.ccFlags, sizeof(stage.ccFlags)); - XXH32_update(&xxHash, &stage.acFlags, sizeof(stage.acFlags)); - XXH32_update(&xxHash, &stage.kaInput, sizeof(stage.kaInput)); - XXH32_update(&xxHash, &stage.kcInput, sizeof(stage.kcInput)); - XXH32_update(&xxHash, &stage.rascInput, sizeof(stage.rascInput)); - } - bool hasInd = mat.flags.samusReflectionIndirectTexture(); - XXH32_update(&xxHash, &hasInd, sizeof(hasInd)); - bool hasLm = mat.flags.lightmap(); - XXH32_update(&xxHash, &hasLm, sizeof(hasLm)); - return XXH32_digest(&xxHash); -} - -static const char* ToString(GX::TevColorArg arg) { - switch (arg) { - case GX::CC_CPREV: - return "CC_CPREV"; - case GX::CC_APREV: - return "CC_APREV"; - case GX::CC_C0: - return "CC_C0"; - case GX::CC_A0: - return "CC_A0"; - case GX::CC_C1: - return "CC_C1"; - case GX::CC_A1: - return "CC_A1"; - case GX::CC_C2: - return "CC_C2"; - case GX::CC_A2: - return "CC_A2"; - case GX::CC_TEXC: - return "CC_TEXC"; - case GX::CC_TEXA: - return "CC_TEXA"; - case GX::CC_RASC: - return "CC_RASC"; - case GX::CC_RASA: - return "CC_RASA"; - case GX::CC_ONE: - return "CC_ONE"; - case GX::CC_HALF: - return "CC_HALF"; - case GX::CC_KONST: - return "CC_KONST"; - case GX::CC_ZERO: - return "CC_ZERO"; - default: - return "UNKNOWN"; - } -} - -static const char* ToString(GX::TevAlphaArg arg) { - switch (arg) { - case GX::CA_APREV: - return "CA_APREV"; - case GX::CA_A0: - return "CA_A0"; - case GX::CA_A1: - return "CA_A1"; - case GX::CA_A2: - return "CA_A2"; - case GX::CA_TEXA: - return "CA_TEXA"; - case GX::CA_RASA: - return "CA_RASA"; - case GX::CA_KONST: - return "CA_KONST"; - case GX::CA_ZERO: - return "CA_ZERO"; - default: - return "UNKNOWN"; - } -} - -static const char* ToString(GX::TevRegID arg) { - switch (arg) { - case GX::TEVPREV: - return "TEVPREV"; - case GX::TEVREG0: - return "TEVREG0"; - case GX::TEVREG1: - return "TEVREG1"; - case GX::TEVREG2: - return "TEVREG2"; - default: - return "UNKNOWN"; - } -} - -// FIXME remove; bug with fmtlib 8.0.0 & AppleClang 12.0.5 -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-local-typedef" -#endif -template -static void _DescribeTEV(const MAT& mat) { - for (uint32_t i = 0; i < mat.tevStageCount; ++i) { - const auto& stage = mat.tevStages[i]; - fmt::print(stderr, FMT_STRING("A:{} B:{} C:{} D:{} -> {} | A:{} B:{} C:{} D:{} -> {}\n"), - ToString(stage.colorInA()), ToString(stage.colorInB()), ToString(stage.colorInC()), - ToString(stage.colorInD()), ToString(stage.colorOpOutReg()), ToString(stage.alphaInA()), - ToString(stage.alphaInB()), ToString(stage.alphaInC()), ToString(stage.alphaInD()), - ToString(stage.alphaOpOutReg())); - } - bool hasInd = mat.flags.samusReflectionIndirectTexture(); - bool hasLm = mat.flags.lightmap(); - fmt::print(stderr, FMT_STRING("HasIndirect: {} HasLightmap: {}\n"), hasInd, hasLm); -} -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -struct TexLink { - const char* shaderInput; - int texidx; - bool alpha; - TexLink(const char* shaderInput, int texidx = -1, bool alpha = false) - : shaderInput(shaderInput), texidx(texidx), alpha(alpha) {} -}; - -struct ExtendedSpecularLink { - int texidx; - ExtendedSpecularLink(int texidx = -1) : texidx(texidx) {} -}; - -struct KColLink { - const char* shaderInput; - int kcidx; - bool alpha; - KColLink(const char* shaderInput, int kcidx = 0, bool alpha = false) - : shaderInput(shaderInput), kcidx(kcidx), alpha(alpha) {} -}; - -struct WhiteColorLink { - const char* shaderInput; - explicit WhiteColorLink(const char* shaderInput) : shaderInput(shaderInput) {} -}; - -static void _GenerateRootShader(Stream& out, int) { /* End of shader links */ -} - -template -static void _GenerateRootShader(Stream& out, int tidx, TexLink tex, Targs... args) { - int texIdx = tex.texidx == -1 ? tidx : tex.texidx; - out << "texture_nodes[" << texIdx << "].name = '" << tex.shaderInput << "'\n"; - out << "texture_nodes[" << texIdx << "].label = '" << tex.shaderInput << "'\n"; - out << "new_nodetree.links.new(texture_nodes[" << texIdx << "].outputs['" << (tex.alpha ? "Alpha" : "Color") - << "'], node.inputs['" << tex.shaderInput << "'])\n"; - if (tex.texidx == -1) - ++tidx; - _GenerateRootShader(out, tidx, args...); -} - -template -static void _GenerateRootShader(Stream& out, int tidx, ExtendedSpecularLink tex, Targs... args) { - int texIdx = tex.texidx == -1 ? tidx : tex.texidx; - out << "texture_nodes[" << texIdx << "].name = 'Specular'\n"; - out << "texture_nodes[" << texIdx << "].label = 'Specular'\n"; - out << "new_nodetree.links.new(texture_nodes[" << texIdx << "].outputs['Color'], node.inputs['Specular'])\n"; - out << "new_nodetree.links.new(texture_nodes[" << texIdx << "].outputs['Alpha'], node.inputs['ExtendedSpecular'])\n"; - if (tex.texidx == -1) - ++tidx; - _GenerateRootShader(out, tidx, args...); -} - -template -static void _GenerateRootShader(Stream& out, int tidx, KColLink kcol, Targs... args) { - out << "node.inputs['" << kcol.shaderInput << "'].default_value = " << (kcol.alpha ? "kalphas[" : "kcolors[") - << kcol.kcidx << "]\n"; - _GenerateRootShader(out, tidx, args...); -} - -template -static void _GenerateRootShader(Stream& out, int tidx, WhiteColorLink wcol, Targs... args) { - out << "node.inputs['" << wcol.shaderInput << "'].default_value = (1.0, 1.0, 1.0, 1.0)\n"; - _GenerateRootShader(out, tidx, args...); -} - -template -static void _GenerateRootShader(Stream& out, const char* type, Targs... args) { - out << "node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - "node.name = 'Output'\n" - "node.node_tree = bpy.data.node_groups['" - << type - << "']\n" - "gridder.place_node(node, 1)\n" - "new_nodetree.links.new(node.outputs['Surface'], blend_node.inputs['Surface'])\n"; - _GenerateRootShader(out, 0, args...); -} - -static TexLink operator"" _tex(const char* str, size_t) { return TexLink(str); } -static TexLink operator"" _texa(const char* str, size_t) { return TexLink(str, -1, true); } -static KColLink operator"" _kcol(const char* str, size_t) { return KColLink(str); } -static KColLink operator"" _kcola(const char* str, size_t) { return KColLink(str, 0, true); } - -template -static void _ConstructMaterial(Stream& out, const MAT& material, unsigned groupIdx, unsigned matIdx) { - unsigned i; - - out.format(FMT_STRING("new_material = bpy.data.materials.new('MAT_{}_{}')\n"), groupIdx, matIdx); - out << "new_material.use_fake_user = True\n" - "new_material.use_nodes = True\n" - "new_material.use_backface_culling = True\n" - "new_material.blend_method = 'BLEND'\n" - "new_nodetree = new_material.node_tree\n" - "for n in new_nodetree.nodes:\n" - " new_nodetree.nodes.remove(n)\n" - "\n" - "gridder = hecl.Nodegrid(new_nodetree)\n" - "\n" - "texture_nodes = []\n" - "kcolors = {}\n" - "kalphas = {}\n" - "tex_links = []\n" - "\n"; - - /* Material Flags */ - out.format(FMT_STRING("new_material.retro_depth_sort = {}\n" - "new_material.retro_alpha_test = {}\n" - "new_material.retro_samus_reflection = {}\n" - "new_material.retro_depth_write = {}\n" - "new_material.retro_samus_reflection_persp = {}\n" - "new_material.retro_shadow_occluder = {}\n" - "new_material.retro_samus_reflection_indirect = {}\n" - "new_material.retro_lightmapped = {}\n" - "new_material.diffuse_color = (1, 1, 1, {})\n"), - material.flags.depthSorting() ? "True" : "False", material.flags.alphaTest() ? "True" : "False", - material.flags.samusReflection() ? "True" : "False", material.flags.depthWrite() ? "True" : "False", - material.flags.samusReflectionSurfaceEye() ? "True" : "False", - material.flags.shadowOccluderMesh() ? "True" : "False", - material.flags.samusReflectionIndirectTexture() ? "True" : "False", - material.flags.lightmap() ? "True" : "False", material.flags.shadowOccluderMesh() ? "0" : "1"); - - /* Texture Indices */ - out << "tex_maps = []\n"; - for (atUint32 idx : material.textureIdxs) - out.format(FMT_STRING("tex_maps.append(texmap_list[{}])\n"), idx); - - /* KColor entries */ - if (material.flags.konstValuesEnabled()) { - unsigned i = 0; - for (const GX::Color& col : material.konstColors) - Material::AddKcolor(out, col, i++); - } - - /* Blend factors */ - out << "blend_node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - "blend_node.name = 'Blend'\n" - "gridder.place_node(blend_node, 2)\n"; - using BlendFactor = Material::BlendFactor; - if (material.blendDstFac != BlendFactor::BL_ZERO) { - if (material.blendDstFac == BlendFactor::BL_ONE) - out << "blend_node.node_tree = bpy.data.node_groups['HECLAdditiveOutput']\n"; - else - out << "blend_node.node_tree = bpy.data.node_groups['HECLBlendOutput']\n"; - } else { - out << "blend_node.node_tree = bpy.data.node_groups['HECLOpaqueOutput']\n" - "new_material.blend_method = 'OPAQUE'\n"; - } - - /* Add texture maps/tcgs */ - unsigned addedTcgs = 0; - bool diffuseStage = false; - for (i = 0; i < material.tevStageCount; ++i) { - if (material.tevStageTexInfo[i].tcgSlot != 0xff && !(addedTcgs >> material.tevStageTexInfo[i].tcgSlot & 1)) { - const Material::TexCoordGen& tcg = material.tcgs[material.tevStageTexInfo[i].tcgSlot]; - GX::TexMtx mtx = tcg.mtx(); - int mtxIdx = -1; - if (mtx >= GX::TEXMTX0 && mtx <= GX::TEXMTX9) - mtxIdx = (mtx - GX::TEXMTX0) / 3; - Material::AddTexture(out, tcg.source(), mtxIdx, material.tevStageTexInfo[i].texSlot, diffuseStage); - addedTcgs |= 1 << material.tevStageTexInfo[i].tcgSlot; - } - diffuseStage = material.tevStages[i].colorOpOutReg() == GX::TEVREG0; - } - - /* Indirect texture node */ - if (material.flags.samusReflectionIndirectTexture()) - Material::AddTexture(out, GX::TexGenSrc::TG_POS, -1, material.indTexSlot[0], false); - - /* Select appropriate root shader and link textures */ - uint32_t hash = _HashTextureConfig(material); - switch (hash) { - case 0x03FEE002: /* RetroShader: Diffuse, Emissive, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, "Reflection"_tex); - break; - case 0x0473AE40: /* RetroShader: Lightmap, Diffuse, Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex); - break; - case 0x072D2CB3: /* RetroShader: Diffuse, Emissive, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, WhiteColorLink("Specular"), - "Reflection"_tex); - break; - case 0x07AA75D7: /* RetroShader: Diffuse, Emissive, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, TexLink("Alpha", 0, true)); - break; - case 0x0879D346: /* RetroShader: KColorDiffuse, Alpha=Texture */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_kcol, "Alpha"_tex); - break; - case 0x0DA256BB: /* Lightmap, Diffuse, Specular, Reflection, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, - "Alpha"_kcola); - break; - case 0x11C41DA4: /* RetroDynamicCharacterShader: Diffuse, DynamicMaskTex, Specular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroDynamicCharacterShader", "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, - "Reflection"_tex); - break; - case 0x1218F83E: /* RetroShader: ObjLightmap, Diffuse, ExtendedSpecular, Reflection, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, ExtendedSpecularLink(), "Reflection"_tex, - TexLink("Alpha", 1, true)); - break; - case 0x129B8578: /* RetroShader: KColorDiffuse, Emissive, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_kcol, "Emissive"_tex, "Alpha"_kcola); - break; - case 0x15A00948: /* RetroShader: Diffuse, Emissive, Specular, ExtendedSpecular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, "ExtendedSpecular"_tex, - "Reflection"_tex); - break; - case 0x15A3E6E5: /* RetroShader: Diffuse, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Alpha"_kcola); - break; - case 0x1BEB3E15: /* RetroShader: Diffuse, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, TexLink("Alpha", 0, true)); - break; - case 0x2261E0EB: /* RetroShader: Diffuse, Emissive, Specular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, "Reflection"_tex); - break; - case 0x239C7724: /* RetroDynamicShader: Diffuse*Dynamic, Emissive*Dynamic, Alpha=1.0 */ - _GenerateRootShader(out, "RetroDynamicShader", "Diffuse"_tex, "Emissive"_tex); - break; - case 0x240C4C84: /* RetroShader: Lightmap, KColorDiffuse, Specular, Reflection, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_kcol, "Specular"_tex, "Reflection"_tex, - "Alpha"_kcola); - break; - case 0x2523A379: /* RetroDynamicShader: Emissive*Dynamic, Specular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroDynamicShader", "Emissive"_tex, "Specular"_tex, "Reflection"_tex); - break; - case 0x25E85017: /* RetroShader: Lightmap, KColorDiffuse, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_kcol, "Alpha"_kcola); - break; - case 0x27FD5C6C: /* RetroShader: ObjLightmap, Diffuse, Specular, Reflection, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, - TexLink("Alpha", 1, true)); - break; - case 0x2AD9F535: /* RetroShader: Emissive, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Emissive"_tex, WhiteColorLink("Specular"), "Reflection"_tex); - break; - case 0x2C9F5104: /* RetroShader: Diffuse, Specular, Reflection, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, "Alpha"_kcola); - break; - case 0x2D059429: /* RetroShader: Diffuse, Emissive, ExtendedSpecular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, ExtendedSpecularLink(), "Reflection"_tex); - break; - case 0x30AC64BB: /* RetroShader: Diffuse, Specular, Reflection, Alpha=KAlpha, IndirectTex */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, "IndirectTex"_tex, - "Alpha"_kcola); - break; - case 0x39BC4809: /* RetroDynamicShader: ObjLightmap*Dynamic, Diffuse*Dynamic, Emissive*Dynamic, Specular, Reflection, - Alpha=1.0 */ - _GenerateRootShader(out, "RetroDynamicShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, - "Reflection"_tex); - break; - case 0x3BF97299: /* RetroShader: Lightmap, Diffuse, Specular, Reflection, Alpha=KAlpha, IndirectTex */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, - "IndirectTex"_tex, "Alpha"_kcola); - break; - case 0x4184FBCA: /* RetroShader: Lightmap, Diffuse, Emissive, DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex, TexLink("Alpha", 1, true)); - break; - case 0x47ECF3ED: /* RetroShader: Diffuse, Specular, Reflection, Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, "Emissive"_tex); - break; - case 0x4BBDFFA6: /* RetroShader: Diffuse, Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex); - break; - case 0x4D4127A3: /* RetroShader: Lightmap, Diffuse, Specular, Reflection, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, - TexLink("Alpha", 1, true)); - break; - case 0x54A92F25: /* RetroShader: ObjLightmap, KColorDiffuse, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_kcol, "Alpha"_kcola); - break; - case 0x58BAA415: /* RetroShader: Lightmap, Diffuse, Emissive, Alpha=1.0 */ - // TODO: Last stage assigns into unused reg2, perhaps for runtime material mod? - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex); - break; - case 0x54C6204C: - _GenerateRootShader(out, "RetroShader"); - break; - case 0x5A62D5F0: /* RetroShader: Lightmap, Diffuse, UnusedExtendedSpecular?, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, TexLink("Alpha", 1, true)); - break; - case 0x5CB59821: /* RetroShader: Diffuse, UnusedSpecular?, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Alpha"_kcola); - break; - case 0x5D0F0069: /* RetroShader: Diffuse, Emissive, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, TexLink("Alpha", 0, true)); - break; - case 0x5D80E53C: /* RetroShader: Emissive, Specular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Emissive"_tex, "Specular"_tex, "Reflection"_tex); - break; - case 0x5F0AB0E9: /* RetroShader: Lightmap, Diffuse, UnusedSpecular?, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, TexLink("Alpha", 1, true)); - break; - case 0x5F189425: /* RetroShader: Lightmap, Diffuse, UnusedSpecular?, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Alpha"_kcola); - break; - case 0x6601D113: /* RetroShader: Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Emissive"_tex); - break; - case 0x694287FA: /* RetroShader: Diffuse, Emissive, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, WhiteColorLink("Specular"), - "Reflection"_tex); - break; - case 0x6D98D689: /* RetroDynamicAlphaShader: Diffuse*Dynamic, Specular, Reflection, Alpha=KAlpha*Dynamic */ - _GenerateRootShader(out, "RetroDynamicAlphaShader", "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, "Alpha"_kcola); - break; - case 0x7252CB90: /* RetroShader: Lightmap, Diffuse, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Alpha"_kcola); - break; - case 0x72BEDDAC: /* RetroShader: DiffuseMod, Diffuse, Emissive, Specular, Reflection Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "DiffuseMod"_tex, "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, - "Reflection"_tex); - break; - case 0x76BEA57E: /* RetroShader: Lightmap, Diffuse, Emissive, Specular, Reflection, Alpha=1.0, IndirectTex */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, - "Reflection"_tex, "IndirectTex"_tex); - break; - case 0x7D6A4487: /* RetroShader: Diffuse, Specular, Reflection, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, TexLink("Alpha", 0, true)); - break; - case 0x81106196: /* RetroDynamicShader: Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroDynamicShader", "Emissive"_tex); - break; - case 0x84319328: /* RetroShader: Reflection, UnusedSpecular?, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", WhiteColorLink("Specular"), "Reflection"_tex); - break; - case 0x846215DA: /* RetroShader: Diffuse, Specular, Reflection, Alpha=DiffuseAlpha, IndirectTex */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, "IndirectTex"_tex, - TexLink("Alpha", 0, true)); - break; - case 0x8C562AB1: /* RetroShader: Diffuse, Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex); - break; - case 0x8E916C01: /* RetroShader: NULL, all inputs 0 */ - _GenerateRootShader(out, "RetroShader"); - break; - case 0x957709F8: /* RetroShader: Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Emissive"_tex); - break; - case 0x96ABB2D3: /* RetroShader: Lightmap, Diffuse, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, TexLink("Alpha", 1, true)); - break; - case 0x985A0B67: /* RetroShader: Diffuse, UnusedSpecular?, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, TexLink("Alpha", 0, true)); - break; - case 0x9B4453A2: /* RetroShader: Diffuse, Emissive, ExtendedSpecular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, ExtendedSpecularLink(), "Reflection"_tex); - break; - case 0xA187C630: /* RetroShader: Diffuse, Emissive, UnusedReflection?, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex); - break; - case 0xB26E9E2E: /* RetroShader: Diffuse, Emissive, Alpha=1.0 */ - // TODO: Last two stages assign into unused reg2, perhaps for runtime material mod? - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex); - break; - case 0xC0E3FF1F: /* RetroShader: KColorDiffuse, Specular, Reflection, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_kcol, "Specular"_tex, "Reflection"_tex, "Alpha"_kcola); - break; - case 0xC138DCFA: /* RetroShader: Diffuse, Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex); - break; - case 0xC3C8B1C8: /* RetroShader: KColorDiffuse, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_kcol, "Alpha"_kcola); - break; - case 0xC689C8C6: /* RetroShader: Diffuse, ExtendedSpecular, Reflection, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, ExtendedSpecularLink(), "Reflection"_tex, - TexLink("Alpha", 0, true)); - break; - case 0xC6B18B28: /* RetroShader: Diffuse, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, TexLink("Alpha", 0, true)); - break; - case 0xCD92D4C5: /* RetroShader: Diffuse, Reflection, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, WhiteColorLink("Specular"), "Reflection"_tex, "Alpha"_kcola); - break; - case 0xCE06F3F2: /* RetroShader: Diffuse, Alpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, TexLink("Alpha", 1, true)); - break; - case 0xD73E7728: /* RetroShader: ObjLightmap, Diffuse, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, TexLink("Alpha", 1, true)); - break; - case 0xDB8F01AD: /* RetroDynamicShader: Diffuse*Dynamic, Emissive*Dynamic, UnusedSpecular?, Alpha=1.0 */ - _GenerateRootShader(out, "RetroDynamicShader", "Diffuse"_tex, "Emissive"_tex); - break; - case 0xE64D1085: /* RetroShader: Lightmap, Diffuse, Emissive, Reflection, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex, "Reflection"_tex, - TexLink("Alpha", 1, true)); - break; - case 0xE6784B10: /* RetroShader: Lightmap, Diffuse, Specular, Reflection, Alpha=DiffuseAlpha, IndirectTex */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, - "IndirectTex"_tex, TexLink("Alpha", 1, true)); - break; - case 0xE68FF182: /* RetroShader: Diffuse, Emissive, Specular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, "Reflection"_tex); - break; - case 0xE92F1340: /* RetroShader: Diffuse, Alpha=DiffuseAlpha*AlphaMod */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, TexLink("Alpha", 0, true), TexLink("AlphaMod", 1, true)); - break; - case 0xEB4645CF: /* RetroDynamicAlphaShader: Diffuse*Dynamic, Alpha=DiffuseAlpha*Dynamic */ - _GenerateRootShader(out, "RetroDynamicAlphaShader", "Diffuse"_tex, TexLink("Alpha", 0, true)); - break; - case 0xECEF8D1F: /* RetroDynamicShader: Diffuse*Dynamic, Emissive*Dynamic, Specular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroDynamicShader", "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, "Reflection"_tex); - break; - case 0xF1C26570: /* RetroShader: Lightmap, Diffuse, Specular, ExtendedSpecular, Reflection, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Specular"_tex, "ExtendedSpecular"_tex, - "Reflection"_tex, TexLink("Alpha", 1, true)); - break; - case 0xF345C16E: /* RetroShader: Emissive, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Emissive"_tex, "Reflection"_tex); - break; - case 0xF4DA0A86: /* RetroShader: KColorDiffuse, Emissive, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_kcol, "Emissive"_tex, "Alpha"_kcola); - break; - break; - case 0xF559DB08: /* RetroShader: Lightmap, Diffuse, Emissive, Specular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, - "Reflection"_tex); - break; - case 0xF9324367: /* RetroShader: Lightmap, Diffuse, Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex); - break; - case 0xFC2761B8: /* RetroShader: Lightmap, Diffuse, Alpha=DiffuseAlpha*AlphaMod */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, TexLink("Alpha", 1, true), - TexLink("AlphaMod", 2, true)); - break; - case 0xFD95D7FD: /* RetroShader: ObjLightmap, Diffuse, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, TexLink("Alpha", 1, true)); - break; - case 0xFFF3CEBB: /* RetroShader: Lightmap, Diffuse, Emissive, Alpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex, TexLink("Alpha", 3, true)); - break; - default: - _DescribeTEV(material); - Log.report(logvisor::Fatal, FMT_STRING("Unable to resolve shader hash {:08X}\n"), hash); - break; - } - - /* Has Lightmap? */ - if (material.flags.lightmap()) { - if (material.tevStageTexInfo[0].texSlot != 0xff) - out << "new_material.hecl_lightmap = tex_maps[0].name\n" - "tex_maps[0].use_fake_user = True\n"; - } - - /* Texmtx Animation Section */ - i = 0; - for (const Material::UVAnimation& anim : material.uvAnims) - Material::AddTextureAnim(out, anim.mode, i++, anim.vals); -} - -void MaterialSet::ConstructMaterial(Stream& out, const MaterialSet::Material& material, unsigned groupIdx, - unsigned matIdx) { - _ConstructMaterial(out, material, groupIdx, matIdx); -} - -MaterialSet::Material::Material(const hecl::blender::Material& mat, std::vector& texPathsOut, - int colorCount, bool lightmapUVs, bool matrixSkinning) { - /* TODO: Rewrite for new shader rep */ - XXH32_state_t xxHash; - XXH32_reset(&xxHash, 0); - -#if 0 - if (gx.m_kcolorCount) { - flags.setKonstValuesEnabled(true); - konstCount.push_back(gx.m_kcolorCount); - } -#endif - - auto search = mat.iprops.find("retro_depth_sort"); - if (search != mat.iprops.end()) - flags.setDepthSorting(search->second != 0); - - search = mat.iprops.find("retro_alpha_test"); - if (search != mat.iprops.end()) - flags.setAlphaTest(search->second != 0); - - search = mat.iprops.find("retro_samus_reflection"); - if (search != mat.iprops.end()) - flags.setSamusReflection(search->second != 0); - - search = mat.iprops.find("retro_depth_write"); - if (search != mat.iprops.end()) - flags.setDepthWrite(search->second != 0); - - search = mat.iprops.find("retro_samus_reflection_persp"); - if (search != mat.iprops.end()) - flags.setSamusReflectionSurfaceEye(search->second != 0); - - search = mat.iprops.find("retro_shadow_occluder"); - if (search != mat.iprops.end()) - flags.setShadowOccluderMesh(search->second != 0); - - search = mat.iprops.find("retro_samus_reflection_indirect"); - if (search != mat.iprops.end()) - flags.setSamusReflectionIndirectTexture(search->second != 0); - - search = mat.iprops.find("retro_lightmapped"); - if (search != mat.iprops.end()) - flags.setLightmap(search->second != 0); - - flags.setLightmapUVArray(lightmapUVs); - -#if 0 - atUint16 texFlags = 0; - atUint16 tcgFlags = 0; - tevStageTexInfo.reserve(gx.m_tevCount); - textureIdxs.reserve(gx.m_tevCount); - for (unsigned i = 0; i < gx.m_tevCount; ++i) { - const hecl::Backend::GX::TEVStage& stage = gx.m_tevs[i]; - tevStageTexInfo.emplace_back(); - TEVStageTexInfo& texInfo = tevStageTexInfo.back(); - if (stage.m_texGenIdx != -1) { - texInfo.tcgSlot = stage.m_texGenIdx; - const hecl::Backend::GX::TexCoordGen& tcg = gx.m_tcgs[stage.m_texGenIdx]; - if (tcg.m_src >= hecl::Backend::GX::TG_TEX0 && tcg.m_src <= hecl::Backend::GX::TG_TEX6) - tcgFlags |= 1 << (tcg.m_src - hecl::Backend::GX::TG_TEX0); - } - if (stage.m_texMapIdx != -1) { - texInfo.texSlot = textureIdxs.size(); - const hecl::ProjectPath& texPath = texPathsIn.at(stage.m_texMapIdx); - texFlags |= 1 << i; - ++textureCount; - bool found = false; - for (size_t t = 0; t < texPathsOut.size(); ++t) { - if (texPath == texPathsOut[t]) { - found = true; - textureIdxs.push_back(t); - break; - } - } - if (!found) { - textureIdxs.push_back(texPathsOut.size()); - texPathsOut.push_back(texPath); - } - } - } - flags.setTextureSlots(texFlags); - - XXH32_update(&xxHash, &flags.flags, sizeof(flags.flags)); - - vaFlags.setPosition(GX::INDEX16); - vaFlags.setNormal(GX::INDEX16); - - if (0 < colorCount) - vaFlags.setColor0(GX::INDEX16); - if (1 < colorCount) - vaFlags.setColor1(GX::INDEX16); - - if (tcgFlags & (1 << 0)) - vaFlags.setTex0(GX::INDEX16); - if (tcgFlags & (1 << 1)) - vaFlags.setTex1(GX::INDEX16); - if (tcgFlags & (1 << 2)) - vaFlags.setTex2(GX::INDEX16); - if (tcgFlags & (1 << 3)) - vaFlags.setTex3(GX::INDEX16); - if (tcgFlags & (1 << 4)) - vaFlags.setTex4(GX::INDEX16); - if (tcgFlags & (1 << 5)) - vaFlags.setTex5(GX::INDEX16); - if (tcgFlags & (1 << 6)) - vaFlags.setTex6(GX::INDEX16); - - if (matrixSkinning) { - vaFlags.setPnMatIdx(GX::DIRECT); - if (tcgFlags & (1 << 0)) - vaFlags.setTex0MatIdx(GX::DIRECT); - if (tcgFlags & (1 << 1)) - vaFlags.setTex1MatIdx(GX::DIRECT); - if (tcgFlags & (1 << 2)) - vaFlags.setTex2MatIdx(GX::DIRECT); - if (tcgFlags & (1 << 3)) - vaFlags.setTex3MatIdx(GX::DIRECT); - if (tcgFlags & (1 << 4)) - vaFlags.setTex4MatIdx(GX::DIRECT); - if (tcgFlags & (1 << 5)) - vaFlags.setTex5MatIdx(GX::DIRECT); - if (tcgFlags & (1 << 6)) - vaFlags.setTex6MatIdx(GX::DIRECT); - } - - XXH32_update(&xxHash, &vaFlags.vaFlags, sizeof(vaFlags.vaFlags)); - - XXH32_update(&xxHash, &gx.m_kcolorCount, sizeof(gx.m_kcolorCount)); - for (unsigned i = 0; i < gx.m_kcolorCount; ++i) { - konstColors.emplace_back(gx.m_kcolors[i]); - XXH32_update(&xxHash, &gx.m_kcolors[i].num, sizeof(gx.m_kcolors[i].num)); - } - - blendDstFac = BlendFactor(gx.m_blendDst); - XXH32_update(&xxHash, &gx.m_blendDst, sizeof(gx.m_blendDst)); - blendSrcFac = BlendFactor(gx.m_blendSrc); - XXH32_update(&xxHash, &gx.m_blendSrc, sizeof(gx.m_blendSrc)); - if (flags.samusReflectionIndirectTexture()) { - indTexSlot.push_back(textureIdxs.size()); - XXH32_update(&xxHash, &indTexSlot.back(), sizeof(indTexSlot.back())); - } - - colorChannelCount = 1; - XXH32_update(&xxHash, &colorChannelCount, sizeof(colorChannelCount)); - colorChannels.emplace_back(); - ColorChannel& ch = colorChannels.back(); - for (unsigned i = 0; i < gx.m_tevCount; ++i) { - const hecl::Backend::GX::TEVStage& stage = gx.m_tevs[i]; - for (int c = 0; c < 4; ++c) - if (stage.m_color[c] == hecl::Backend::GX::CC_RASC || stage.m_color[c] == hecl::Backend::GX::CC_RASA || - stage.m_alpha[c] == hecl::Backend::GX::CA_RASA) { - ch.setLighting(true); - uint8_t one = 1; - XXH32_update(&xxHash, &one, sizeof(one)); - break; - } - if (ch.lighting()) - break; - } - ch.setDiffuseFn(GX::DF_CLAMP); - ch.setAttenuationFn(GX::AF_SPOT); - - tevStageCount = gx.m_tevCount; - XXH32_update(&xxHash, &tevStageCount, sizeof(tevStageCount)); - tevStages.reserve(gx.m_tevCount); - for (unsigned i = 0; i < gx.m_tevCount; ++i) { - const hecl::Backend::GX::TEVStage& stage = gx.m_tevs[i]; - tevStages.emplace_back(); - TEVStage& target = tevStages.back(); - - target.setColorInA(stage.m_color[0]); - target.setColorInB(stage.m_color[1]); - target.setColorInC(stage.m_color[2]); - target.setColorInD(stage.m_color[3]); - target.setAlphaInA(stage.m_alpha[0]); - target.setAlphaInB(stage.m_alpha[1]); - target.setAlphaInC(stage.m_alpha[2]); - target.setAlphaInD(stage.m_alpha[3]); - target.setColorOp(stage.m_cop); - target.setColorOpBias(GX::TB_ZERO); - target.setColorOpScale(GX::CS_SCALE_1); - target.setColorOpClamp(true); - target.setColorOpOutReg(stage.m_cRegOut); - target.setAlphaOp(stage.m_aop); - target.setAlphaOpBias(GX::TB_ZERO); - target.setAlphaOpScale(GX::CS_SCALE_1); - target.setAlphaOpClamp(true); - target.setAlphaOpOutReg(stage.m_aRegOut); - target.setKColorIn(stage.m_kColor); - target.setKAlphaIn(stage.m_kAlpha); - - target.setRASIn(GX::GX_COLOR_NULL); - for (int c = 0; c < 4; ++c) - if (stage.m_color[c] == hecl::Backend::GX::CC_RASC || stage.m_color[c] == hecl::Backend::GX::CC_RASA || - stage.m_alpha[c] == hecl::Backend::GX::CA_RASA) { - target.setRASIn(GX::GX_COLOR0A0); - break; - } - - XXH32_update(&xxHash, &target.ciFlags, sizeof(target.ciFlags)); - XXH32_update(&xxHash, &target.aiFlags, sizeof(target.aiFlags)); - XXH32_update(&xxHash, &target.ccFlags, sizeof(target.ccFlags)); - XXH32_update(&xxHash, &target.acFlags, sizeof(target.acFlags)); - XXH32_update(&xxHash, &target.kaInput, sizeof(target.kaInput)); - XXH32_update(&xxHash, &target.kcInput, sizeof(target.kcInput)); - XXH32_update(&xxHash, &target.rascInput, sizeof(target.rascInput)); - } - - tcgCount = gx.m_tcgCount; - XXH32_update(&xxHash, &tcgCount, sizeof(tcgCount)); - for (unsigned i = 0; i < gx.m_tcgCount; ++i) { - const hecl::Backend::GX::TexCoordGen& tcg = gx.m_tcgs[i]; - tcgs.emplace_back(); - TexCoordGen& target = tcgs.back(); - target.setType(GX::TG_MTX3x4); - target.setSource(tcg.m_src); - target.setMtx(tcg.m_mtx); - target.setNormalize(tcg.m_norm); - target.setPostMtx(tcg.m_pmtx); - - XXH32_update(&xxHash, &target.flags, sizeof(target.flags)); - } - - uvAnimsSize = 4; - uvAnimsCount = 0; - for (; uvAnimsCount < 8;) { - bool found = false; - for (unsigned t = 0; t < gx.m_tcgCount; ++t) { - const hecl::Backend::GX::TexCoordGen& tcg = gx.m_tcgs[t]; - if (tcg.m_mtx == GX::IDENTITY) - continue; - if ((tcg.m_mtx - GX::TEXMTX0) / 3 == uvAnimsCount) { - found = true; - ++uvAnimsCount; - uvAnims.emplace_back(tcg.m_gameFunction, tcg.m_gameArgs); - XXH32_update(&xxHash, tcg.m_gameFunction.data(), sizeof(tcg.m_gameFunction.size())); - for (const atVec4f& arg : tcg.m_gameArgs) - XXH32_update(&xxHash, &arg, sizeof(arg)); - size_t tmpUvAnimsSize = uvAnimsSize; - uvAnims.back().binarySize(tmpUvAnimsSize); - uvAnimsSize = tmpUvAnimsSize; - break; - } - } - if (!found) - break; - } - - XXH32_update(&xxHash, &uvAnimsSize, sizeof(uvAnimsSize)); - XXH32_update(&xxHash, &uvAnimsCount, sizeof(uvAnimsCount)); -#endif - - uniqueIdx = XXH32_digest(&xxHash); -} - -HMDLMaterialSet::Material::Material(const hecl::blender::Material& mat) { - auto search = mat.iprops.find("retro_depth_sort"); - if (search != mat.iprops.end()) - flags.setDepthSorting(search->second != 0); - - search = mat.iprops.find("retro_alpha_test"); - if (search != mat.iprops.end()) - flags.setAlphaTest(search->second != 0); - - search = mat.iprops.find("retro_samus_reflection"); - if (search != mat.iprops.end()) - flags.setSamusReflection(search->second != 0); - - search = mat.iprops.find("retro_depth_write"); - if (search != mat.iprops.end()) - flags.setDepthWrite(search->second != 0); - - search = mat.iprops.find("retro_samus_reflection_persp"); - if (search != mat.iprops.end()) - flags.setSamusReflectionSurfaceEye(search->second != 0); - - search = mat.iprops.find("retro_shadow_occluder"); - if (search != mat.iprops.end()) - flags.setShadowOccluderMesh(search->second != 0); - - search = mat.iprops.find("retro_samus_reflection_indirect"); - if (search != mat.iprops.end()) - flags.setSamusReflectionIndirectTexture(search->second != 0); - - search = mat.iprops.find("retro_lightmapped"); - if (search != mat.iprops.end()) - flags.setLightmap(search->second != 0); - - XXH64_state_t xxh; - XXH64_reset(&xxh, 0); - shaderType = mat.shaderType; - XXH64_update(&xxh, &shaderType, sizeof(shaderType)); - chunkCount = 0; - chunks.reserve(mat.chunks.size()); - for (const auto& chunk : mat.chunks) { - chunk.visit([this, &xxh](const auto& var) { - using T = std::decay_t; - chunks.push_back(Chunk::Build(T::variant_type(), var)); - var.hash(&xxh); - ++chunkCount; - }); - } - blendMode = mat.blendMode; - XXH64_update(&xxh, &blendMode, sizeof(blendMode)); - int hashFlags = 0; - if (flags.samusReflection()) - hashFlags |= 1; - if (flags.samusReflectionIndirectTexture()) - hashFlags |= 2; - if (flags.depthWrite()) - hashFlags |= 4; - if (flags.alphaTest()) - hashFlags |= 8; - XXH64_update(&xxh, &hashFlags, sizeof(hashFlags)); - hash = XXH64_digest(&xxh); -} - -MaterialSet::Material::UVAnimation::UVAnimation(const std::string& gameFunction, const std::vector& gameArgs) { - if (gameFunction == "RetroUVMode0NodeN") - mode = Mode::MvInvNoTranslation; - else if (gameFunction == "RetroUVMode1NodeN") - mode = Mode::MvInv; - else if (gameFunction == "RetroUVMode2Node") { - mode = Mode::Scroll; - if (gameArgs.size() < 2) - Log.report(logvisor::Fatal, FMT_STRING("Mode2 UV anim requires 2 vector arguments")); - vals[0] = gameArgs[0].simd[0]; - vals[1] = gameArgs[0].simd[1]; - vals[2] = gameArgs[1].simd[0]; - vals[3] = gameArgs[1].simd[1]; - } else if (gameFunction == "RetroUVMode3Node") { - mode = Mode::Rotation; - if (gameArgs.size() < 2) - Log.report(logvisor::Fatal, FMT_STRING("Mode3 UV anim requires 2 arguments")); - vals[0] = gameArgs[0].simd[0]; - vals[1] = gameArgs[1].simd[0]; - } else if (gameFunction == "RetroUVMode4Node") { - mode = Mode::HStrip; - if (gameArgs.size() < 4) - Log.report(logvisor::Fatal, FMT_STRING("Mode4 UV anim requires 4 arguments")); - vals[0] = gameArgs[0].simd[0]; - vals[1] = gameArgs[1].simd[0]; - vals[2] = gameArgs[2].simd[0]; - vals[3] = gameArgs[3].simd[0]; - } else if (gameFunction == "RetroUVMode5Node") { - mode = Mode::VStrip; - if (gameArgs.size() < 4) - Log.report(logvisor::Fatal, FMT_STRING("Mode5 UV anim requires 4 arguments")); - vals[0] = gameArgs[0].simd[0]; - vals[1] = gameArgs[1].simd[0]; - vals[2] = gameArgs[2].simd[0]; - vals[3] = gameArgs[3].simd[0]; - } else if (gameFunction == "RetroUVMode6NodeN") - mode = Mode::Model; - else if (gameFunction == "RetroUVMode7NodeN") { - mode = Mode::CylinderEnvironment; - if (gameArgs.size() < 2) - Log.report(logvisor::Fatal, FMT_STRING("Mode7 UV anim requires 2 arguments")); - vals[0] = gameArgs[0].simd[0]; - vals[1] = gameArgs[1].simd[0]; - } else - Log.report(logvisor::Fatal, FMT_STRING("unsupported UV anim '{}'"), gameFunction); -} - -template -void MaterialSet::Material::UVAnimation::Enumerate(typename Op::StreamT& s) { - Do({}, mode, s); - switch (mode) { - case Mode::MvInvNoTranslation: - case Mode::MvInv: - case Mode::Model: - break; - case Mode::Scroll: - case Mode::HStrip: - case Mode::VStrip: - for (int i = 0; i < 4; ++i) - Do({}, vals[i], s); - break; - case Mode::Rotation: - case Mode::CylinderEnvironment: - for (int i = 0; i < 2; ++i) - Do({}, vals[i], s); - break; - case Mode::Eight: - for (int i = 0; i < 9; ++i) - Do({}, vals[i], s); - break; - } -} - -AT_SPECIALIZE_DNA(MaterialSet::Material::UVAnimation) - -template -void HMDLMaterialSet::Material::PASS::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"type"}, type, s); - Do(athena::io::PropId{"texId"}, texId, s); - Do(athena::io::PropId{"source"}, source, s); - Do(athena::io::PropId{"uvAnimType"}, uvAnimType, s); - size_t uvParmCount = uvAnimParamsCount(); - for (size_t i = 0; i < uvParmCount; ++i) - Do({}, uvAnimParms[i], s); - Do(athena::io::PropId{"alpha"}, alpha, s); -} - -AT_SPECIALIZE_DNA(HMDLMaterialSet::Material::PASS) - -std::string_view HMDLMaterialSet::Material::PASS::DNAType() { - return "DataSpec::DNAMP1::HMDLMaterialSet::Material::PASS"sv; -} - -} // namespace DataSpec::DNAMP1 - -namespace DataSpec::DNAMP2 { - -void MaterialSet::ConstructMaterial(Stream& out, const MaterialSet::Material& material, unsigned groupIdx, - unsigned matIdx) { - DataSpec::DNAMP1::_ConstructMaterial(out, material, groupIdx, matIdx); -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP1/CMDLMaterials.hpp b/DataSpec/DNAMP1/CMDLMaterials.hpp deleted file mode 100644 index 355176df8..000000000 --- a/DataSpec/DNAMP1/CMDLMaterials.hpp +++ /dev/null @@ -1,640 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/GX.hpp" -#include "DataSpec/DNACommon/CMDL.hpp" -#include "DNAMP1.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -struct MaterialSet : BigDNA { - static constexpr bool OneSection() { return false; } - - AT_DECL_DNA - struct MaterialSetHead : BigDNA { - AT_DECL_DNA - Value textureCount = 0; - Vector textureIDs; - Value materialCount = 0; - Vector materialEndOffs; - - void addTexture(const UniqueID32& id) { - textureIDs.push_back(id); - ++textureCount; - } - void addMaterialEndOff(atUint32 off) { - materialEndOffs.push_back(off); - ++materialCount; - } - - template - void ensureTexturesExtracted(PAKRouter& pakRouter) const { - for (const auto& id : textureIDs) { - const nod::Node* node; - const PAK::Entry* texEntry = pakRouter.lookupEntry(id, &node); - if (!texEntry) - continue; - hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry); - if (txtrPath.isNone()) { - txtrPath.makeDirChain(false); - PAKEntryReadStream rs = texEntry->beginReadStream(*node); - TXTR::Extract(rs, txtrPath); - } - } - } - } head; - - struct Material : BigDNA { - AT_DECL_DNA - struct Flags : BigDNA { - AT_DECL_DNA - Value flags = 0; - bool konstValuesEnabled() const { return (flags & 0x8) != 0; } - void setKonstValuesEnabled(bool enabled) { - flags &= ~0x8; - flags |= atUint32(enabled) << 3; - } - bool depthSorting() const { return (flags & 0x10) != 0; } - void setDepthSorting(bool enabled) { - flags &= ~0x10; - flags |= atUint32(enabled) << 4; - } - bool alphaTest() const { return (flags & 0x20) != 0; } - void setAlphaTest(bool enabled) { - flags &= ~0x20; - flags |= atUint32(enabled) << 5; - } - bool samusReflection() const { return (flags & 0x40) != 0; } - void setSamusReflection(bool enabled) { - flags &= ~0x40; - flags |= atUint32(enabled) << 6; - } - bool depthWrite() const { return (flags & 0x80) != 0; } - void setDepthWrite(bool enabled) { - flags &= ~0x80; - flags |= atUint32(enabled) << 7; - } - bool samusReflectionSurfaceEye() const { return (flags & 0x100) != 0; } - void setSamusReflectionSurfaceEye(bool enabled) { - flags &= ~0x100; - flags |= atUint32(enabled) << 8; - } - bool shadowOccluderMesh() const { return (flags & 0x200) != 0; } - void setShadowOccluderMesh(bool enabled) { - flags &= ~0x200; - flags |= atUint32(enabled) << 9; - } - bool samusReflectionIndirectTexture() const { return (flags & 0x400) != 0; } - void setSamusReflectionIndirectTexture(bool enabled) { - flags &= ~0x400; - flags |= atUint32(enabled) << 10; - } - bool lightmap() const { return (flags & 0x800) != 0; } - void setLightmap(bool enabled) { - flags &= ~0x800; - flags |= atUint32(enabled) << 11; - } - bool lightmapUVArray() const { return (flags & 0x2000) != 0; } - void setLightmapUVArray(bool enabled) { - flags &= ~0x2000; - flags |= atUint32(enabled) << 13; - } - atUint16 textureSlots() const { return (flags >> 16) != 0; } - void setTextureSlots(atUint16 texslots) { - flags &= ~0xffff0000; - flags |= atUint32(texslots) << 16; - } - } flags; - const Flags& getFlags() const { return flags; } - - Value textureCount = 0; - Vector textureIdxs; - struct VAFlags : BigDNA { - AT_DECL_DNA - Value vaFlags = 0; - GX::AttrType position() const { return GX::AttrType(vaFlags & 0x3); } - void setPosition(GX::AttrType val) { - vaFlags &= ~0x3; - vaFlags |= atUint32(val); - } - GX::AttrType normal() const { return GX::AttrType(vaFlags >> 2 & 0x3); } - void setNormal(GX::AttrType val) { - vaFlags &= ~0xC; - vaFlags |= atUint32(val) << 2; - } - GX::AttrType color0() const { return GX::AttrType(vaFlags >> 4 & 0x3); } - void setColor0(GX::AttrType val) { - vaFlags &= ~0x30; - vaFlags |= atUint32(val) << 4; - } - GX::AttrType color1() const { return GX::AttrType(vaFlags >> 6 & 0x3); } - void setColor1(GX::AttrType val) { - vaFlags &= ~0xC0; - vaFlags |= atUint32(val) << 6; - } - GX::AttrType tex0() const { return GX::AttrType(vaFlags >> 8 & 0x3); } - void setTex0(GX::AttrType val) { - vaFlags &= ~0x300; - vaFlags |= atUint32(val) << 8; - } - GX::AttrType tex1() const { return GX::AttrType(vaFlags >> 10 & 0x3); } - void setTex1(GX::AttrType val) { - vaFlags &= ~0xC00; - vaFlags |= atUint32(val) << 10; - } - GX::AttrType tex2() const { return GX::AttrType(vaFlags >> 12 & 0x3); } - void setTex2(GX::AttrType val) { - vaFlags &= ~0x3000; - vaFlags |= atUint32(val) << 12; - } - GX::AttrType tex3() const { return GX::AttrType(vaFlags >> 14 & 0x3); } - void setTex3(GX::AttrType val) { - vaFlags &= ~0xC000; - vaFlags |= atUint32(val) << 14; - } - GX::AttrType tex4() const { return GX::AttrType(vaFlags >> 16 & 0x3); } - void setTex4(GX::AttrType val) { - vaFlags &= ~0x30000; - vaFlags |= atUint32(val) << 16; - } - GX::AttrType tex5() const { return GX::AttrType(vaFlags >> 18 & 0x3); } - void setTex5(GX::AttrType val) { - vaFlags &= ~0xC0000; - vaFlags |= atUint32(val) << 18; - } - GX::AttrType tex6() const { return GX::AttrType(vaFlags >> 20 & 0x3); } - void setTex6(GX::AttrType val) { - vaFlags &= ~0x300000; - vaFlags |= atUint32(val) << 20; - } - GX::AttrType pnMatIdx() const { return GX::AttrType(vaFlags >> 24 & 0x1); } - void setPnMatIdx(GX::AttrType val) { - vaFlags &= ~0x1000000; - vaFlags |= atUint32(val & 0x1) << 24; - } - GX::AttrType tex0MatIdx() const { return GX::AttrType(vaFlags >> 25 & 0x1); } - void setTex0MatIdx(GX::AttrType val) { - vaFlags &= ~0x2000000; - vaFlags |= atUint32(val & 0x1) << 25; - } - GX::AttrType tex1MatIdx() const { return GX::AttrType(vaFlags >> 26 & 0x1); } - void setTex1MatIdx(GX::AttrType val) { - vaFlags &= ~0x4000000; - vaFlags |= atUint32(val & 0x1) << 26; - } - GX::AttrType tex2MatIdx() const { return GX::AttrType(vaFlags >> 27 & 0x1); } - void setTex2MatIdx(GX::AttrType val) { - vaFlags &= ~0x8000000; - vaFlags |= atUint32(val & 0x1) << 27; - } - GX::AttrType tex3MatIdx() const { return GX::AttrType(vaFlags >> 28 & 0x1); } - void setTex3MatIdx(GX::AttrType val) { - vaFlags &= ~0x10000000; - vaFlags |= atUint32(val & 0x1) << 28; - } - GX::AttrType tex4MatIdx() const { return GX::AttrType(vaFlags >> 29 & 0x1); } - void setTex4MatIdx(GX::AttrType val) { - vaFlags &= ~0x20000000; - vaFlags |= atUint32(val & 0x1) << 29; - } - GX::AttrType tex5MatIdx() const { return GX::AttrType(vaFlags >> 30 & 0x1); } - void setTex5MatIdx(GX::AttrType val) { - vaFlags &= ~0x40000000; - vaFlags |= atUint32(val & 0x1) << 30; - } - GX::AttrType tex6MatIdx() const { return GX::AttrType(vaFlags >> 31 & 0x1); } - void setTex6MatIdx(GX::AttrType val) { - vaFlags &= ~0x80000000; - vaFlags |= atUint32(val & 0x1) << 31; - } - - size_t vertDLSize() const { - static size_t ATTR_SZ[] = {0, 1, 1, 2}; - size_t ret = 0; - ret += ATTR_SZ[position()]; - ret += ATTR_SZ[normal()]; - ret += ATTR_SZ[color0()]; - ret += ATTR_SZ[color1()]; - ret += ATTR_SZ[tex0()]; - ret += ATTR_SZ[tex1()]; - ret += ATTR_SZ[tex2()]; - ret += ATTR_SZ[tex3()]; - ret += ATTR_SZ[tex4()]; - ret += ATTR_SZ[tex5()]; - ret += ATTR_SZ[tex6()]; - ret += ATTR_SZ[pnMatIdx()]; - ret += ATTR_SZ[tex0MatIdx()]; - ret += ATTR_SZ[tex1MatIdx()]; - ret += ATTR_SZ[tex2MatIdx()]; - ret += ATTR_SZ[tex3MatIdx()]; - ret += ATTR_SZ[tex4MatIdx()]; - ret += ATTR_SZ[tex5MatIdx()]; - ret += ATTR_SZ[tex6MatIdx()]; - return ret; - } - } vaFlags; - const VAFlags& getVAFlags() const { return vaFlags; } - Value uniqueIdx; - - Vector konstCount; - Vector konstColors; - - using BlendFactor = GX::BlendFactor; - Value blendDstFac; - Value blendSrcFac; - Vector indTexSlot; - - Value colorChannelCount = 0; - struct ColorChannel : BigDNA { - AT_DECL_DNA - Value flags = 0; - bool lighting() const { return (flags & 0x1) != 0; } - void setLighting(bool enabled) { - flags &= ~0x1; - flags |= atUint32(enabled); - } - bool useAmbient() const { return (flags & 0x2) != 0; } - void setUseAmbient(bool enabled) { - flags &= ~0x2; - flags |= atUint32(enabled) << 1; - } - bool useMaterial() const { return (flags & 0x4) != 0; } - void setUseMaterial(bool enabled) { - flags &= ~0x4; - flags |= atUint32(enabled) << 2; - } - atUint8 lightmask() const { return atUint8(flags >> 3 & 0xff); } - void setLightmask(atUint8 mask) { - flags &= ~0x7f8; - flags |= atUint32(mask) << 3; - } - GX::DiffuseFn diffuseFn() const { return GX::DiffuseFn(flags >> 11 & 0x3); } - void setDiffuseFn(GX::DiffuseFn fn) { - flags &= ~0x1800; - flags |= atUint32(fn) << 11; - } - GX::AttnFn attenuationFn() const { return GX::AttnFn(flags >> 13 & 0x3); } - void setAttenuationFn(GX::AttnFn fn) { - flags &= ~0x6000; - flags |= atUint32(fn) << 13; - } - }; - Vector colorChannels; - - Value tevStageCount = 0; - struct TEVStage : BigDNA { - AT_DECL_DNA - Value ciFlags = 0; - Value aiFlags = 0; - Value ccFlags = 0; - Value acFlags = 0; - Value pad = 0; - Value kaInput = 0; - Value kcInput = 0; - Value rascInput = 0; - - GX::TevColorArg colorInA() const { return GX::TevColorArg(ciFlags & 0xf); } - void setColorInA(GX::TevColorArg val) { - ciFlags &= ~0x1f; - ciFlags |= atUint32(val); - } - GX::TevColorArg colorInB() const { return GX::TevColorArg(ciFlags >> 5 & 0xf); } - void setColorInB(GX::TevColorArg val) { - ciFlags &= ~0x3e0; - ciFlags |= atUint32(val) << 5; - } - GX::TevColorArg colorInC() const { return GX::TevColorArg(ciFlags >> 10 & 0xf); } - void setColorInC(GX::TevColorArg val) { - ciFlags &= ~0x7c00; - ciFlags |= atUint32(val) << 10; - } - GX::TevColorArg colorInD() const { return GX::TevColorArg(ciFlags >> 15 & 0xf); } - void setColorInD(GX::TevColorArg val) { - ciFlags &= ~0xf8000; - ciFlags |= atUint32(val) << 15; - } - - GX::TevAlphaArg alphaInA() const { return GX::TevAlphaArg(aiFlags & 0x7); } - void setAlphaInA(GX::TevAlphaArg val) { - aiFlags &= ~0x1f; - aiFlags |= atUint32(val); - } - GX::TevAlphaArg alphaInB() const { return GX::TevAlphaArg(aiFlags >> 5 & 0x7); } - void setAlphaInB(GX::TevAlphaArg val) { - aiFlags &= ~0x3e0; - aiFlags |= atUint32(val) << 5; - } - GX::TevAlphaArg alphaInC() const { return GX::TevAlphaArg(aiFlags >> 10 & 0x7); } - void setAlphaInC(GX::TevAlphaArg val) { - aiFlags &= ~0x7c00; - aiFlags |= atUint32(val) << 10; - } - GX::TevAlphaArg alphaInD() const { return GX::TevAlphaArg(aiFlags >> 15 & 0x7); } - void setAlphaInD(GX::TevAlphaArg val) { - aiFlags &= ~0xf8000; - aiFlags |= atUint32(val) << 15; - } - - GX::TevOp colorOp() const { return GX::TevOp(ccFlags & 0xf); } - void setColorOp(GX::TevOp val) { - ccFlags &= ~0x1; - ccFlags |= atUint32(val); - } - GX::TevBias colorOpBias() const { return GX::TevBias(ccFlags >> 4 & 0x3); } - void setColorOpBias(GX::TevBias val) { - ccFlags &= ~0x30; - ccFlags |= atUint32(val) << 4; - } - GX::TevScale colorOpScale() const { return GX::TevScale(ccFlags >> 6 & 0x3); } - void setColorOpScale(GX::TevScale val) { - ccFlags &= ~0xc0; - ccFlags |= atUint32(val) << 6; - } - bool colorOpClamp() const { return ccFlags >> 8 & 0x1; } - void setColorOpClamp(bool val) { - ccFlags &= ~0x100; - ccFlags |= atUint32(val) << 8; - } - GX::TevRegID colorOpOutReg() const { return GX::TevRegID(ccFlags >> 9 & 0x3); } - void setColorOpOutReg(GX::TevRegID val) { - ccFlags &= ~0x600; - ccFlags |= atUint32(val) << 9; - } - - GX::TevOp alphaOp() const { return GX::TevOp(acFlags & 0xf); } - void setAlphaOp(GX::TevOp val) { - acFlags &= ~0x1; - acFlags |= atUint32(val); - } - GX::TevBias alphaOpBias() const { return GX::TevBias(acFlags >> 4 & 0x3); } - void setAlphaOpBias(GX::TevBias val) { - acFlags &= ~0x30; - acFlags |= atUint32(val) << 4; - } - GX::TevScale alphaOpScale() const { return GX::TevScale(acFlags >> 6 & 0x3); } - void setAlphaOpScale(GX::TevScale val) { - acFlags &= ~0xc0; - acFlags |= atUint32(val) << 6; - } - bool alphaOpClamp() const { return acFlags >> 8 & 0x1; } - void setAlphaOpClamp(bool val) { - acFlags &= ~0x100; - acFlags |= atUint32(val) << 8; - } - GX::TevRegID alphaOpOutReg() const { return GX::TevRegID(acFlags >> 9 & 0x3); } - void setAlphaOpOutReg(GX::TevRegID val) { - acFlags &= ~0x600; - acFlags |= atUint32(val) << 9; - } - - GX::TevKColorSel kColorIn() const { return GX::TevKColorSel(kcInput); } - void setKColorIn(GX::TevKColorSel val) { kcInput = val; } - GX::TevKAlphaSel kAlphaIn() const { return GX::TevKAlphaSel(kaInput); } - void setKAlphaIn(GX::TevKAlphaSel val) { kaInput = val; } - - GX::ChannelID rasIn() const { return GX::ChannelID(rascInput); } - void setRASIn(GX::ChannelID id) { rascInput = id; } - }; - Vector tevStages; - struct TEVStageTexInfo : BigDNA { - AT_DECL_DNA - Value pad = 0; - Value texSlot = 0xff; - Value tcgSlot = 0xff; - }; - Vector tevStageTexInfo; - - Value tcgCount = 0; - struct TexCoordGen : BigDNA { - AT_DECL_DNA - Value flags = 0; - - GX::TexGenType type() const { return GX::TexGenType(flags & 0xf); } - void setType(GX::TexGenType val) { - flags &= ~0xf; - flags |= atUint32(val); - } - GX::TexGenSrc source() const { return GX::TexGenSrc(flags >> 4 & 0x1f); } - void setSource(GX::TexGenSrc val) { - flags &= ~0x1f0; - flags |= atUint32(val) << 4; - } - GX::TexMtx mtx() const { return GX::TexMtx((flags >> 9 & 0x1f) + 30); } - void setMtx(GX::TexMtx val) { - flags &= ~0x3e00; - flags |= (atUint32(val) - 30) << 9; - } - bool normalize() const { return flags >> 14 & 0x1; } - void setNormalize(bool val) { - flags &= ~0x4000; - flags |= atUint32(val) << 14; - } - GX::PTTexMtx postMtx() const { return GX::PTTexMtx((flags >> 15 & 0x3f) + 64); } - void setPostMtx(GX::PTTexMtx val) { - flags &= ~0x1f8000; - flags |= (atUint32(val) - 64) << 15; - } - }; - Vector tcgs; - - Value uvAnimsSize = 4; - Value uvAnimsCount = 0; - struct UVAnimation : BigDNA { - AT_DECL_EXPLICIT_DNA - enum class Mode { - MvInvNoTranslation, - MvInv, - Scroll, - Rotation, - HStrip, - VStrip, - Model, - CylinderEnvironment, - Eight - } mode; - float vals[9]; - - UVAnimation() = default; - UVAnimation(const std::string& gameFunction, const std::vector& gameArgs); - }; - Vector uvAnims; - - static void AddTexture(hecl::blender::PyOutStream& out, GX::TexGenSrc type, int mtxIdx, uint32_t texIdx, - bool diffuse); - static void AddTextureAnim(hecl::blender::PyOutStream& out, MaterialSet::Material::UVAnimation::Mode type, - unsigned idx, const float* vals); - static void AddKcolor(hecl::blender::PyOutStream& out, const GX::Color& col, unsigned idx); - static void AddDynamicColor(hecl::blender::PyOutStream& out, unsigned idx); - static void AddDynamicAlpha(hecl::blender::PyOutStream& out, unsigned idx); - - Material() = default; - Material(const hecl::blender::Material& material, std::vector& texPathsOut, int colorCount, - bool lightmapUVs, bool matrixSkinning); - }; - Vector materials; - - static void RegisterMaterialProps(hecl::blender::PyOutStream& out); - static void ConstructMaterial(hecl::blender::PyOutStream& out, const MaterialSet::Material& material, - unsigned groupIdx, unsigned matIdx); - - void readToBlender(hecl::blender::PyOutStream& os, const PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, unsigned setIdx) { - DNACMDL::ReadMaterialSetToBlender_1_2(os, *this, pakRouter, entry, setIdx); - } - - template - void nameTextures(PAKRouter& pakRouter, const char* prefix, int setIdx) const { - int matIdx = 0; - for (const Material& mat : materials) { - int stageIdx = 0; - for (const Material::TEVStage& stage : mat.tevStages) { - (void)stage; - const Material::TEVStageTexInfo& texInfo = mat.tevStageTexInfo[stageIdx]; - if (texInfo.texSlot == 0xff) { - ++stageIdx; - continue; - } - const nod::Node* node; - typename PAKRouter::EntryType* texEntry = (typename PAKRouter::EntryType*)pakRouter.lookupEntry( - head.textureIDs[mat.textureIdxs[texInfo.texSlot]], &node); - if (texEntry->name.size()) { - if (texEntry->name.size() < 5 || texEntry->name.compare(0, 5, "mult_")) - texEntry->name = "mult_" + texEntry->name; - ++stageIdx; - continue; - } - if (setIdx < 0) - texEntry->name = fmt::format(FMT_STRING("{}_{}_{}"), prefix, matIdx, stageIdx); - else - texEntry->name = fmt::format(FMT_STRING("{}_{}_{}_{}"), prefix, setIdx, matIdx, stageIdx); - - if (mat.flags.lightmap() && stageIdx == 0) { - texEntry->name += "light"; - ++stageIdx; - continue; - } - - ++stageIdx; - } - ++matIdx; - } - } - - void ensureTexturesExtracted(PAKRouter& pakRouter) const { head.ensureTexturesExtracted(pakRouter); } -}; - -struct HMDLMaterialSet : BigDNA { - static constexpr bool OneSection() { return false; } - - AT_DECL_DNA - Value materialCount = 0; - Vector materialEndOffs; - - struct Material : BigDNA { - AT_DECL_DNA - MaterialSet::Material::Flags flags; - - using BlendMaterial = hecl::blender::Material; - - struct PASS : hecl::TypedRecordBigDNA { - AT_DECL_EXPLICIT_DNA - Value type; - UniqueID32 texId; - Value source; - Value uvAnimType; - Value uvAnimParms[9] = {}; - Value alpha; - PASS() = default; - explicit PASS(const BlendMaterial::PASS& pass) - : type(pass.type), texId(pass.tex), source(pass.source), uvAnimType(pass.uvAnimType), alpha(pass.alpha) { - std::copy(pass.uvAnimParms.begin(), pass.uvAnimParms.end(), std::begin(uvAnimParms)); - } - bool shouldNormalizeUv() const { - switch (uvAnimType) { - case BlendMaterial::UVAnimType::MvInvNoTranslation: - case BlendMaterial::UVAnimType::MvInv: - case BlendMaterial::UVAnimType::Model: - case BlendMaterial::UVAnimType::CylinderEnvironment: - return true; - default: - return false; - } - } - size_t uvAnimParamsCount() const { - switch (uvAnimType) { - default: - return 0; - case BlendMaterial::UVAnimType::Scroll: - case BlendMaterial::UVAnimType::HStrip: - case BlendMaterial::UVAnimType::VStrip: - return 4; - case BlendMaterial::UVAnimType::Rotation: - case BlendMaterial::UVAnimType::CylinderEnvironment: - return 2; - case BlendMaterial::UVAnimType::Eight: - return 9; - } - } - }; - struct CLR : hecl::TypedRecordBigDNA { - AT_DECL_DNA - Value type; - Value color; - CLR() = default; - explicit CLR(const BlendMaterial::CLR& clr) : type(clr.type), color(clr.color.val) {} - }; - using Chunk = hecl::TypedVariantBigDNA; - - static unsigned TexMapIdx(BlendMaterial::PassType type) { - switch (type) { - case BlendMaterial::PassType::Lightmap: - return 0; - case BlendMaterial::PassType::Diffuse: - return 1; - case BlendMaterial::PassType::Emissive: - return 2; - case BlendMaterial::PassType::Specular: - return 3; - case BlendMaterial::PassType::ExtendedSpecular: - return 4; - case BlendMaterial::PassType::Reflection: - return 5; - case BlendMaterial::PassType::Alpha: - return 6; - case BlendMaterial::PassType::IndirectTex: - return 7; - default: - assert(false && "Unknown pass type"); - return 0; - } - } - - Value hash; - Value shaderType; - Value chunkCount; - Vector chunks; - Value blendMode = BlendMaterial::BlendMode::Opaque; - - std::pair blendFactors() const { - switch (blendMode) { - case BlendMaterial::BlendMode::Opaque: - default: - return {hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::Zero}; - case BlendMaterial::BlendMode::Alpha: - return {hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha}; - case BlendMaterial::BlendMode::Additive: - return {hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One}; - } - } - - Material() = default; - Material(const hecl::blender::Material& mat); - }; - Vector materials; -}; - -} // namespace DataSpec::DNAMP1 - -AT_SPECIALIZE_TYPED_VARIANT_BIGDNA(DataSpec::DNAMP1::HMDLMaterialSet::Material::PASS, - DataSpec::DNAMP1::HMDLMaterialSet::Material::CLR) diff --git a/DataSpec/DNAMP1/CMakeLists.txt b/DataSpec/DNAMP1/CMakeLists.txt deleted file mode 100644 index 9c28078fc..000000000 --- a/DataSpec/DNAMP1/CMakeLists.txt +++ /dev/null @@ -1,68 +0,0 @@ -include(DNAMP1/ScriptObjects/CMakeLists.txt) -include(DNAMP1/SFX/CMakeLists.txt) - -make_dnalist(PAK - MLVL - AGSC - CSNG - AFSM - ANCS - ANIM - CINF - CSKR - EVNT - CMDLMaterials - MREA - DeafBabe - SCAN - FRME - SAVW - HINT - MazeSeeds - SnowForces - DCLN - Tweaks/CTweakGame - Tweaks/CTweakParticle - Tweaks/CTweakPlayer - Tweaks/CTweakPlayerControl - Tweaks/CTweakPlayerGun - Tweaks/CTweakGunRes - Tweaks/CTweakPlayerRes - Tweaks/CTweakGui - Tweaks/CTweakSlideShow - Tweaks/CTweakCameraBob - Tweaks/CTweakTargeting - Tweaks/CTweakAutoMapper - Tweaks/CTweakBall - Tweaks/CTweakGuiColors) - -set(DNAMP1_SOURCES - DNAMP1.hpp DNAMP1.cpp - AFSM.cpp - PAK.cpp - MLVL.cpp - STRG.hpp STRG.cpp - AGSC.cpp - CSNG.cpp - CSKR.cpp - ANCS.cpp - ANIM.cpp - CINF.cpp - EVNT.cpp - PATH.hpp - CMDL.hpp CMDL.cpp - CMDLMaterials.cpp - DCLN.cpp - MAPA.hpp - MAPU.hpp - MREA.cpp - SCLY.hpp SCLY.cpp - FRME.cpp - SCAN.cpp - DeafBabe.cpp - Tweaks/CTweakPlayer.cpp - Tweaks/CTweakTargeting.cpp - Tweaks/CTweakBall.cpp - ) - -dataspec_add_list(DNAMP1 DNAMP1_SOURCES) diff --git a/DataSpec/DNAMP1/CSKR.cpp b/DataSpec/DNAMP1/CSKR.cpp deleted file mode 100644 index 7c4083a11..000000000 --- a/DataSpec/DNAMP1/CSKR.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "CSKR.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -void CSKR::weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atUint32 idx) const { - atUint32 accum = 0; - for (const SkinningRule& rule : skinningRules) { - if (idx >= accum && idx < accum + rule.vertCount) - for (const SkinningRule::Weight& weight : rule.weights) - os.format(FMT_STRING("vert[dvert_lay][{}] = {}\n"), cinf.getBoneIdxFromId(weight.boneId), weight.weight); - accum += rule.vertCount; - } -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CSKR.hpp b/DataSpec/DNAMP1/CSKR.hpp deleted file mode 100644 index c31c9234a..000000000 --- a/DataSpec/DNAMP1/CSKR.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "CINF.hpp" - -namespace DataSpec::DNAMP1 { - -struct CSKR : BigDNA { - AT_DECL_DNA - Value skinningRuleCount; - struct SkinningRule : BigDNA { - AT_DECL_DNA - Value weightCount; - struct Weight : BigDNA { - AT_DECL_DNA - Value boneId; - Value weight; - }; - Vector weights; - Value vertCount; - }; - Vector skinningRules; - - const atInt16* getMatrixBank(size_t) const { return nullptr; } - - void weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atUint32 idx) const; -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CSNG.cpp b/DataSpec/DNAMP1/CSNG.cpp deleted file mode 100644 index 949003df0..000000000 --- a/DataSpec/DNAMP1/CSNG.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "CSNG.hpp" -#include "amuse/SongConverter.hpp" - -namespace DataSpec::DNAMP1 { - -bool CSNG::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - hecl::ProjectPath midPath = outPath.getWithExtension(".mid", true); - hecl::ProjectPath yamlPath = outPath.getWithExtension(".yaml", true); - - Header head; - head.read(rs); - - { - athena::io::YAMLDocWriter dw("CSNG"); - dw.writeUint32("midiSetupId", head.midiSetupId); - dw.writeUint32("songGroupId", head.songGroupId); - if (auto rec = dw.enterSubRecord("agscId")) - head.agscId.write(dw); - - athena::io::FileWriter w(yamlPath.getAbsolutePath()); - if (w.hasError()) - return false; - dw.finish(&w); - } - - { - auto sng = rs.readUBytes(head.sngLength); - int version; - bool isBig; - auto midi = amuse::SongConverter::SongToMIDI(sng.get(), version, isBig); - - athena::io::FileWriter w(midPath.getAbsolutePath()); - if (w.hasError()) - return false; - w.writeUBytes(midi.data(), midi.size()); - } - - /* Update !songs.yaml for Amuse editor */ - hecl::ProjectPath audGrp(outPath.getParentPath().getParentPath(), "AudioGrp"); - audGrp.makeDirChain(true); - hecl::ProjectPath songsPath(audGrp, "!songs.yaml"); - std::optional r; - if (songsPath.isFile()) - r.emplace(songsPath.getAbsolutePath()); - athena::io::YAMLDocWriter ydw("amuse::Songs", r ? &*r : nullptr); - r = std::nullopt; - ydw.writeString(fmt::format(FMT_STRING("{:04X}"), head.midiSetupId), - fmt::format(FMT_STRING("../MidiData/{}"), midPath.getLastComponent())); - athena::io::FileWriter w(songsPath.getAbsolutePath()); - ydw.finish(&w); - - return true; -} - -bool CSNG::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - hecl::ProjectPath midPath = inPath.getWithExtension(".mid", true); - hecl::ProjectPath yamlPath = inPath.getWithExtension(".yaml", true); - - std::vector sngData; - { - athena::io::FileReader midR(midPath.getAbsolutePath()); - if (midR.hasError()) - return false; - - uint32_t midLen = midR.length(); - std::vector midData; - midData.resize(midLen); - midR.readUBytesToBuf(midData.data(), midLen); - sngData = amuse::SongConverter::MIDIToSong(midData, 1, true); - } - - athena::io::FileWriter w(outPath.getAbsolutePath()); - if (w.hasError()) - return false; - - { - athena::io::FileReader yamlR(yamlPath.getAbsolutePath()); - if (yamlR.hasError()) - return false; - athena::io::YAMLDocReader dr; - if (!dr.parse(&yamlR)) - return false; - - Header head; - head.midiSetupId = dr.readUint32("midiSetupId"); - head.songGroupId = dr.readUint32("songGroupId"); - if (auto rec = dr.enterSubRecord("agscId")) - head.agscId.read(dr); - head.sngLength = sngData.size(); - head.write(w); - } - - w.writeUBytes(sngData.data(), sngData.size()); - - return true; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CSNG.hpp b/DataSpec/DNAMP1/CSNG.hpp deleted file mode 100644 index da45efe47..000000000 --- a/DataSpec/DNAMP1/CSNG.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -class CSNG { - struct Header : BigDNA { - AT_DECL_DNA - Value magic = 0x2; - Value midiSetupId; - Value songGroupId; - UniqueID32 agscId; - Value sngLength; - }; - -public: - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/DCLN.cpp b/DataSpec/DNAMP1/DCLN.cpp deleted file mode 100644 index 330ec144d..000000000 --- a/DataSpec/DNAMP1/DCLN.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "DCLN.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -#if DCLN_DUMP_OBB -void DCLN::Collision::Node::sendToBlender(hecl::blender::PyOutStream& os) const { - os.format( - "obj = bpy.data.objects.new('%s', None)\n" - "obj.empty_display_type = 'CUBE'\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "obj.rotation_mode = 'QUATERNION'\n" - "obj.location = mtxd[0]\n" - "obj.rotation_quaternion = mtxd[1]\n" - "obj.scale = (%f,%f,%f)\n", - isLeaf ? "leaf" : "branch", xf[0].simd[0], xf[0].simd[1], xf[0].simd[2], xf[0].simd[3], xf[1].simd[0], - xf[1].simd[1], xf[1].simd[2], xf[1].simd[3], xf[2].simd[0], xf[2].simd[1], xf[2].simd[2], xf[2].simd[3], - halfExtent.simd[0], halfExtent.simd[1], halfExtent.simd[2]); - if (isLeaf) - os << "obj.show_name = True\n"; - if (!isLeaf) { - left->sendToBlender(os); - right->sendToBlender(os); - } -} -#endif - -void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entryName) { - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os.format(FMT_STRING("import bpy\n" - "import bmesh\n" - "from mathutils import Vector, Matrix\n" - "\n" - "bpy.context.scene.name = '{}'\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n"), - entryName); - - DeafBabe::BlenderInit(os); - atInt32 idx = 0; - for (const Collision& col : collision) { - DeafBabeSendToBlender(os, col, true, idx++); -#if DCLN_DUMP_OBB - col.root.sendToBlender(os); -#endif - } - os.centerView(); - os.close(); -} - -bool DCLN::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - DCLN dcln; - dcln.read(rs); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::ColMesh)) - return false; - - dcln.sendToBlender(conn, pakRouter.getBestEntryName(entry, false)); - return conn.saveBlend(); -} - -bool DCLN::Cook(const hecl::ProjectPath& outPath, const std::vector& meshes) { - DCLN dcln; - dcln.colCount = atUint32(meshes.size()); - for (const Mesh& mesh : meshes) { - dcln.collision.emplace_back(); - Collision& colOut = dcln.collision.back(); - DeafBabeBuildFromBlender(colOut, mesh); - colOut.root = std::move(*OBBTreeBuilder::buildCol(mesh)); - colOut.memSize = atUint32(colOut.root.getMemoryUsage()); - } - -#if DCLN_DUMP_OBB - hecl::blender::Connection& conn = hecl::blender::SharedBlenderToken.getBlenderConnection(); - conn.createBlend(outPath.getWithExtension(".blend"), hecl::blender::BlendType::ColMesh); - dcln.sendToBlender(conn, "BLAH"); - conn.saveBlend(); -#endif - - athena::io::FileWriter w(outPath.getAbsolutePath()); - dcln.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/DCLN.hpp b/DataSpec/DNAMP1/DCLN.hpp deleted file mode 100644 index 380de3e44..000000000 --- a/DataSpec/DNAMP1/DCLN.hpp +++ /dev/null @@ -1,120 +0,0 @@ -#pragma once - -#include "athena/Types.hpp" -#include "DataSpec/DNACommon/DeafBabe.hpp" -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/OBBTreeBuilder.hpp" -#include "DNAMP1.hpp" -#include "DeafBabe.hpp" - -#define DCLN_DUMP_OBB 0 - -namespace DataSpec::DNAMP1 { - -struct DCLN : BigDNA { - using Mesh = hecl::blender::ColMesh; - - AT_DECL_DNA - Value colCount; - struct Collision : BigDNA { - using Material = DeafBabe::Material; - using Edge = DeafBabe::Edge; - using Triangle = DeafBabe::Triangle; - - AT_DECL_DNA - Value magic; - Value version; - Value memSize; - Value materialCount; - Vector materials; - Value vertMatsCount; - Vector vertMats; - Value edgeMatsCount; - Vector edgeMats; - Value triMatsCount; - Vector triMats; - Value edgeVertsCount; - Vector edgeVertConnections; - Value triangleEdgesCount; - Vector triangleEdgeConnections; - Value vertCount; - Vector verts; - - struct Node : BigDNA { - AT_DECL_EXPLICIT_DNA - - struct LeafData : BigDNA { - AT_DECL_DNA - Value triangleIndexCount; - Vector triangleIndices; - size_t getMemoryUsage() const { return (((triangleIndices.size() * 2) + 16) + 3) & ~3; } - }; - - Value xf[3]; - Value halfExtent; - Value isLeaf; - std::unique_ptr leafData; - std::unique_ptr left; - std::unique_ptr right; - - size_t getMemoryUsage() const { - size_t ret = 80; - if (isLeaf) - ret += leafData->getMemoryUsage(); - else { - ret += left->getMemoryUsage(); - ret += right->getMemoryUsage(); - } - - return (ret + 3) & ~3; - } - -#if DCLN_DUMP_OBB - void sendToBlender(hecl::blender::PyOutStream& os) const; -#endif - }; - Node root; - size_t getMemoryUsage() const { return root.getMemoryUsage(); } - - /* Dummy MP2 member */ - void insertNoClimb(hecl::blender::PyOutStream&) const {} - }; - - Vector collision; - - void sendToBlender(hecl::blender::Connection& conn, std::string_view entryName); - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged); - - static bool Cook(const hecl::ProjectPath& outPath, const std::vector& meshes); -}; - -template -void DCLN::Collision::Node::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"xf[0]"}, xf[0], s); - Do(athena::io::PropId{"xf[1]"}, xf[1], s); - Do(athena::io::PropId{"xf[2]"}, xf[2], s); - Do(athena::io::PropId{"halfExtent"}, halfExtent, s); - Do(athena::io::PropId{"isLeaf"}, isLeaf, s); - if (isLeaf) { - if (!leafData) { - leafData = std::make_unique(); - } - Do(athena::io::PropId{"leafData"}, *leafData, s); - } else { - if (!left) { - left = std::make_unique(); - } - Do(athena::io::PropId{"left"}, *left, s); - if (!right) { - right = std::make_unique(); - } - Do(athena::io::PropId{"right"}, *right, s); - } -} - -AT_SPECIALIZE_DNA(DCLN::Collision::Node) - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/DNAMP1.cpp b/DataSpec/DNAMP1/DNAMP1.cpp deleted file mode 100644 index aeda873f6..000000000 --- a/DataSpec/DNAMP1/DNAMP1.cpp +++ /dev/null @@ -1,440 +0,0 @@ -#include - -#define NOD_ATHENA 1 -#include "DNAMP1.hpp" -#include "STRG.hpp" -#include "SCAN.hpp" -#include "MLVL.hpp" -#include "DataSpec/DNACommon/TXTR.hpp" -#include "DataSpec/DNACommon/PART.hpp" -#include "DataSpec/DNACommon/ELSC.hpp" -#include "DataSpec/DNACommon/SWHC.hpp" -#include "DataSpec/DNACommon/CRSC.hpp" -#include "DataSpec/DNACommon/WPSC.hpp" -#include "DataSpec/DNACommon/DPSC.hpp" -#include "DataSpec/DNACommon/FONT.hpp" -#include "DataSpec/DNACommon/DGRP.hpp" -#include "DataSpec/DNACommon/ATBL.hpp" -#include "HINT.hpp" -#include "CMDL.hpp" -#include "AFSM.hpp" -#include "SAVW.hpp" -#include "ANCS.hpp" -#include "MREA.hpp" -#include "MAPA.hpp" -#include "MAPU.hpp" -#include "FRME.hpp" -#include "AGSC.hpp" -#include "CSNG.hpp" -#include "DCLN.hpp" -#include "PATH.hpp" - -#include "DataSpec/DNACommon/Tweaks/TweakWriter.hpp" -#include "DataSpec/DNACommon/MetaforceVersionInfo.hpp" -#include "Tweaks/CTweakPlayerRes.hpp" -#include "Tweaks/CTweakGunRes.hpp" -#include "Tweaks/CTweakPlayer.hpp" -#include "Tweaks/CTweakCameraBob.hpp" -#include "Tweaks/CTweakSlideShow.hpp" -#include "Tweaks/CTweakGame.hpp" -#include "Tweaks/CTweakTargeting.hpp" -#include "Tweaks/CTweakAutoMapper.hpp" -#include "Tweaks/CTweakGui.hpp" -#include "Tweaks/CTweakPlayerControl.hpp" -#include "Tweaks/CTweakBall.hpp" -#include "Tweaks/CTweakParticle.hpp" -#include "Tweaks/CTweakGuiColors.hpp" -#include "Tweaks/CTweakPlayerGun.hpp" -#include "MazeSeeds.hpp" -#include "SnowForces.hpp" - -namespace DataSpec::DNAMP1 { -logvisor::Module Log("DataSpec::DNAMP1"); - -static bool GetNoShare(std::string_view name) { - std::string lowerName(name); - std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower); - if (!lowerName.compare(0, 7, "metroid")) - return false; - return true; -} - -PAKBridge::PAKBridge(const nod::Node& node, bool doExtract) -: m_node(node), m_pak(false, GetNoShare(node.getName())), m_doExtract(doExtract) { - nod::AthenaPartReadStream rs(node.beginReadStream()); - m_pak.read(rs); - - /* Append Level String */ - for (auto& [id, entry] : m_pak.m_entries) { - if (entry.type == FOURCC('MLVL')) { - m_levelId = entry.id; - PAKEntryReadStream rs = entry.beginReadStream(m_node); - MLVL mlvl; - mlvl.read(rs); - PAK::Entry* nameEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldNameId); - if (nameEnt) { - nameEnt->name = entry.name + "_name"; - PAKEntryReadStream rs = nameEnt->beginReadStream(m_node); - STRG mlvlName; - mlvlName.read(rs); - if (m_levelString.size()) - m_levelString += ", "; - m_levelString += mlvlName.getUTF8(FOURCC('ENGL'), 0); - } - } - } -} - -static std::string LayerName(std::string_view name) { - std::string ret(name); - for (auto& ch : ret) - if (ch == '/' || ch == '\\') - ch = '-'; - return ret; -} - -void PAKBridge::build() { - /* First pass: build per-area/per-layer dependency map */ - for (const auto& [id, entry] : m_pak.m_entries) { - if (entry.type == FOURCC('MLVL')) { - Level& level = m_levelDeps[entry.id]; - - MLVL mlvl; - { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - mlvl.read(rs); - } - std::string catalogueName; - std::string bestName = m_pak.bestEntryName(m_node, entry, catalogueName); - level.name = bestName; - level.areas.reserve(mlvl.areaCount); - unsigned layerIdx = 0; - - /* Make MAPW available to lookup MAPAs */ - PAK::Entry* worldMapEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldMap); - std::vector mapw; - if (worldMapEnt) { - worldMapEnt->name = entry.name + "_mapw"; - PAKEntryReadStream rs = worldMapEnt->beginReadStream(m_node); - rs.seek(8, athena::SeekOrigin::Current); - atUint32 areaCount = rs.readUint32Big(); - mapw.reserve(areaCount); - for (atUint32 i = 0; i < areaCount; ++i) - mapw.emplace_back(rs); - level.resources.insert(mlvl.worldMap); - } - - PAK::Entry* savwEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.saveWorldId); - if (savwEnt) { - savwEnt->name = entry.name + "_savw"; - level.resources.insert(mlvl.saveWorldId); - } - - PAK::Entry* skyEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldSkyboxId); - if (skyEnt) { - skyEnt->name = entry.name + "_skybox"; - level.resources.insert(mlvl.worldSkyboxId); - } - - /* Index areas */ - unsigned ai = 0; - for (const MLVL::Area& area : mlvl.areas) { - Level::Area& areaDeps = level.areas[area.areaMREAId]; - MLVL::LayerFlags& layerFlags = mlvl.layerFlags[ai]; - PAK::Entry* areaNameEnt = (PAK::Entry*)m_pak.lookupEntry(area.areaNameId); - if (areaNameEnt) { - STRG areaName; - { - PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node); - areaName.read(rs); - } - areaDeps.name = areaName.getUTF8(FOURCC('ENGL'), 0); - areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name); - } - if (areaDeps.name.empty()) { - std::string idStr = area.areaMREAId.toString(); - areaDeps.name = std::string("MREA_") + idStr; - } - std::string num = fmt::format(FMT_STRING("{:02d} "), ai); - areaDeps.name = num + areaDeps.name; - - std::string lowerName(areaDeps.name); - for (char& ch : lowerName) { - ch = tolower(ch); - if (ch == ' ') - ch = '_'; - } - if (areaNameEnt) - areaNameEnt->name = lowerName + "_name"; - PAK::Entry* areaEnt = (PAK::Entry*)m_pak.lookupEntry(area.areaMREAId); - if (areaEnt) - areaEnt->name = lowerName; - - areaDeps.layers.reserve(area.depLayerCount - 1); - unsigned r = 0; - for (unsigned l = 1; l < area.depLayerCount; ++l) { - areaDeps.layers.emplace_back(); - Level::Area::Layer& layer = areaDeps.layers.back(); - layer.name = LayerName(mlvl.layerNames[layerIdx++]); - layer.active = layerFlags.flags >> (l - 1) & 0x1; - layer.name = hecl::StringUtils::TrimWhitespace(layer.name); - - num = fmt::format(FMT_STRING("{:02d} "), l - 1); - layer.name = num + layer.name; - - layer.resources.reserve(area.depLayers[l] - r); - for (; r < area.depLayers[l]; ++r) - layer.resources.emplace(area.deps[r].id); - } - areaDeps.resources.reserve(area.depCount - r + 2); - for (; r < area.depCount; ++r) - areaDeps.resources.emplace(area.deps[r].id); - areaDeps.resources.emplace(area.areaMREAId); - if (mapw.size() > ai) - areaDeps.resources.emplace(mapw[ai]); - ++ai; - } - } - } - - /* Second pass: cross-compare uniqueness */ - for (auto& [id, entry] : m_pak.m_entries) - entry.unique.checkEntry(*this, entry); -} - -void PAKBridge::addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const { - for (const auto& [id, entry] : m_pak.m_entries) { - if (entry.type == FOURCC('ANCS')) { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - ANCS ancs; - ancs.read(rs); - for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters) { - charAssoc.m_cmdlRigs[ci.cmdl] = {ci.cskr, ci.cinf}; - charAssoc.m_cskrToCharacter[ci.cskr] = - std::make_pair(entry.id, fmt::format(FMT_STRING("{}_{}.CSKR"), ci.name, ci.cskr)); - PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdl); - PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskr); - PAK::Entry* cinfEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cinf); - if (cmdlEnt != nullptr && cskrEnt != nullptr && cinfEnt != nullptr) { - cmdlEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}_model"), id, ci.name); - cskrEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}_skin"), id, ci.name); - cinfEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}_skel"), id, ci.name); - if (ci.cmdlIce.isValid() && ci.cskrIce.isValid()) { - charAssoc.m_cmdlRigs[ci.cmdlIce] = {ci.cskrIce, ci.cinf}; - charAssoc.m_cskrToCharacter[ci.cskrIce] = - std::make_pair(entry.id, fmt::format(FMT_STRING("{}.ICE_{}.CSKR"), ci.name, ci.cskrIce)); - PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdlIce); - PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskrIce); - cmdlEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}_icemodel"), id, ci.name); - cskrEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}_iceskin"), id, ci.name); - } - } - } - std::map> animInfo; - ancs.getAnimationResInfo(&pakRouter, animInfo); - for (auto& [animIdx, animResInfo] : animInfo) { - PAK::Entry* animEnt = (PAK::Entry*)m_pak.lookupEntry(animResInfo.animId); - animEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}"), id, animResInfo.name); - charAssoc.m_cskrToCharacter[animResInfo.animId] = - std::make_pair(entry.id, fmt::format(FMT_STRING("{}_{}.ANIM"), animResInfo.name, animResInfo.animId)); - if (animResInfo.evntId.isValid()) { - PAK::Entry* evntEnt = (PAK::Entry*)m_pak.lookupEntry(animResInfo.evntId); - evntEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}_evnt"), id, animResInfo.name); - charAssoc.m_cskrToCharacter[animResInfo.evntId] = std::make_pair( - entry.id, fmt::format(FMT_STRING("{}_{}.evnt.yaml"), animResInfo.name, animResInfo.evntId)); - } - } - } else if (entry.type == FOURCC('MREA')) { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - MREA::AddCMDLRigPairs(rs, pakRouter, charAssoc); - } - } -} - -void PAKBridge::addPATHToMREA(PAKRouter& pakRouter, - std::unordered_map& pathToMrea) const { - for (const auto& [id, entry] : m_pak.m_entries) { - if (entry.type == FOURCC('MREA')) { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - UniqueID32 pathID = MREA::GetPATHId(rs); - if (pathID.isValid()) - pathToMrea[pathID] = id; - } - } -} - -static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}}; - -void PAKBridge::addMAPATransforms(PAKRouter& pakRouter, - std::unordered_map& addTo, - std::unordered_map& pathOverrides) const { - for (const auto& [id, entry] : m_pak.m_entries) { - if (entry.type == FOURCC('MLVL')) { - MLVL mlvl; - { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - mlvl.read(rs); - } - hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry).getParentPath(); - - if (mlvl.worldNameId.isValid()) - pathOverrides[mlvl.worldNameId] = - hecl::ProjectPath(mlvlDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), mlvl.worldNameId)); - - for (const MLVL::Area& area : mlvl.areas) { - { - /* Get PATH transform */ - const nod::Node* areaNode; - const PAK::Entry* areaEntry = pakRouter.lookupEntry(area.areaMREAId, &areaNode); - PAKEntryReadStream rs = areaEntry->beginReadStream(*areaNode); - UniqueID32 pathId = MREA::GetPATHId(rs); - if (pathId.isValid()) - addTo[pathId] = zeus::CMatrix4f(area.transformMtx[0], area.transformMtx[1], area.transformMtx[2], BottomRow) - .transposed(); - } - - hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath(); - if (area.areaNameId.isValid()) - pathOverrides[area.areaNameId] = - hecl::ProjectPath(areaDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), area.areaNameId)); - } - - if (mlvl.worldMap.isValid()) { - const nod::Node* mapNode; - const PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode); - if (mapEntry) { - PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode); - u32 magic = rs.readUint32Big(); - if (magic == 0xDEADF00D) { - rs.readUint32Big(); - u32 count = rs.readUint32Big(); - for (u32 i = 0; i < count && i < mlvl.areas.size(); ++i) { - MLVL::Area& areaData = mlvl.areas[i]; - UniqueID32 mapaId; - mapaId.read(rs); - addTo[mapaId] = zeus::CMatrix4f(areaData.transformMtx[0], areaData.transformMtx[1], - areaData.transformMtx[2], BottomRow) - .transposed(); - } - } - } - } - } - } -} - -ResExtractor PAKBridge::LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry) { - switch (entry.type.toUint32()) { - case SBIG('STRG'): - return {STRG::Extract, {".yaml"}}; - case SBIG('SCAN'): - return {SCAN::Extract, {".yaml"}, 0, SCAN::Name}; - case SBIG('HINT'): - return {HINT::Extract, {".yaml"}}; - case SBIG('TXTR'): - return {TXTR::Extract, {".png"}}; - case SBIG('AFSM'): - return {AFSM::Extract, {".yaml"}}; - case SBIG('FRME'): - return {FRME::Extract, {".blend"}, 2}; - case SBIG('CINF'): - return {CINF::Extract, {".blend"}, 1}; - case SBIG('CMDL'): - return {CMDL::Extract, {".blend"}, 1, CMDL::Name}; - case SBIG('DCLN'): - return {DCLN::Extract, {".blend"}}; - case SBIG('ANCS'): - return {ANCS::Extract, {".yaml", ".blend"}, 2}; - case SBIG('MLVL'): - return {MLVL::Extract, {".yaml", ".blend"}, 3}; - case SBIG('SAVW'): - return {MLVL::ExtractSAVW, {".yaml"}, 3}; - case SBIG('MREA'): - return {MREA::Extract, {".blend"}, 4, MREA::Name}; - case SBIG('MAPA'): - return {MAPA::Extract, {".blend"}, 4}; - case SBIG('MAPW'): - return {MLVL::ExtractMAPW, {".yaml"}, 4}; - case SBIG('MAPU'): - return {MAPU::Extract, {".blend"}, 5}; - case SBIG('PATH'): - return {PATH::Extract, {".blend"}, 5}; - case SBIG('PART'): - return {DNAParticle::ExtractGPSM, {".gpsm.yaml"}}; - case SBIG('ELSC'): - return {DNAParticle::ExtractELSM, {".elsm.yaml"}}; - case SBIG('SWHC'): - return {DNAParticle::ExtractSWSH, {".swsh.yaml"}}; - case SBIG('CRSC'): - return {DNAParticle::ExtractCRSM, {".crsm.yaml"}}; - case SBIG('WPSC'): - return {DNAParticle::ExtractWPSM, {".wpsm.yaml"}}; - case SBIG('DPSC'): - return {DNAParticle::ExtractDPSM, {".dpsm.yaml"}}; - case SBIG('FONT'): - return {DNAFont::ExtractFONT, {".yaml"}}; - case SBIG('DGRP'): - return {DNADGRP::ExtractDGRP, {".yaml"}}; - case SBIG('AGSC'): - return {AGSC::Extract, {}}; - case SBIG('CSNG'): - return {CSNG::Extract, {".mid", ".yaml"}}; - case SBIG('ATBL'): - return {DNAAudio::ATBL::Extract, {".yaml"}}; - case SBIG('CTWK'): - case SBIG('DUMB'): { - std::string catalogueName; - std::string name = pak.bestEntryName(pakNode, entry, catalogueName); - if (!catalogueName.empty()) { - if (catalogueName == "PlayerRes"sv) { - if (isCurrentSpecWii() || getCurrentRegion() == ERegion::PAL || getCurrentRegion() == ERegion::NTSC_J) { - /* We need to use the new rep for these tweaks */ - return {ExtractTweak>, {".yaml"}}; - } - /* We need to use the old rep for these tweaks */ - return {ExtractTweak>, {".yaml"}}; - } - if (catalogueName == "GunRes"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "Player"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "CameraBob"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "SlideShow"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "Game"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "Targeting"sv) { - if (isCurrentSpecWii() || getCurrentRegion() == ERegion::PAL || getCurrentRegion() == ERegion::NTSC_J) { - /* We need to use the new rep for these tweaks */ - return {ExtractTweak>, {".yaml"}}; - } - /* We need to use the old rep for these tweaks */ - return {ExtractTweak>, {".yaml"}}; - } - if (catalogueName == "Gui"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "AutoMapper"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "PlayerControls"sv || catalogueName == "PlayerControls2"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "Ball"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "Particle"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "GuiColors"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "PlayerGun"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "DUMB_MazeSeeds"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "DUMB_SnowForces"sv) - return {ExtractTweak, {".yaml"}}; - } - break; - } - } - return {}; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/DNAMP1.hpp b/DataSpec/DNAMP1/DNAMP1.hpp deleted file mode 100644 index ebc9db828..000000000 --- a/DataSpec/DNAMP1/DNAMP1.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "PAK.hpp" -#include "zeus/CMatrix4f.hpp" - -namespace DataSpec::DNAMP1 { - -extern logvisor::Module Log; - -/* MP1-specific, one-shot PAK traversal/extraction class */ -class PAKBridge { - const nod::Node& m_node; - PAK m_pak; - -public: - bool m_doExtract; - using Level = DataSpec::Level; - std::unordered_map m_levelDeps; - UniqueID32 m_levelId; - std::string m_levelString; - - PAKBridge(const nod::Node& node, bool doExtract = true); - void build(); - static ResExtractor LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry); - std::string_view getName() const { return m_node.getName(); } - UniqueID32 getLevelId() const { return m_levelId; } - std::string_view getLevelString() const { return m_levelString; } - using PAKType = PAK; - const PAKType& getPAK() const { return m_pak; } - const nod::Node& getNode() const { return m_node; } - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const; - - void addPATHToMREA(PAKRouter& pakRouter, std::unordered_map& pathToMrea) const; - - void addMAPATransforms(PAKRouter& pakRouter, std::unordered_map& addTo, - std::unordered_map& pathOverrides) const; -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/DeafBabe.cpp b/DataSpec/DNAMP1/DeafBabe.cpp deleted file mode 100644 index b074ba4b9..000000000 --- a/DataSpec/DNAMP1/DeafBabe.cpp +++ /dev/null @@ -1,233 +0,0 @@ -#include "DeafBabe.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os) { - os << "TYPE_COLORS = {'NoSFX':(0.0, 0.0, 0.0),\n" - " 'Stone':(1.0, 0.43, 0.15),\n" - " 'Metal':(0.5, 0.5, 0.5),\n" - " 'Grass':(0.0, 0.42, 0.01)," - " 'Ice':(0.0, 0.1, 0.1),\n" - " 'Metal Grating':(0.09, 0.09, 0.09),\n" - " 'Phazon':(0.24, 0.0, 0.21),\n" - " 'Dirt':(0.1, 0.07, 0.05),\n" - " 'Stone':(0.12, 0.12, 0.12),\n" - " 'Lava':(0.8, 0.15, 0.0),\n" - " 'Stone/Rock':(0.06, 0.05, 0.03),\n" - " 'Snow':(0.9, 1.0, 1.0),\n" - " 'Mud (Slow)':(0.12, 0.06, 0.02),\n" - " 'Mud':(0.12, 0.06, 0.02),\n" - " 'Glass':(0.27, 0.38, 0.9),\n" - " 'Shield':(1.0, 0.6, 0.0),\n" - " 'Sand':(0.53, 0.44, 0.21),\n" - " 'Wood':(0.30, 0.15, 0.03),\n" - " 'Organic':(0.19, 0.45, 0.2)}\n" - "\n" - "# Diffuse Color Maker\n" - "from mathutils import Color\n" - "def make_color(index, mat_type, name):\n" - " new_mat = bpy.data.materials.new(name)\n" - " if mat_type in TYPE_COLORS:\n" - " new_mat.diffuse_color = TYPE_COLORS[mat_type] + (1.0,)\n" - " else:\n" - " col = Color()\n" - " col.hsv = ((index / 6.0) % 1.0, 1.0-((index // 6) / 6.0), 1)\n" - " new_mat.diffuse_color = tuple(col) + (1.0,)\n" - " return new_mat\n" - "\n" - "bpy.types.Material.retro_unknown = bpy.props.BoolProperty(name='Retro: Unknown (U)')\n" - "bpy.types.Material.retro_surface_stone = bpy.props.BoolProperty(name='Retro Surface: Stone')\n" - "bpy.types.Material.retro_surface_metal = bpy.props.BoolProperty(name='Retro Surface: Metal')\n" - "bpy.types.Material.retro_surface_grass = bpy.props.BoolProperty(name='Retro Surface: Grass')\n" - "bpy.types.Material.retro_surface_ice = bpy.props.BoolProperty(name='Retro Surface: Ice')\n" - "bpy.types.Material.retro_pillar = bpy.props.BoolProperty(name='Retro Pillar (I)')\n" - "bpy.types.Material.retro_surface_metal_grating = bpy.props.BoolProperty(name='Retro Surface: Metal Grating')\n" - "bpy.types.Material.retro_surface_phazon = bpy.props.BoolProperty(name='Retro Surface: Phazon')\n" - "bpy.types.Material.retro_surface_dirt = bpy.props.BoolProperty(name='Retro Surface: Rock')\n" - "bpy.types.Material.retro_surface_lava = bpy.props.BoolProperty(name='Retro Surface: Lava')\n" - "bpy.types.Material.retro_surface_lava_stone = bpy.props.BoolProperty(name='Retro Surface: Lava Stone')\n" - "bpy.types.Material.retro_surface_snow = bpy.props.BoolProperty(name='Retro Surface: Snow')\n" - "bpy.types.Material.retro_surface_mud_slow = bpy.props.BoolProperty(name='Retro Surface: Mud (Slow)')\n" - "bpy.types.Material.retro_half_pipe = bpy.props.BoolProperty(name='Retro: Half Pipe (H)')\n" - "bpy.types.Material.retro_surface_mud = bpy.props.BoolProperty(name='Retro Surface: Mud')\n" - "bpy.types.Material.retro_surface_glass = bpy.props.BoolProperty(name='Retro Surface: Glass')\n" - "bpy.types.Material.retro_surface_shield = bpy.props.BoolProperty(name='Retro Surface: Shield')\n" - "bpy.types.Material.retro_surface_sand = bpy.props.BoolProperty(name='Retro Surface: Sand')\n" - "bpy.types.Material.retro_projectile_passthrough = bpy.props.BoolProperty(name='Retro: Projectile Passthrough " - "(P)')\n" - "bpy.types.Material.retro_solid = bpy.props.BoolProperty(name='Retro: Solid (K)')\n" - "bpy.types.Material.retro_no_platform_collision = bpy.props.BoolProperty(name='Retro: No Platform Collision')\n" - "bpy.types.Material.retro_camera_passthrough = bpy.props.BoolProperty(name='Retro: Camera Passthrough (O)')\n" - "bpy.types.Material.retro_surface_wood = bpy.props.BoolProperty(name='Retro Surface: Wood')\n" - "bpy.types.Material.retro_surface_organic = bpy.props.BoolProperty(name='Retro Surface: Organic')\n" - "bpy.types.Material.retro_no_edge_collision = bpy.props.BoolProperty(name='Retro: No Edge Collision')\n" - "bpy.types.Material.retro_see_through = bpy.props.BoolProperty(name='Retro: See Through')\n" - "bpy.types.Material.retro_scan_passthrough = bpy.props.BoolProperty(name='Retro: Scan Passthrough (S)')\n" - "bpy.types.Material.retro_ai_passthrough = bpy.props.BoolProperty(name='Retro: AI Passthrough (A)')\n" - "bpy.types.Material.retro_ceiling = bpy.props.BoolProperty(name='Retro: Ceiling (C)')\n" - "bpy.types.Material.retro_wall = bpy.props.BoolProperty(name='Retro: Wall (W)')\n" - "bpy.types.Material.retro_floor = bpy.props.BoolProperty(name='Retro: Floor (F)')\n" - "\n" - "material_dict = {}\n" - "material_index = []\n" - "def get_type_id(data):\n" - "\n" - " ret = 0\n" - " for i in range(1, 24):\n" - " if i == 5 or i == 13 or i in range(18, 22):\n" - " continue\n" - " if ((data >> i) & 1):\n" - " ret = i\n" - " return ret\n" - "\n" - "def select_material(data):\n" - "\n" - " type_id = get_type_id(data)\n" - " mat_type = str(type_id)\n" - " if type_id == 0:\n" - " mat_type = 'NoSFX'\n" - " if type_id == 1:\n" - " mat_type = 'Stone'\n" - " elif type_id == 2:\n" - " mat_type = 'Metal'\n" - " elif type_id == 3:\n" - " mat_type = 'Grass'\n" - " elif type_id == 4:\n" - " mat_type = 'Ice'\n" - " elif type_id == 6:\n" - " mat_type = 'Metal Grating'\n" - " elif type_id == 7:\n" - " mat_type = 'Phazon'\n" - " elif type_id == 8:\n" - " mat_type = 'Dirt'\n" - " elif type_id == 9:\n" - " mat_type = 'Lava'\n" - " elif type_id == 10:\n" - " mat_type = 'Stone/Rock'\n" - " elif type_id == 11:\n" - " mat_type = 'Snow'\n" - " elif type_id == 12:\n" - " mat_type = 'Mud (Slow)'\n" - " elif type_id == 14:\n" - " mat_type = 'Mud'\n" - " elif type_id == 15:\n" - " mat_type = 'Glass'\n" - " elif type_id == 16:\n" - " mat_type = 'Shield'\n" - " elif type_id == 17:\n" - " mat_type = 'Sand'\n" - " elif type_id == 22:\n" - " mat_type = 'Wood'\n" - " elif type_id == 23:\n" - " mat_type = 'Organic'\n" - "\n" - " mat_flags = ''\n" - " if ((data >> 0) & 1):\n" - " mat_flags += 'U'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 5) & 1):\n" - " mat_flags += 'I'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 13) & 1):\n" - " mat_flags += 'H'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 18) & 1):\n" - " mat_flags += 'P'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 19) & 1):\n" - " mat_flags += 'K'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 20) & 1):\n" - " mat_flags += 'u'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 21) & 1):\n" - " mat_flags += 'O'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 24) & 1):\n" - " mat_flags += 'u'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 26) & 1):\n" - " mat_flags += 'T'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 27) & 1):\n" - " mat_flags += 'S'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 28) & 1):\n" - " mat_flags += 'A'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 29) & 1):\n" - " mat_flags += 'C'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 30) & 1):\n" - " mat_flags += 'W'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 31) & 1):\n" - " mat_flags += 'F'\n" - " else:\n" - " mat_flags += 'x'\n" - "\n" - " if len(mat_flags) > 0:\n" - " mat_flags = ' ' + mat_flags\n" - "\n" - " mat_name = mat_type + mat_flags\n" - "\n" - " if mat_name in material_index:\n" - " return material_index.index(mat_name)\n" - " elif mat_name in material_dict:\n" - " material_index.append(mat_name)\n" - " return len(material_index)-1\n" - " else:\n" - " mat = make_color(len(material_dict), mat_type, mat_name)\n" - " mat.retro_unknown = ((data >> 0) & 1)\n" - " mat.retro_surface_stone = ((data >> 1) & 1)\n" - " mat.retro_surface_metal = ((data >> 2) & 1)\n" - " mat.retro_surface_grass = ((data >> 3) & 1) \n" - " mat.retro_surface_ice = ((data >> 4) & 1)\n" - " mat.retro_pillar = ((data >> 5) & 1)\n" - " mat.retro_surface_metal_grating = ((data >> 6) & 1)\n" - " mat.retro_surface_phazon = ((data >> 7) & 1)\n" - " mat.retro_surface_dirt = ((data >> 8) & 1)\n" - " mat.retro_surface_lava = ((data >> 9) & 1)\n" - " mat.retro_surface_lava_stone = ((data >> 10) & 1)\n" - " mat.retro_surface_snow = ((data >> 11) & 1)\n" - " mat.retro_surface_mud_slow = ((data >> 12) & 1)\n" - " mat.retro_half_pipe = ((data >> 13) & 1)\n" - " mat.retro_surface_mud = ((data >> 14) & 1)\n" - " mat.retro_surface_glass = ((data >> 15) & 1)\n" - " mat.retro_surface_shield = ((data >> 16) & 1)\n" - " mat.retro_surface_sand = ((data >> 17) & 1)\n" - " mat.retro_projectile_passthrough = ((data >> 18) & 1)\n" - " mat.retro_solid = ((data >> 19) & 1)\n" - " mat.retro_no_platform_collision = ((data >> 20) & 1)\n" - " mat.retro_camera_passthrough = ((data >> 21) & 1)\n" - " mat.retro_surface_wood = ((data >> 22) & 1)\n" - " mat.retro_surface_organic = ((data >> 23) & 1)\n" - " mat.retro_no_edge_collision = ((data >> 24) & 1)\n" - " mat.retro_see_through = ((data >> 26) & 1)\n" - " mat.retro_scan_passthrough = ((data >> 27) & 1)\n" - " mat.retro_ai_passthrough = ((data >> 28) & 1)\n" - " mat.retro_ceiling = ((data >> 29) & 1)\n" - " mat.retro_wall= ((data >> 30) & 1)\n" - " mat.retro_floor = ((data >> 31) & 1)\n" - " material_dict[mat_name] = mat\n" - " material_index.append(mat_name)\n" - " return len(material_index)-1\n" - "\n" - "\n"; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/DeafBabe.hpp b/DataSpec/DNAMP1/DeafBabe.hpp deleted file mode 100644 index f573d4625..000000000 --- a/DataSpec/DNAMP1/DeafBabe.hpp +++ /dev/null @@ -1,241 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DeafBabe.hpp" -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace DataSpec::DNAMP1 { - -struct DeafBabe : BigDNA { - AT_DECL_DNA - using BspNodeType = DataSpec::BspNodeType; - - struct Material : BigDNA { - AT_DECL_DNA - Value material = 0; - bool unknown() const { return material & 1; } - void setUnknown(bool v) { - material &= ~1; - material |= int(v); - } - bool surfaceStone() const { return (material >> 1) & 1; } - void setSurfaceStone(bool v) { - material &= ~(1ull << 1); - material |= (v << 1); - } - bool surfaceMetal() const { return (material >> 2) & 1; } - void setSurfaceMetal(bool v) { - material &= ~(1ull << 2); - material |= (v << 2); - } - bool surfaceGrass() const { return (material >> 3) & 1; } - void setSurfaceGrass(bool v) { - material &= ~(1ull << 3); - material |= (v << 3); - } - bool surfaceIce() const { return (material >> 4) & 1; } - void setSurfaceIce(bool v) { - material &= ~(1ull << 4); - material |= (v << 4); - } - bool pillar() const { return (material >> 5) & 1; } - void setPillar(bool v) { - material &= ~(1ull << 5); - material |= (v << 5); - } - bool surfaceMetalGrating() const { return (material >> 6) & 1; } - void setSurfaceMetalGrating(bool v) { - material &= ~(1ull << 6); - material |= (v << 6); - } - bool surfacePhazon() const { return (material >> 7) & 1; } - void setSurfacePhazon(bool v) { - material &= ~(1ull << 7); - material |= (v << 7); - } - bool surfaceDirt() const { return (material >> 8) & 1; } - void setSurfaceDirt(bool v) { - material &= ~(1ull << 8); - material |= (v << 8); - } - bool surfaceLava() const { return (material >> 9) & 1; } - void setSurfaceLava(bool v) { - material &= ~(1ull << 9); - material |= (v << 9); - } - bool surfaceStoneRock() const { return (material >> 10) & 1; } - void setSurfaceLavaStone(bool v) { - material &= ~(1ull << 10); - material |= (v << 10); - } - bool surfaceSnow() const { return (material >> 11) & 1; } - void setSurfaceSnow(bool v) { - material &= ~(1ull << 11); - material |= (v << 11); - } - bool surfaceMudSlow() const { return (material >> 12) & 1; } - void setSurfaceMudSlow(bool v) { - material &= ~(1ull << 12); - material |= (v << 12); - } - bool halfPipe() const { return (material >> 13) & 1; } - void setHalfPipe(bool v) { - material &= ~(1ull << 13); - material |= (v << 13); - } - bool surfaceMud() const { return (material >> 14) & 1; } - void setSurfaceMud(bool v) { - material &= ~(1ull << 14); - material |= (v << 14); - } - bool surfaceGlass() const { return (material >> 15) & 1; } - void setSurfaceGlass(bool v) { - material &= ~(1ull << 15); - material |= (v << 15); - } - bool surfaceShield() const { return (material >> 16) & 1; } - void setSurfaceShield(bool v) { - material &= ~(1ull << 16); - material |= (v << 16); - } - bool surfaceSand() const { return (material >> 17) & 1; } - void setSurfaceSand(bool v) { - material &= ~(1ull << 17); - material |= (v << 17); - } - bool projectilePassthrough() const { return (material >> 18) & 1; } - void setProjectilePassthrough(bool v) { - material &= ~(1ull << 18); - material |= (v << 18); - } - bool solid() const { return (material >> 19) & 1; } - void setSolid(bool v) { - material &= ~(1ull << 19); - material |= (v << 19); - } - bool noPlatformCollision() const { return (material >> 20) & 1; } - void setNoPlatformCollision(bool v) { - material &= ~(1ull << 20); - material |= (v << 20); - } - bool cameraPassthrough() const { return (material >> 21) & 1; } - void setCameraPassthrough(bool v) { - material &= ~(1ull << 21); - material |= (v << 21); - } - bool surfaceWood() const { return (material >> 22) & 1; } - void setSurfaceWood(bool v) { - material &= ~(1ull << 22); - material |= (v << 22); - } - bool surfaceOrganic() const { return (material >> 23) & 1; } - void setSurfaceOrganic(bool v) { - material &= ~(1ull << 23); - material |= (v << 23); - } - bool noEdgeCollision() const { return (material >> 24) & 1; } - void setNoEdgeCollision(bool v) { - material &= ~(1ull << 24); - material |= (v << 24); - } - bool flipFace() const { return (material >> 25) & 1; } - void setFlipFace(bool v) { - material &= ~(1ull << 25); - material |= (v << 25); - } - bool seeThrough() const { return (material >> 26) & 1; } - void setSeeThrough(bool v) { - material &= ~(1ull << 26); - material |= (v << 26); - } - bool scanPassthrough() const { return (material >> 27) & 1; } - void setScanPassthrough(bool v) { - material &= ~(1ull << 27); - material |= (v << 27); - } - bool aiPassthrough() const { return (material >> 28) & 1; } - void setAiPassthrough(bool v) { - material &= ~(1ull << 28); - material |= (v << 28); - } - bool ceiling() const { return (material >> 29) & 1; } - void setCeiling(bool v) { - material &= ~(1ull << 29); - material |= (v << 29); - } - bool wall() const { return (material >> 30) & 1; } - void setWall(bool v) { - material &= ~(1ull << 30); - material |= (v << 30); - } - bool floor() const { return (material >> 31) & 1; } - void setFloor(bool v) { - material &= ~(1ull << 31); - material |= (v << 31); - } - - /* Dummies for later games */ - bool surfaceSPMetal() const { return false; } - void setSurfaceSPMetal(bool v) {} - bool surfaceFabric() const { return false; } - void setSurfaceFabric(bool v) {} - bool surfaceRubber() const { return false; } - void setSurfaceRubber(bool v) {} - bool surfaceMothOrSeedOrganics() const { return false; } - void setSurfaceMothOrSeedOrganics(bool v) {} - bool surfaceWeb() const { return false; } - void setSurfaceWeb(bool v) {} - bool unused3() const { return false; } - void setUnused3(bool v) {} - bool unused4() const { return false; } - void setUnused4(bool v) {} - bool aiBlock() const { return false; } - void setAiBlock(bool v) {} - bool jumpNotAllowed() const { return false; } - void setJumpNotAllowed(bool v) {} - bool spiderBall() const { return false; } - void setSpiderBall(bool v) {} - bool screwAttackWallJump() const { return false; } - void setScrewAttackWallJump(bool v) {} - }; - - struct Edge : BigDNA { - AT_DECL_DNA - Value verts[2]; - }; - - struct Triangle : BigDNA { - AT_DECL_DNA - Value edges[3]; - }; - - Value unk1; - Value length; - Value magic; - Value version; - Value aabb[2]; - Value rootNodeType; - Value bspSize; - Buffer bspTree; - Value materialCount; - Vector materials; - Value vertMatsCount; - Vector vertMats; - Value edgeMatsCount; - Vector edgeMats; - Value triMatsCount; - Vector triMats; - Value edgeVertsCount; - Vector edgeVertConnections; - Value triangleEdgesCount; - Vector triangleEdgeConnections; - Value vertCount; - Vector verts; - - /* Dummy MP2 member */ - void insertNoClimb(hecl::blender::PyOutStream&) const {} - - static void BlenderInit(hecl::blender::PyOutStream& os); - void sendToBlender(hecl::blender::PyOutStream& os) const { DeafBabeSendToBlender(os, *this); } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/EVNT.cpp b/DataSpec/DNAMP1/EVNT.cpp deleted file mode 100644 index 95d5c401c..000000000 --- a/DataSpec/DNAMP1/EVNT.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "EVNT.hpp" - -namespace DataSpec::DNAMP1 { - -template -void EVNT::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"version"}, version, s); - - DoSize(athena::io::PropId{"boolPOICount"}, boolPOICount, s); - Do(athena::io::PropId{"boolPOINodes"}, boolPOINodes, boolPOICount, s); - - DoSize(athena::io::PropId{"int32POICount"}, int32POICount, s); - Do(athena::io::PropId{"int32POINodes"}, int32POINodes, int32POICount, s); - - DoSize(athena::io::PropId{"particlePOICount"}, particlePOICount, s); - Do(athena::io::PropId{"particlePOINodes"}, particlePOINodes, particlePOICount, s); - - if (version == 2) { - DoSize(athena::io::PropId{"soundPOICount"}, soundPOICount, s); - Do(athena::io::PropId{"soundPOINodes"}, soundPOINodes, soundPOICount, s); - } -} - -AT_SPECIALIZE_DNA_YAML(EVNT) - -std::string_view EVNT::DNAType() { return "DNAMP1::EVNT"sv; } - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/EVNT.hpp b/DataSpec/DNAMP1/EVNT.hpp deleted file mode 100644 index 8d39a78ed..000000000 --- a/DataSpec/DNAMP1/EVNT.hpp +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -struct EVNT : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - Value version; - - struct POINode : BigDNA { - AT_DECL_DNA_YAML - Value unk0; - String<-1> name; - Value type; - struct CharAnimTime : BigDNA { - enum class Type : atUint32 { NonZero, ZeroIncreasing, ZeroSteady, ZeroDecreasing, Infinity }; - - AT_DECL_DNA_YAML - Value time; - Value type; - }; - - CharAnimTime animTime; - Value idx; - Value unk2; - Value weight; - Value charIdx; - Value flags; - }; - - struct BoolPOINode : POINode { - AT_DECL_DNA_YAML - Value value; - }; - Value boolPOICount; - Vector boolPOINodes; - - struct Int32POINode : POINode { - AT_DECL_DNA_YAML - Value value; - String<-1> locator; - }; - Value int32POICount; - Vector int32POINodes; - - struct ParticlePOINode : POINode { - AT_DECL_DNA_YAML - Value duration; - DNAFourCC ptype; - UniqueID32 id; - String<-1> locator; - Value scale; - Value parentMode; - }; - Value particlePOICount; - Vector particlePOINodes; - - struct SoundPOINode : POINode { - AT_DECL_DNA_YAML - Value soundId; - Value falloff; - Value maxDist; - }; - Value soundPOICount; - Vector soundPOINodes; - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - EVNT evnt; - evnt.read(rs); - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(evnt, writer); - return true; - } - - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - EVNT evnt; - athena::io::FileReader reader(inPath.getAbsolutePath()); - athena::io::FromYAMLStream(evnt, reader); - athena::io::FileWriter ws(outPath.getAbsolutePath()); - evnt.write(ws); - return true; - } - - void gatherDependencies(std::vector& pathsOut) const { - for (const ParticlePOINode& node : particlePOINodes) - g_curSpec->flattenDependencies(node.id, pathsOut); - } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/FRME.cpp b/DataSpec/DNAMP1/FRME.cpp deleted file mode 100644 index 27e89411a..000000000 --- a/DataSpec/DNAMP1/FRME.cpp +++ /dev/null @@ -1,613 +0,0 @@ -#include "FRME.hpp" -#include "DataSpec/DNACommon/TXTR.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -template <> -void FRME::Enumerate(athena::io::IStreamReader& __dna_reader) { - /* version */ - version = __dna_reader.readUint32Big(); - /* unk1 */ - unk1 = __dna_reader.readUint32Big(); - /* modelCount */ - modelCount = __dna_reader.readUint32Big(); - /* unk3 */ - unk3 = __dna_reader.readUint32Big(); - /* widgetCount */ - widgetCount = __dna_reader.readUint32Big(); - /* widgets */ - __dna_reader.enumerate(widgets, widgetCount, [this](athena::io::IStreamReader& reader, Widget& w) { - w.owner = this; - w.read(reader); - }); -} - -template <> -void FRME::Enumerate(athena::io::IStreamWriter& __dna_writer) { - /* version */ - __dna_writer.writeUint32Big(version); - /* unk1 */ - __dna_writer.writeUint32Big(unk1); - /* modelCount */ - __dna_writer.writeUint32Big(modelCount); - /* unk3 */ - __dna_writer.writeUint32Big(unk3); - /* widgetCount */ - __dna_writer.writeUint32Big(widgetCount); - /* widgets */ - __dna_writer.enumerate(widgets); -} - -template <> -void FRME::Enumerate(size_t& __isz) { - for (const Widget& w : widgets) - w.binarySize(__isz); - __isz += 20; -} - -template <> -void FRME::Widget::Enumerate(athena::io::IStreamReader& __dna_reader) { - /* type */ - type.read(__dna_reader); - /* header */ - header.read(__dna_reader); - switch (type.toUint32()) { - case SBIG('BWIG'): - widgetInfo = std::make_unique(); - break; - case SBIG('HWIG'): - widgetInfo = std::make_unique(); - break; - case SBIG('CAMR'): - widgetInfo = std::make_unique(); - break; - case SBIG('LITE'): - widgetInfo = std::make_unique(); - break; - case SBIG('ENRG'): - widgetInfo = std::make_unique(); - break; - case SBIG('MODL'): - widgetInfo = std::make_unique(); - break; - case SBIG('METR'): - widgetInfo = std::make_unique(); - break; - case SBIG('GRUP'): - widgetInfo = std::make_unique(); - break; - case SBIG('PANE'): - widgetInfo = std::make_unique(); - break; - case SBIG('TXPN'): - widgetInfo = std::make_unique(owner->version); - break; - case SBIG('IMGP'): - widgetInfo = std::make_unique(); - break; - case SBIG('TBGP'): - widgetInfo = std::make_unique(); - break; - case SBIG('SLGP'): - widgetInfo = std::make_unique(); - break; - default: - Log.report(logvisor::Fatal, FMT_STRING("Unsupported FRME widget type {}"), type); - } - - /* widgetInfo */ - widgetInfo->read(__dna_reader); - - /* isWorker */ - isWorker = __dna_reader.readBool(); - if (isWorker) { - /* workerId */ - workerId = __dna_reader.readUint16Big(); - } - /* origin */ - origin = __dna_reader.readVec3fBig(); - /* basis[0] */ - basis[0] = __dna_reader.readVec3fBig(); - /* basis[1] */ - basis[1] = __dna_reader.readVec3fBig(); - /* basis[2] */ - basis[2] = __dna_reader.readVec3fBig(); - /* rotationCenter */ - rotationCenter = __dna_reader.readVec3fBig(); - /* unk1 */ - unk1 = __dna_reader.readInt32Big(); - /* unk2 */ - unk2 = __dna_reader.readInt16Big(); -} - -template <> -void FRME::Widget::Enumerate(athena::io::IStreamWriter& __dna_writer) { - /* type */ - DNAFourCC _type = widgetInfo ? widgetInfo->fourcc() : FOURCC('BWIG'); - _type.write(__dna_writer); - /* header */ - header.write(__dna_writer); - - /* widgetInfo */ - if (widgetInfo) - widgetInfo->write(__dna_writer); - - /* isWorker */ - __dna_writer.writeBool(isWorker); - if (isWorker) { - /* workerId */ - __dna_writer.writeUint16Big(workerId); - } - /* origin */ - __dna_writer.writeVec3fBig(origin); - /* basis[0] */ - __dna_writer.writeVec3fBig(basis[0]); - /* basis[1] */ - __dna_writer.writeVec3fBig(basis[1]); - /* basis[2] */ - __dna_writer.writeVec3fBig(basis[2]); - /* rotationCenter */ - __dna_writer.writeVec3fBig(rotationCenter); - /* unk1 */ - __dna_writer.writeInt32Big(unk1); - /* unk2 */ - __dna_writer.writeInt16Big(unk2); -} - -template <> -void FRME::Widget::Enumerate(size_t& __isz) { - type.binarySize(__isz); - header.binarySize(__isz); - if (widgetInfo) - widgetInfo->binarySize(__isz); - if (isWorker) - __isz += 4; - __isz += 67; -} - -template <> -void FRME::Widget::CAMRInfo::Enumerate(athena::io::IStreamReader& __dna_reader) { - projectionType = ProjectionType(__dna_reader.readUint32Big()); - if (projectionType == ProjectionType::Perspective) { - projection = std::make_unique(); - } else if (projectionType == ProjectionType::Orthographic) { - projection = std::make_unique(); - } else { - Log.report(logvisor::Fatal, FMT_STRING("Invalid CAMR projection mode! {}"), int(projectionType)); - } - - projection->read(__dna_reader); -} - -template <> -void FRME::Widget::CAMRInfo::Enumerate(athena::io::IStreamWriter& __dna_writer) { - if (!projection) - Log.report(logvisor::Fatal, FMT_STRING("Invalid CAMR projection object!")); - if (projection->type != projectionType) - Log.report(logvisor::Fatal, FMT_STRING("CAMR projection type does not match actual projection type!")); - - __dna_writer.writeUint32Big(atUint32(projectionType)); - projection->write(__dna_writer); -} - -template <> -void FRME::Widget::CAMRInfo::Enumerate(size_t& __isz) { - projection->binarySize(__isz); - __isz += 4; -} - -template <> -void FRME::Widget::LITEInfo::Enumerate(athena::io::IStreamReader& __dna_reader) { - /* type */ - type = ELightType(__dna_reader.readUint32Big()); - /* distC */ - distC = __dna_reader.readFloatBig(); - /* distL */ - distL = __dna_reader.readFloatBig(); - /* distQ */ - distQ = __dna_reader.readFloatBig(); - /* angC */ - angC = __dna_reader.readFloatBig(); - /* angL */ - angL = __dna_reader.readFloatBig(); - /* angQ */ - angQ = __dna_reader.readFloatBig(); - /* loadedIdx */ - loadedIdx = __dna_reader.readUint32Big(); - - /* cutoff */ - if (type == ELightType::Spot) - cutoff = __dna_reader.readFloatBig(); -} - -template <> -void FRME::Widget::LITEInfo::Enumerate(athena::io::IStreamWriter& __dna_writer) { - /* type */ - __dna_writer.writeUint32Big(atUint32(type)); - /* distC */ - __dna_writer.writeFloatBig(distC); - /* distL */ - __dna_writer.writeFloatBig(distL); - /* distQ */ - __dna_writer.writeFloatBig(distQ); - /* angC */ - __dna_writer.writeFloatBig(angC); - /* angL */ - __dna_writer.writeFloatBig(angL); - /* angQ */ - __dna_writer.writeFloatBig(angQ); - /* loadedIdx */ - __dna_writer.writeUint32Big(loadedIdx); - - /* cutoff */ - if (type == ELightType::Spot) - __dna_writer.writeFloatBig(cutoff); -} - -template <> -void FRME::Widget::LITEInfo::Enumerate(size_t& __isz) { - __isz += ((type == ELightType::Spot) ? 36 : 32); -} - -template -void FRME::Widget::TXPNInfo::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"xDim"}, xDim, s); - Do(athena::io::PropId{"zDim"}, zDim, s); - Do(athena::io::PropId{"scaleCenter"}, scaleCenter, s); - Do(athena::io::PropId{"font"}, font, s); - Do(athena::io::PropId{"wordWrap"}, wordWrap, s); - Do(athena::io::PropId{"horizontal"}, horizontal, s); - Do(athena::io::PropId{"justification"}, justification, s); - Do(athena::io::PropId{"verticalJustification"}, verticalJustification, s); - Do(athena::io::PropId{"fillColor"}, fillColor, s); - Do(athena::io::PropId{"outlineColor"}, outlineColor, s); - Do(athena::io::PropId{"blockExtent"}, blockExtent, s); - if (version == 1) { - Do(athena::io::PropId{"jpnFont"}, jpnFont, s); - Do(athena::io::PropId{"jpnPointScale[0]"}, jpnPointScale[0], s); - Do(athena::io::PropId{"jpnPointScale[1]"}, jpnPointScale[1], s); - } -} - -AT_SPECIALIZE_DNA(FRME::Widget::TXPNInfo) - -bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - if (!force && outPath.isFile()) - return true; - - FRME frme; - frme.read(rs); - - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Frame)) - return false; - - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - - os << "import bpy, math, bmesh\n" - "from mathutils import Matrix, Quaternion\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "def duplicateObject(copy_obj):\n" - " # Create new mesh\n" - " mesh = bpy.data.meshes.new(copy_obj.name)\n" - " # Create new object associated with the mesh\n" - " ob_new = bpy.data.objects.new(copy_obj.name, mesh)\n" - " # Copy data block from the old object into the new object\n" - " ob_new.data = copy_obj.data\n" - " ob_new.scale = copy_obj.scale\n" - " ob_new.location = copy_obj.location\n" - " # Link new object to the given scene and select it\n" - " bpy.context.scene.collection.objects.link(ob_new)\n" - " return ob_new\n"; - - os.format(FMT_STRING("bpy.context.scene.name = '{}'\n" - "bpy.context.scene.render.resolution_x = 640\n" - "bpy.context.scene.render.resolution_y = 480\n" - "bpy.context.scene.world.use_nodes = True\n" - "bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n" - "bg_node.inputs[1].default_value = 0.0\n"), - pakRouter.getBestEntryName(entry)); - - int pIdx = 0; - for (const FRME::Widget& w : frme.widgets) { - os << "binding = None\n" - "angle = Quaternion((1.0, 0.0, 0.0), 0)\n"; - if (w.type == SBIG('CAMR')) { - using CAMRInfo = Widget::CAMRInfo; - os.format(FMT_STRING("cam = bpy.data.cameras.new(name='{}')\n" - "binding = cam\n"), - w.header.name); - if (CAMRInfo* info = static_cast(w.widgetInfo.get())) { - if (info->projectionType == CAMRInfo::ProjectionType::Orthographic) { - CAMRInfo::OrthographicProjection* proj = - static_cast(info->projection.get()); - os.format(FMT_STRING("cam.type = 'ORTHO'\n" - "cam.ortho_scale = {}\n" - "cam.clip_start = {}\n" - "cam.clip_end = {}\n"), - std::fabs(proj->right - proj->left), proj->znear, proj->zfar); - } else if (info->projectionType == CAMRInfo::ProjectionType::Perspective) { - CAMRInfo::PerspectiveProjection* proj = static_cast(info->projection.get()); - os.format(FMT_STRING("cam.type = 'PERSP'\n" - "cam.lens_unit = 'FOV'\n" - "cam.clip_start = {}\n" - "cam.clip_end = {}\n" - "bpy.context.scene.render.resolution_x = int(480 * {})\n"), - proj->znear, proj->zfar, proj->aspect); - if (proj->aspect > 1.f) - os.format(FMT_STRING("cam.angle = math.atan2({}, 1.0 / math.tan(math.radians({} / 2.0))) * 2.0\n"), - proj->aspect, proj->fov); - else - os.format(FMT_STRING("cam.angle = math.radians({})\n"), proj->fov); - } - } - os << "angle = Quaternion((1.0, 0.0, 0.0), math.radians(90.0))\n"; - } else if (w.type == SBIG('LITE')) { - using LITEInfo = Widget::LITEInfo; - if (LITEInfo* info = static_cast(w.widgetInfo.get())) { - switch (info->type) { - case LITEInfo::ELightType::LocalAmbient: { - zeus::simd_floats colorF(w.header.color.simd); - os.format(FMT_STRING("bg_node.inputs[0].default_value = ({},{},{},1.0)\n" - "bg_node.inputs[1].default_value = {}\n"), - colorF[0], colorF[1], colorF[2], info->distQ / 8.0); - break; - } - case LITEInfo::ELightType::Spot: - case LITEInfo::ELightType::Directional: - os << "angle = Quaternion((1.0, 0.0, 0.0), math.radians(90.0))\n"; - [[fallthrough]]; - default: { - zeus::simd_floats colorF(w.header.color.simd); - os.format(FMT_STRING("lamp = bpy.data.lights.new(name='{}', type='POINT')\n" - "lamp.color = ({}, {}, {})\n" - "lamp.hecl_falloff_constant = {}\n" - "lamp.hecl_falloff_linear = {}\n" - "lamp.hecl_falloff_quadratic = {}\n" - "lamp.retro_light_angle_constant = {}\n" - "lamp.retro_light_angle_linear = {}\n" - "lamp.retro_light_angle_quadratic = {}\n" - "lamp.retro_light_index = {}\n" - "binding = lamp\n"), - w.header.name, colorF[0], colorF[1], colorF[2], info->distC, info->distL, info->distQ, info->angC, - info->angL, info->angQ, info->loadedIdx); - if (info->type == LITEInfo::ELightType::Spot) - os.format(FMT_STRING("lamp.type = 'SPOT'\n" - "lamp.spot_size = {}\n"), - info->cutoff); - else if (info->type == LITEInfo::ELightType::Directional) - os << "lamp.type = 'SUN'\n"; - } - } - } - } else if (w.type == SBIG('IMGP')) { - using IMGPInfo = Widget::IMGPInfo; - if (IMGPInfo* info = static_cast(w.widgetInfo.get())) { - std::string texName; - std::string resPath; - if (info->texture.isValid()) { - texName = pakRouter.getBestEntryName(info->texture); - const nod::Node* node; - const PAKRouter::EntryType* texEntry = pakRouter.lookupEntry(info->texture, &node); - hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry); - if (txtrPath.isNone()) { - txtrPath.makeDirChain(false); - PAKEntryReadStream rs = texEntry->beginReadStream(*node); - TXTR::Extract(rs, txtrPath); - } - resPath = pakRouter.getResourceRelativePath(entry, info->texture); - } - - if (resPath.size()) { - os.format(FMT_STRING("if '{}' in bpy.data.images:\n" - " image = bpy.data.images['{}']\n" - "else:\n" - " image = bpy.data.images.load('''//{}''')\n" - " image.name = '{}'\n"), - texName, texName, resPath, texName); - } else { - os << "image = None\n"; - } - - os.format(FMT_STRING("material = bpy.data.materials.new('{}')\n" - "material.use_nodes = True\n" - "new_nodetree = material.node_tree\n" - "for n in new_nodetree.nodes:\n" - " new_nodetree.nodes.remove(n)\n" - "tex_node = new_nodetree.nodes.new('ShaderNodeTexImage')\n" - "tex_node.image = image\n" - "bm = bmesh.new()\n" - "verts = []\n"), - w.header.name); - - for (uint32_t i = 0; i < info->quadCoordCount; ++i) { - int ti; - if (i == 2) - ti = 3; - else if (i == 3) - ti = 2; - else - ti = i; - zeus::simd_floats f(info->quadCoords[ti].simd); - os.format(FMT_STRING("verts.append(bm.verts.new(({},{},{})))\n"), f[0], f[1], f[2]); - } - os << "bm.faces.new(verts)\n" - "bm.loops.layers.uv.new('UV')\n" - "bm.verts.ensure_lookup_table()\n"; - for (uint32_t i = 0; i < info->uvCoordCount; ++i) { - int ti; - if (i == 2) - ti = 3; - else if (i == 3) - ti = 2; - else - ti = i; - zeus::simd_floats f(info->uvCoords[ti].simd); - os.format(FMT_STRING("bm.verts[{}].link_loops[0][bm.loops.layers.uv[0]].uv = ({},{})\n"), i, f[0], f[1]); - } - os.format(FMT_STRING("binding = bpy.data.meshes.new('{}')\n" - "bm.to_mesh(binding)\n" - "bm.free()\n" - "binding.materials.append(material)\n"), - w.header.name); - } - } - - zeus::simd_floats colorF(w.header.color.simd); - os.format(FMT_STRING( - "frme_obj = bpy.data.objects.new(name='{}', object_data=binding)\n" - "frme_obj.pass_index = {}\n" - "parentName = '{}'\n" - "frme_obj.retro_widget_type = 'RETRO_{}'\n" - "frme_obj.retro_widget_use_anim_controller = {}\n" - "frme_obj.retro_widget_default_visible = {}\n" - "frme_obj.retro_widget_default_active = {}\n" - "frme_obj.retro_widget_cull_faces = {}\n" - "frme_obj.retro_widget_color = ({},{},{},{})\n" - "widget_model_draw_flags = {}\n" - "if bpy.app.version >= (2, 93, 0):\n" - " frme_obj.retro_widget_model_draw_flags = bpy.types.Object.retro_widget_model_draw_flags.keywords['items'][widget_model_draw_flags][0]\n" - "else:\n" - " frme_obj.retro_widget_model_draw_flags = bpy.types.Object.retro_widget_model_draw_flags[1]['items'][widget_model_draw_flags][0]\n" - "frme_obj.retro_widget_is_worker = {}\n" - "frme_obj.retro_widget_worker_id = {}\n" - "if parentName not in bpy.data.objects:\n" - " frme_obj.retro_widget_parent = parentName\n" - "else:\n" - " frme_obj.parent = bpy.data.objects[parentName]\n"), - w.header.name, pIdx++, w.header.parent, w.type, - w.header.useAnimController ? "True" : "False", w.header.defaultVisible ? "True" : "False", - w.header.defaultActive ? "True" : "False", w.header.cullFaces ? "True" : "False", colorF[0], colorF[1], - colorF[2], colorF[3], w.header.modelDrawFlags, w.isWorker ? "True" : "False", w.workerId); - - if (w.type == SBIG('MODL')) { - using MODLInfo = FRME::Widget::MODLInfo; - MODLInfo* info = static_cast(w.widgetInfo.get()); - hecl::ProjectPath modelPath = pakRouter.getWorking(info->model); - const PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info->model, nullptr, true, true); - - os.linkMesh(modelPath.getAbsolutePath(), pakRouter.getBestEntryName(*cmdlE)); - - os.format(FMT_STRING("frme_obj.retro_model_light_mask = {}\n"), info->lightMask); - os << "print(obj.name)\n" - "copy_obj = duplicateObject(obj)\n" - "copy_obj.parent = frme_obj\n" - "copy_obj.hide_set(False)\n"; - } else if (w.type == SBIG('CAMR')) { - os << "bpy.context.scene.camera = frme_obj\n" - "if 'Camera' in bpy.data.objects:\n" - " cam = bpy.data.objects['Camera']\n" - " #bpy.context.scene.objects.unlink(cam)\n" - " bpy.data.objects.remove(cam)\n"; - } else if (w.type == SBIG('PANE')) { - using PANEInfo = Widget::PANEInfo; - if (PANEInfo* info = static_cast(w.widgetInfo.get())) { - zeus::simd_floats f(info->scaleCenter.simd); - os.format(FMT_STRING("frme_obj.retro_pane_dimensions = ({},{})\n" - "frme_obj.retro_pane_scale_center = ({},{},{})\n"), - info->xDim, info->zDim, f[0], f[1], f[2]); - } - } else if (w.type == SBIG('TXPN')) { - using TXPNInfo = Widget::TXPNInfo; - if (TXPNInfo* info = static_cast(w.widgetInfo.get())) { - hecl::ProjectPath fontPath = pakRouter.getWorking(info->font, true); - hecl::ProjectPath jpFontPath; - if (frme.version >= 1) - jpFontPath = pakRouter.getWorking(info->jpnFont, true); - - zeus::simd_floats scaleF(info->scaleCenter.simd); - zeus::simd_floats fillF(info->fillColor.simd); - zeus::simd_floats outlineF(info->outlineColor.simd); - zeus::simd_floats extentF(info->blockExtent.simd); - os.format(FMT_STRING( - "frme_obj.retro_pane_dimensions = ({},{})\n" - "frme_obj.retro_pane_scale_center = ({},{},{})\n" - "frme_obj.retro_textpane_font_path = '{}'\n" - "frme_obj.retro_textpane_word_wrap = {}\n" - "frme_obj.retro_textpane_horizontal = {}\n" - "frme_obj.retro_textpane_fill_color = ({},{},{},{})\n" - "frme_obj.retro_textpane_outline_color = ({},{},{},{})\n" - "frme_obj.retro_textpane_block_extent = ({},{})\n" - "frme_obj.retro_textpane_jp_font_path = '{}'\n" - "frme_obj.retro_textpane_jp_font_scale = ({},{})\n" - "textpane_hjustification = {}\n" - "textpane_vjustification = {}\n" - "if bpy.app.version >= (2, 93, 0):\n" - " frme_obj.retro_textpane_hjustification = bpy.types.Object.retro_textpane_hjustification.keywords['items'][textpane_hjustification][0]\n" - " frme_obj.retro_textpane_vjustification = bpy.types.Object.retro_textpane_vjustification.keywords['items'][textpane_vjustification][0]\n" - "else:\n" - " frme_obj.retro_textpane_hjustification = bpy.types.Object.retro_textpane_hjustification[1]['items'][textpane_hjustification][0]\n" - " frme_obj.retro_textpane_vjustification = bpy.types.Object.retro_textpane_vjustification[1]['items'][textpane_vjustification][0]\n"), - info->xDim, info->zDim, scaleF[0], scaleF[1], scaleF[2], fontPath.getRelativePath(), - info->wordWrap ? "True" : "False", info->horizontal ? "True" : "False", fillF[0], fillF[1], fillF[2], - fillF[3], outlineF[0], outlineF[1], outlineF[2], outlineF[3], extentF[0], extentF[1], - jpFontPath.getRelativePath(), info->jpnPointScale[0], info->jpnPointScale[1], - int(info->justification), int(info->verticalJustification)); - } - } else if (w.type == SBIG('TBGP')) { - using TBGPInfo = Widget::TBGPInfo; - if (TBGPInfo* info = static_cast(w.widgetInfo.get())) { - os.format(FMT_STRING("frme_obj.retro_tablegroup_elem_count = {}\n" - "frme_obj.retro_tablegroup_elem_default = {}\n" - "frme_obj.retro_tablegroup_wraparound = {}\n"), - info->elementCount, info->defaultSelection, info->selectWraparound ? "True" : "False"); - } - } else if (w.type == SBIG('GRUP')) { - using GRUPInfo = Widget::GRUPInfo; - if (GRUPInfo* info = static_cast(w.widgetInfo.get())) { - os.format(FMT_STRING("frme_obj.retro_group_default_worker = {}\n"), info->defaultWorker); - } - } else if (w.type == SBIG('SLGP')) { - using SLGPInfo = Widget::SLGPInfo; - if (SLGPInfo* info = static_cast(w.widgetInfo.get())) { - os.format(FMT_STRING("frme_obj.retro_slider_min = {}\n" - "frme_obj.retro_slider_max = {}\n" - "frme_obj.retro_slider_default = {}\n" - "frme_obj.retro_slider_increment = {}\n"), - info->min, info->max, info->cur, info->increment); - } - } else if (w.type == SBIG('ENRG')) { - using ENRGInfo = Widget::ENRGInfo; - if (ENRGInfo* info = static_cast(w.widgetInfo.get())) { - hecl::ProjectPath txtrPath = pakRouter.getWorking(info->texture); - if (txtrPath) - os.format(FMT_STRING("frme_obj.retro_energybar_texture_path = '{}'\n"), txtrPath.getRelativePath()); - } - } else if (w.type == SBIG('METR')) { - using METRInfo = Widget::METRInfo; - if (METRInfo* info = static_cast(w.widgetInfo.get())) { - os.format(FMT_STRING("frme_obj.retro_meter_no_round_up = {}\n" - "frme_obj.retro_meter_max_capacity = {}\n" - "frme_obj.retro_meter_worker_count = {}\n"), - info->noRoundUp ? "True" : "False", info->maxCapacity, info->workerCount); - } - } - - zeus::simd_floats xfMtxF[3]; - for (int i = 0; i < 3; ++i) - w.basis[i].simd.copy_to(xfMtxF[i]); - zeus::simd_floats originF(w.origin.simd); - os.format(FMT_STRING("mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "frme_obj.rotation_mode = 'QUATERNION'\n" - "frme_obj.location = mtxd[0]\n" - "frme_obj.rotation_quaternion = mtxd[1] @ angle\n" - "frme_obj.scale = mtxd[2]\n" - "bpy.context.scene.collection.objects.link(frme_obj)\n"), - xfMtxF[0][0], xfMtxF[0][1], xfMtxF[0][2], originF[0], xfMtxF[1][0], xfMtxF[1][1], xfMtxF[1][2], - originF[1], xfMtxF[2][0], xfMtxF[2][1], xfMtxF[2][2], originF[2]); - } - - os.centerView(); - os.close(); - conn.saveBlend(); - return true; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/FRME.hpp b/DataSpec/DNAMP1/FRME.hpp deleted file mode 100644 index 5e24d7c9c..000000000 --- a/DataSpec/DNAMP1/FRME.hpp +++ /dev/null @@ -1,274 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DNAMP1.hpp" -#include -#include "athena/DNAOp.hpp" - -namespace DataSpec::DNAMP1 { -struct FRME : BigDNA { - AT_DECL_EXPLICIT_DNA - Value version; - Value unk1; - Value modelCount; // Matches MODL widgets - Value unk3; - Value widgetCount; - - struct Widget : BigDNA { - AT_DECL_EXPLICIT_DNA - FRME* owner; - DNAFourCC type; - struct WidgetHeader : BigDNA { - AT_DECL_DNA - String<-1> name; - String<-1> parent; - Value useAnimController; - Value defaultVisible; - Value defaultActive; - Value cullFaces; - Value color; - Value modelDrawFlags; - } header; - - struct IWidgetInfo : BigDNAV { - Delete _dBase; - virtual FourCC fourcc() const = 0; - }; - - std::unique_ptr widgetInfo; - Value isWorker; - Value workerId = 0; - Value origin; - Value basis[3]; - Value rotationCenter; - Value unk1; - Value unk2; - - struct BWIGInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::BWIG"sv; } - FourCC fourcc() const override { return FOURCC('BWIG'); } - }; - - struct HWIGInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::HWIG"sv; } - FourCC fourcc() const override { return FOURCC('HWIG'); } - }; - - struct CAMRInfo : IWidgetInfo { - AT_DECL_EXPLICIT_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::CAMR"sv; } - enum class ProjectionType { Perspective, Orthographic }; - - Value projectionType; - struct IProjection : BigDNAV { - Delete _d; - const ProjectionType type; - IProjection(ProjectionType t) : type(t) {} - }; - - struct PerspectiveProjection : IProjection { - AT_DECL_DNAV - PerspectiveProjection() : IProjection(ProjectionType::Perspective) {} - Value fov; - Value aspect; - Value znear; - Value zfar; - }; - - struct OrthographicProjection : IProjection { - AT_DECL_DNAV - OrthographicProjection() : IProjection(ProjectionType::Orthographic) {} - Value left; - Value right; - Value top; - Value bottom; - Value znear; - Value zfar; - }; - std::unique_ptr projection; - - FourCC fourcc() const override { return FOURCC('CAMR'); } - }; - - struct MODLInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::MODL"sv; } - UniqueID32 model; - enum class BlendMode { Unknown0, Unknown1, Unknown2, Additive }; - - Value blendMode; - Value lightMask; - - FourCC fourcc() const override { return FOURCC('MODL'); } - }; - - struct LITEInfo : IWidgetInfo { - AT_DECL_EXPLICIT_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::LITE"sv; } - enum class ELightType : atUint32 { - Spot = 0, - Point = 1, - Directional = 2, - LocalAmbient = 3, - Custom = 4, - }; - - Value type; - Value distC; - Value distL; - Value distQ; - Value angC; - Value angL; - Value angQ; - Value loadedIdx; - Value cutoff; /* Spot only */ - - FourCC fourcc() const override { return FOURCC('LITE'); } - }; - - struct ENRGInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::ENRG"sv; } - UniqueID32 texture; - - FourCC fourcc() const override { return FOURCC('ENRG'); } - }; - - struct METRInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::METR"sv; } - Value unk1; - Value noRoundUp; - Value maxCapacity; - Value workerCount; - - FourCC fourcc() const override { return FOURCC('METR'); } - }; - - struct GRUPInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::GRUP"sv; } - Value defaultWorker; - Value unk3; - - FourCC fourcc() const override { return FOURCC('GRUP'); } - }; - - struct TBGPInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::TBGP"sv; } - Value elementCount; - Value unk2; - Value unkEnum; - Value defaultSelection; - Value un4; - Value selectWraparound; - Value unk6; - Value unkFloat1; - Value unkFloat2; - Value unk7; - Value unkFloat3; - Value unk8; - Value unk9; - Value unk10; - Value unk11; - - FourCC fourcc() const override { return FOURCC('TBGP'); } - }; - - struct SLGPInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::SLGP"sv; } - Value min; - Value max; - Value cur; - Value increment; - - FourCC fourcc() const override { return FOURCC('SLGP'); } - }; - - struct PANEInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::PANE"sv; } - Value xDim; - Value zDim; - Value scaleCenter; - - FourCC fourcc() const override { return FOURCC('PANE'); } - }; - - struct TXPNInfo : IWidgetInfo { - std::string_view DNATypeV() const override { return "FRME::TXPN"sv; } - enum class Justification : atUint32 { - Left = 0, - Center, - Right, - Full, - NLeft, - NCenter, - NRight, - LeftMono, - CenterMono, - RightMono - }; - - enum class VerticalJustification : atUint32 { - Top = 0, - Center, - Bottom, - Full, - NTop, - NCenter, - NBottom, - LeftMono, - CenterMono, - RightMono - }; - - AT_DECL_EXPLICIT_DNAV_NO_TYPE - - atUint32 version = 0; - TXPNInfo() {} - TXPNInfo(atUint32 version) : version(version) {} - Value xDim; - Value zDim; - Value scaleCenter; - UniqueID32 font; - Value wordWrap; - Value horizontal; - Value justification; - Value verticalJustification; - Value fillColor; - Value outlineColor; - Value blockExtent; /* In points; converted to int by loader */ - /* The following is only found in V1 */ - UniqueID32 jpnFont; - Value jpnPointScale[2] = {}; - - FourCC fourcc() const override { return FOURCC('TXPN'); } - }; - - struct IMGPInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::IMGP"sv; } - UniqueID32 texture; - Value unk1; - Value unk2; - Value quadCoordCount; - Vector quadCoords; - Value uvCoordCount; - Vector uvCoords; - - FourCC fourcc() const override { return FOURCC('IMGP'); } - }; - }; - - Vector widgets; - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/HINT.hpp b/DataSpec/DNAMP1/HINT.hpp deleted file mode 100644 index f035bd68c..000000000 --- a/DataSpec/DNAMP1/HINT.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAMP1 { -struct HINT : BigDNA { - AT_DECL_DNA_YAML - Value magic; - Value version; - - struct Hint : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value immediateTime; - Value normalTime; - UniqueID32 stringID; - Value textPageCount; - struct Location : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 worldAssetID; - UniqueID32 areaAssetID; - Value areaID; - UniqueID32 stringID; - }; - - Value locationCount; - Vector locations; - }; - Value hintCount; - Vector hints; - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - HINT hint; - hint.read(rs); - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(hint, writer); - return true; - } - - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - HINT hint; - athena::io::FileReader reader(inPath.getAbsolutePath()); - athena::io::FromYAMLStream(hint, reader); - athena::io::FileWriter ws(outPath.getAbsolutePath()); - hint.write(ws); - return true; - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/MAPA.hpp b/DataSpec/DNAMP1/MAPA.hpp deleted file mode 100644 index 49a0daaf7..000000000 --- a/DataSpec/DNAMP1/MAPA.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MAPA.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -struct MAPA : DNAMAPA::MAPA { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - MAPA mapa; - mapa.read(rs); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); - } - - static bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out) { - return DNAMAPA::Cook(mapa, out); - } - - static uint32_t Version() { return 2; } - using Header = DNAMAPA::MAPA::HeaderMP1; - using MappableObject = DNAMAPA::MAPA::MappableObjectMP1_2; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/MAPU.hpp b/DataSpec/DNAMP1/MAPU.hpp deleted file mode 100644 index a29254dc0..000000000 --- a/DataSpec/DNAMP1/MAPU.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MAPU.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -struct MAPU : DNAMAPU::MAPU { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - MAPU mapu; - mapu.read(rs); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMAPU::ReadMAPUToBlender(conn, mapu, outPath, pakRouter, entry, force); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/MLVL.cpp b/DataSpec/DNAMP1/MLVL.cpp deleted file mode 100644 index 7acce31f9..000000000 --- a/DataSpec/DNAMP1/MLVL.cpp +++ /dev/null @@ -1,537 +0,0 @@ -#include "MLVL.hpp" -#include "SCLY.hpp" -#include "SAVW.hpp" -#include "SCAN.hpp" -#include "ScriptObjects/MemoryRelay.hpp" -#include "ScriptObjects/SpecialFunction.hpp" -#include "ScriptObjects/DoorArea.hpp" -#include "Runtime/RetroTypes.hpp" -#include "Runtime/World/ScriptObjectSupport.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec { -extern hecl::Database::DataSpecEntry SpecEntMP1; - -namespace DNAMP1 { - -bool MLVL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - MLVL mlvl; - mlvl.read(rs); - const nod::Node* node; - const typename PAKRouter::EntryType* savwEntry = pakRouter.lookupEntry(mlvl.saveWorldId, &node); - SAVW savw; - { - PAKEntryReadStream rs = savwEntry->beginReadStream(*node); - savw.read(rs); - } - - atUint32 areaIdx = 0; - for (const MLVL::Area& area : mlvl.areas) { - hecl::ProjectPath areaDir = pakRouter.getWorking(area.areaMREAId).getParentPath(); - { - athena::io::FileWriter fw(hecl::ProjectPath(areaDir, "!memoryid.yaml").getAbsolutePath()); - athena::io::YAMLDocWriter w; - w.writeUint32("memoryid", area.areaId); - w.finish(&fw); - } - { - athena::io::FileWriter fw(hecl::ProjectPath(areaDir, "!memoryrelays.yaml").getAbsolutePath()); - athena::io::YAMLDocWriter w; - - std::vector relayIds; - for (const atUint32& relay : savw.relays) { - atUint16 aIdx = ((relay >> 16) & 0x3ff); - if (aIdx == areaIdx && std::find(relayIds.begin(), relayIds.end(), relay) == relayIds.end()) - relayIds.push_back(relay); - } - - w.enumerate("memrelays", relayIds); - w.finish(&fw); - } - if (pakRouter.mreaHasDupeResources(area.areaMREAId)) - athena::io::FileWriter(hecl::ProjectPath(areaDir, "!duperes").getAbsolutePath()); - - areaIdx++; - } - - athena::io::FileWriter writer(outPath.getWithExtension(".yaml", true).getAbsolutePath()); - athena::io::ToYAMLStream(mlvl, writer, &MLVL::writeMeta); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged); -} - -bool MLVL::ExtractMAPW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - /* Empty placeholder file for dependency management */ - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::YAMLDocWriter dw("DataSpec::DNAMP1::MAPW"); - return dw.finish(&writer); -} - -bool MLVL::ExtractSAVW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - /* Empty placeholder file for dependency management */ - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::YAMLDocWriter dw("DataSpec::DNAMP1::SAVW"); - return dw.finish(&writer); -} - -struct LayerResources { - std::unordered_set addedPaths; - std::vector>> layerPaths; - std::unordered_set addedSharedPaths; - std::vector> sharedPaths; - void beginLayer() { - layerPaths.resize(layerPaths.size() + 1); - addedPaths.clear(); - } - void addSharedPath(const hecl::ProjectPath& path, bool lazy) { - auto search = addedSharedPaths.find(path.hash()); - if (search == addedSharedPaths.cend()) { - sharedPaths.emplace_back(path, lazy); - addedSharedPaths.insert(path.hash()); - } - } - void addPath(const hecl::ProjectPath& path, bool lazy) { - auto search = addedPaths.find(path.hash()); - if (search == addedPaths.cend()) { - layerPaths.back().emplace_back(path, lazy); - addedPaths.insert(path.hash()); - } - } -}; - -bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const World& wld, - hecl::blender::Token& btok) { - MLVL mlvl = {}; - athena::io::FileReader reader(inPath.getWithExtension(".yaml", true).getAbsolutePath()); - athena::io::FromYAMLStream(mlvl, reader, &MLVL::readMeta); - - const hecl::ProjectPath parentPath = inPath.getParentPath(); - const hecl::DirectoryEnumerator dEnum(parentPath.getAbsolutePath()); - - mlvl.magic = 0xDEAFBABE; - mlvl.version = 0x11; - hecl::ProjectPath namePath = GetPathBeginsWith(dEnum, parentPath, "!name"); - if (namePath.isFile()) - mlvl.worldNameId = namePath; - hecl::ProjectPath savwPath = GetPathBeginsWith(dEnum, parentPath, "!savw"); - if (savwPath.isFile()) { - CookSAVW(savwPath.getCookedPath(SpecEntMP1), wld); - mlvl.saveWorldId = savwPath; - } - hecl::ProjectPath mapwPath = GetPathBeginsWith(dEnum, parentPath, "!mapw"); - if (mapwPath.isFile()) { - CookMAPW(mapwPath.getCookedPath(SpecEntMP1), wld); - mlvl.worldMap = mapwPath; - } - - size_t areaIdx = 0; - size_t nameStartIdx = 0; - for (const World::Area& area : wld.areas) { - if (area.path.getPathType() != hecl::ProjectPath::Type::Directory) - continue; - - const hecl::DirectoryEnumerator areaDEnum(area.path.getAbsolutePath()); - const hecl::ProjectPath areaPath = GetPathBeginsWith(areaDEnum, area.path, "!area"); - if (!areaPath.isFile()) - continue; - - Log.report(logvisor::Info, FMT_STRING("Visiting {}"), area.path.getRelativePath()); - - hecl::ProjectPath memRelayPath(area.path, "!memoryrelays.yaml"); - - std::vector memRelays; - - if (memRelayPath.isFile()) { - athena::io::FileReader fr(memRelayPath.getAbsolutePath()); - athena::io::YAMLDocReader r; - if (r.parse(&fr)) - r.enumerate("memrelays", memRelays); - } - - std::vector memRelayLinks; - /* Bare minimum we'll need exactly the same number of links as relays */ - memRelayLinks.reserve(memRelays.size()); - - bool areaInit = false; - size_t layerIdx = 0; - LayerResources layerResources; - const hecl::DirectoryEnumerator enumerator(area.path.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsSorted); - for (const hecl::DirectoryEnumerator::Entry& e : enumerator) { - std::string layerName; - char* endCh = nullptr; - hecl::StrToUl(e.m_name.c_str(), &endCh, 10); - if (!endCh) - layerName = hecl::StringUtils::TrimWhitespace(e.m_name); - else - layerName = hecl::StringUtils::TrimWhitespace(std::string(endCh)); - - hecl::ProjectPath objectsPath(area.path, e.m_name + "/!objects.yaml"); - if (objectsPath.isNone()) - continue; - - SCLY::ScriptLayer layer; - { - athena::io::FileReader freader(objectsPath.getAbsolutePath()); - if (!freader.isOpen()) - continue; - if (!athena::io::ValidateFromYAMLStream(freader)) - continue; - - athena::io::YAMLDocReader reader; - if (!reader.parse(&freader)) - continue; - - layer.read(reader); - } - - layerResources.beginLayer(); - - /* Set active flag state */ - hecl::ProjectPath defActivePath(area.path, e.m_name + "/!defaultactive"); - bool active = defActivePath.isNone() ? false : true; - - if (!areaInit) { - /* Finish last area */ - mlvl.finishLastArea(); - - /* Populate area record */ - mlvl.areas.emplace_back(); - MLVL::Area& areaOut = mlvl.areas.back(); - - namePath = GetPathBeginsWith(areaDEnum, area.path, "!name"); - if (namePath.isFile()) - areaOut.areaNameId = namePath; - - areaOut.transformMtx[0] = area.transform[0]; - areaOut.transformMtx[1] = area.transform[1]; - areaOut.transformMtx[2] = area.transform[2]; - areaOut.aabb[0] = area.aabb[0]; - areaOut.aabb[1] = area.aabb[1]; - areaOut.areaMREAId = areaPath; - areaOut.areaId = 0xffffffff; - - hecl::ProjectPath memIdPath(area.path, "!memoryid.yaml"); - if (memIdPath.isFile()) { - athena::io::FileReader fr(memIdPath.getAbsolutePath()); - athena::io::YAMLDocReader r; - if (r.parse(&fr)) - areaOut.areaId = r.readUint32("memoryid"); - } - - /* Attached Areas and Docks */ - { - std::unordered_set addedAreas; - areaOut.dockCount = area.docks.size(); - for (const World::Area::Dock& dock : area.docks) { - areaOut.docks.emplace_back(); - MLVL::Area::Dock& dockOut = areaOut.docks.back(); - - if (dock.targetArea != UINT32_MAX && dock.targetDock != UINT32_MAX) { - dockOut.endpointCount = 1; - dockOut.endpoints.emplace_back(); - MLVL::Area::Dock::Endpoint& ep = dockOut.endpoints.back(); - ep.areaIdx = dock.targetArea; - ep.dockIdx = dock.targetDock; - - if (addedAreas.find(dock.targetArea) == addedAreas.cend()) { - addedAreas.insert(dock.targetArea); - areaOut.attachedAreas.push_back(dock.targetArea); - } - } else { - dockOut.endpointCount = 0; - } - - dockOut.planeVertCount = 4; - dockOut.planeVerts.push_back(dock.verts[0]); - dockOut.planeVerts.push_back(dock.verts[1]); - dockOut.planeVerts.push_back(dock.verts[2]); - dockOut.planeVerts.push_back(dock.verts[3]); - } - areaOut.attachedAreaCount = areaOut.attachedAreas.size(); - } - - /* Layer flags */ - mlvl.layerFlags.emplace_back(); - mlvl.layerFlags.back().layerCount = 0; - mlvl.layerFlags.back().flags = ~0; - - /* Layer name offset */ - mlvl.layerNameOffsets.push_back(nameStartIdx); - - areaInit = true; - } - - /* Gather memory relays, scans, and dependencies */ - { - g_ThreadBlenderToken.reset(&btok); - std::vector depPaths; - std::vector lazyPaths; - for (std::unique_ptr& obj : layer.objects) { - if (obj->type == int(metaforce::EScriptObjectType::MemoryRelay)) { - MemoryRelay& memRelay = static_cast(*obj); - for (IScriptObject::Connection& conn : memRelay.connections) { - MemRelayLink linkOut; - linkOut.memRelayId = memRelay.id; - linkOut.targetId = conn.target; - linkOut.msg = conn.msg; - linkOut.active = memRelay.active; - auto iter = std::find(memRelays.begin(), memRelays.end(), linkOut.memRelayId); - if (iter == memRelays.end()) { - /* We must have a new relay, let's track it */ - memRelayLinks.push_back(linkOut); - memRelays.push_back(memRelay.id); - } else { - memRelayLinks.push_back(linkOut); - } - } - } - - obj->gatherDependencies(depPaths, lazyPaths); - } - - /* Cull duplicate paths and add typed hash to list */ - for (const hecl::ProjectPath& path : depPaths) - layerResources.addPath(path, false); - for (const hecl::ProjectPath& path : lazyPaths) - layerResources.addPath(path, true); - } - - mlvl.layerNames.emplace_back(layerName); - ++nameStartIdx; - - MLVL::LayerFlags& thisLayFlags = mlvl.layerFlags.back(); - ++thisLayFlags.layerCount; - if (!active) - thisLayFlags.flags &= ~(1 << layerIdx); - - ++layerIdx; - } - - if (!areaInit) - Log.report(logvisor::Info, FMT_STRING("No layer directories for area {}"), area.path.getRelativePath()); - - /* Build deplist */ - MLVL::Area& areaOut = mlvl.areas.back(); - for (const std::vector>& layer : layerResources.layerPaths) { - areaOut.depLayers.push_back(areaOut.deps.size()); - for (const std::pair& path : layer) { - if (path.first) { - metaforce::SObjectTag tag = g_curSpec->buildTagFromPath(path.first); - if (tag.id.IsValid()) { - if (path.second) - areaOut.lazyDeps.emplace_back(tag.id.Value(), tag.type.toUint32()); - else - areaOut.lazyDeps.emplace_back(0, FOURCC('NONE')); - areaOut.deps.emplace_back(tag.id.Value(), tag.type.toUint32()); - } - } - } - } - - /* Append Memory Relays */ - if (!memRelayLinks.empty()) - mlvl.memRelayLinks.insert(mlvl.memRelayLinks.end(), memRelayLinks.begin(), memRelayLinks.end()); - - /* Cull duplicate area paths and add typed hash to list */ - auto& conn = btok.getBlenderConnection(); - if (conn.openBlend(areaPath)) { - areaOut.depLayers.push_back(areaOut.deps.size()); - - auto ds = conn.beginData(); - std::vector texs = ds.getTextures(); - ds.close(); - - for (const hecl::ProjectPath& path : texs) - layerResources.addSharedPath(path, false); - - for (const std::pair& path : layerResources.sharedPaths) { - metaforce::SObjectTag tag = g_curSpec->buildTagFromPath(path.first); - if (tag.id.IsValid()) { - if (path.second) - areaOut.lazyDeps.emplace_back(tag.id.Value(), tag.type.toUint32()); - else - areaOut.lazyDeps.emplace_back(0, FOURCC('NONE')); - areaOut.deps.emplace_back(tag.id.Value(), tag.type.toUint32()); - } - } - - hecl::ProjectPath pathPath = GetPathBeginsWith(areaDEnum, area.path, "!path"); - metaforce::SObjectTag pathTag = g_curSpec->buildTagFromPath(pathPath); - if (pathTag.id.IsValid()) { - areaOut.deps.emplace_back(pathTag.id.Value(), pathTag.type.toUint32()); - areaOut.lazyDeps.emplace_back(0, FOURCC('NONE')); - } - } - - ++areaIdx; - } - - /* Finish last area */ - mlvl.finishLastArea(); - - mlvl.memRelayLinkCount = mlvl.memRelayLinks.size(); - mlvl.areaCount = mlvl.areas.size(); - mlvl.layerFlagCount = mlvl.layerFlags.size(); - mlvl.layerNameCount = mlvl.layerNames.size(); - mlvl.layerNameOffsetCount = mlvl.layerNameOffsets.size(); - - /* Write out */ - { - athena::io::FileWriter fo(outPath.getAbsolutePath()); - mlvl.write(fo); - int64_t rem = fo.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - fo.writeBytes((atInt8*)"\xff", 1); - } - - return true; -} - -bool MLVL::CookMAPW(const hecl::ProjectPath& outPath, const World& wld) { - std::vector mapaTags; - mapaTags.reserve(wld.areas.size()); - - for (const World::Area& area : wld.areas) { - if (area.path.getPathType() != hecl::ProjectPath::Type::Directory) - continue; - - /* Area map */ - hecl::ProjectPath mapPath = GetPathBeginsWith(area.path, "!map"); - if (mapPath.isFile()) - mapaTags.push_back(g_curSpec->buildTagFromPath(mapPath)); - } - - /* Write out MAPW */ - { - athena::io::FileWriter fo(outPath.getAbsolutePath()); - fo.writeUint32Big(0xDEADF00D); - fo.writeUint32Big(1); - fo.writeUint32Big(mapaTags.size()); - for (const metaforce::SObjectTag& mapa : mapaTags) - fo.writeUint32Big(u32(mapa.id.Value())); - int64_t rem = fo.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - fo.writeBytes((atInt8*)"\xff", 1); - } - - return true; -} - -bool MLVL::CookSAVW(const hecl::ProjectPath& outPath, const World& wld) { - SAVW savw = {}; - savw.header.magic = 0xC001D00D; - savw.header.version = 0x3; - std::unordered_set addedScans; - - for (const World::Area& area : wld.areas) { - if (area.path.getPathType() != hecl::ProjectPath::Type::Directory) - continue; - - hecl::ProjectPath areaPath = GetPathBeginsWith(area.path, "!area"); - if (!areaPath.isFile()) - continue; - - hecl::ProjectPath memRelayPath(area.path, "/!memoryrelays.yaml"); - std::vector memRelays; - if (memRelayPath.isFile()) { - athena::io::FileReader fr(memRelayPath.getAbsolutePath()); - athena::io::YAMLDocReader r; - if (r.parse(&fr)) - r.enumerate("memrelays", memRelays); - } - savw.relays.insert(savw.relays.end(), memRelays.begin(), memRelays.end()); - - for (const hecl::DirectoryEnumerator::Entry& e : - hecl::DirectoryEnumerator(area.path.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsSorted)) { - hecl::ProjectPath objectsPath(area.path, e.m_name + "/!objects.yaml"); - if (objectsPath.isNone()) - continue; - - SCLY::ScriptLayer layer; - { - athena::io::FileReader freader(objectsPath.getAbsolutePath()); - if (!freader.isOpen()) - continue; - if (!athena::io::ValidateFromYAMLStream(freader)) - continue; - - athena::io::YAMLDocReader reader; - if (!reader.parse(&freader)) - continue; - - layer.read(reader); - } - - /* Gather memory relays, scans, and dependencies */ - { - std::vector scans; - for (std::unique_ptr& obj : layer.objects) { - if (obj->type == int(metaforce::EScriptObjectType::MemoryRelay)) { - MemoryRelay& memRelay = static_cast(*obj); - auto iter = std::find(memRelays.begin(), memRelays.end(), memRelay.id); - if (iter == memRelays.end()) { - /* We must have a new relay, let's track it */ - savw.relays.push_back(memRelay.id); - memRelays.push_back(memRelay.id); - } - } else if (obj->type == int(metaforce::EScriptObjectType::SpecialFunction)) { - SpecialFunction& specialFunc = static_cast(*obj); - if (specialFunc.function == ESpecialFunctionType::CinematicSkip) - savw.skippableCutscenes.push_back(specialFunc.id); - else if (specialFunc.function == ESpecialFunctionType::ScriptLayerController) { - savw.layers.emplace_back(); - SAVWCommon::Layer& layer = savw.layers.back(); - layer.areaId = specialFunc.layerSwitch.area; - layer.layer = specialFunc.layerSwitch.layerIdx; - } - } else if (obj->type == int(metaforce::EScriptObjectType::Door)) { - DoorArea& doorArea = static_cast(*obj); - savw.doors.push_back(doorArea.id); - } - - obj->gatherScans(scans); - } - - /* Cull duplicate scans and add to list */ - for (const Scan& scan : scans) { - if (!scan.scanId.isValid()) - continue; - if (addedScans.find(scan.scanId) == addedScans.cend()) { - addedScans.insert(scan.scanId); - hecl::ProjectPath scanPath = UniqueIDBridge::TranslatePakIdToPath(scan.scanId); - savw.scans.emplace_back(); - Scan& scanOut = savw.scans.back(); - scanOut.scanId = scan.scanId; - scanOut.category = SAVWCommon::EScanCategory(SCAN::GetCategory(scanPath)); - } - } - } - } - } - - /* Write out SAVW */ - { - savw.header.areaCount = wld.areas.size(); - savw.skippableCutsceneCount = savw.skippableCutscenes.size(); - savw.relayCount = savw.relays.size(); - savw.layerCount = savw.layers.size(); - savw.doorCount = savw.doors.size(); - savw.scanCount = savw.scans.size(); - - athena::io::FileWriter fo(outPath.getAbsolutePath()); - savw.write(fo); - int64_t rem = fo.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - fo.writeBytes((atInt8*)"\xff", 1); - } - - return true; -} - -} // namespace DNAMP1 -} // namespace DataSpec diff --git a/DataSpec/DNAMP1/MLVL.hpp b/DataSpec/DNAMP1/MLVL.hpp deleted file mode 100644 index 98dc25587..000000000 --- a/DataSpec/DNAMP1/MLVL.hpp +++ /dev/null @@ -1,148 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MLVL.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -struct MLVL : BigDNA { - AT_DECL_DNA_YAML - Value magic; - Value version; - UniqueID32 worldNameId; - UniqueID32 saveWorldId; - UniqueID32 worldSkyboxId; - - Value memRelayLinkCount; - struct MemRelayLink : BigDNA { - AT_DECL_DNA_YAML - Value memRelayId; - Value targetId; - Value msg; - Value active; - }; - Vector memRelayLinks; - - Value areaCount; - Value unknown1; - struct Area : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 areaNameId; - Value transformMtx[3]; - Value aabb[2]; - UniqueID32 areaMREAId; - Value areaId; - - Value attachedAreaCount; - Vector attachedAreas; - - struct Dependency : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 id; - DNAFourCC type; - - Dependency() = default; - Dependency(const UniqueID32& idin, const hecl::FourCC& fcc) : id(idin), type(fcc) {} - }; - - Value lazyDepCount; - Vector lazyDeps; - - Value depCount; - Vector deps; - - Value depLayerCount; - Vector depLayers; - - Value dockCount; - struct Dock : BigDNA { - AT_DECL_DNA_YAML - Value endpointCount; - struct Endpoint : BigDNA { - AT_DECL_DNA_YAML - Value areaIdx; - Value dockIdx; - }; - Vector endpoints; - - Value planeVertCount; - Vector planeVerts; - }; - Vector docks; - }; - Vector areas; - - void finishLastArea() { - if (areas.size()) { - MLVL::Area& areaLast = areas.back(); - areaLast.attachedAreaCount = areaLast.attachedAreas.size(); - areaLast.lazyDepCount = areaLast.lazyDeps.size(); - areaLast.depCount = areaLast.deps.size(); - areaLast.depLayerCount = areaLast.depLayers.size(); - areaLast.dockCount = areaLast.docks.size(); - } - } - - UniqueID32 worldMap; - Value unknown2; - Value unknown3; - - Value audioGroupCount; - struct AudioGroup : BigDNA { - AT_DECL_DNA_YAML - Value groupId; - UniqueID32 agscId; - }; - Vector audioGroups; - String<-1> unkString; - - Value layerFlagCount; - struct LayerFlags : BigDNA { - AT_DECL_DNA_YAML - Value layerCount; - Value flags; - }; - Vector layerFlags; - - Value layerNameCount; - Vector, AT_DNA_COUNT(layerNameCount)> layerNames; - - Value layerNameOffsetCount; - Vector layerNameOffsets; - - void readMeta(athena::io::YAMLDocReader& __dna_docin) { - /* worldSkyboxId */ - __dna_docin.enumerate("worldSkyboxId", worldSkyboxId); - /* audioGroupCount squelched */ - /* audioGroups */ - audioGroupCount = __dna_docin.enumerate("audioGroups", audioGroups); - } - - void writeMeta(athena::io::YAMLDocWriter& __dna_docout) const { - /* worldSkyboxId */ - __dna_docout.enumerate("worldSkyboxId", worldSkyboxId); - /* audioGroupCount squelched */ - /* audioGroups */ - __dna_docout.enumerate("audioGroups", audioGroups); - } - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged); - - static bool ExtractMAPW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - - static bool ExtractSAVW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - - using World = hecl::blender::World; - - static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const World& wld, - hecl::blender::Token& btok); - - static bool CookMAPW(const hecl::ProjectPath& outPath, const World& wld); - - static bool CookSAVW(const hecl::ProjectPath& outPath, const World& wld); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/MREA.cpp b/DataSpec/DNAMP1/MREA.cpp deleted file mode 100644 index d3ab74930..000000000 --- a/DataSpec/DNAMP1/MREA.cpp +++ /dev/null @@ -1,771 +0,0 @@ -#include "hecl/ClientProcess.hpp" -#include "athena/MemoryReader.hpp" -#include "MREA.hpp" -#include "SCLY.hpp" -#include "PATH.hpp" -#include "DeafBabe.hpp" -#include "DataSpec/DNACommon/BabeDead.hpp" -#include "zeus/Math.hpp" -#include "zeus/CAABox.hpp" -#include "DataSpec/DNACommon/AROTBuilder.hpp" -#include "ScriptObjects/ScriptTypes.hpp" -#include "hecl/Blender/Connection.hpp" - -#define DUMP_OCTREE 0 - -extern std::string ExeDir; - -namespace DataSpec::DNAMP1 { - -void MREA::ReadBabeDeadToBlender_1_2(hecl::blender::PyOutStream& os, athena::io::IStreamReader& rs) { - atUint32 bdMagic = rs.readUint32Big(); - if (bdMagic != 0xBABEDEAD) - Log.report(logvisor::Fatal, FMT_STRING("invalid BABEDEAD magic")); - os << "bpy.context.scene.world.use_nodes = True\n" - "bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n" - "bg_node.inputs[1].default_value = 0.0\n"; - for (atUint32 s = 0; s < 2; ++s) { - atUint32 lightCount = rs.readUint32Big(); - for (atUint32 l = 0; l < lightCount; ++l) { - BabeDeadLight light; - light.read(rs); - ReadBabeDeadLightToBlender(os, light, s, l); - } - } -} - -void MREA::AddCMDLRigPairs(PAKEntryReadStream& rs, PAKRouter& pakRouter, - CharacterAssociations& charAssoc) { - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* Skip to SCLY */ - atUint32 curSec = 0; - atUint64 secStart = rs.position(); - while (curSec != head.sclySecIdx) - secStart += head.secSizes[curSec++]; - rs.seek(secStart, athena::SeekOrigin::Begin); - SCLY scly; - scly.read(rs); - scly.addCMDLRigPairs(pakRouter, charAssoc); -} - -UniqueID32 MREA::GetPATHId(PAKEntryReadStream& rs) { - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* Skip to PATH */ - atUint32 curSec = 0; - atUint64 secStart = rs.position(); - while (curSec != head.pathSecIdx) - secStart += head.secSizes[curSec++]; - if (!head.secSizes[curSec]) - return {}; - rs.seek(secStart, athena::SeekOrigin::Begin); - return {rs}; -} - -#if DUMP_OCTREE -/* Collision octree dumper */ -static void OutputOctreeNode(hecl::blender::PyOutStream& os, athena::io::MemoryReader& r, BspNodeType type, - const zeus::CAABox& aabb) { - if (type == BspNodeType::Branch) { - u16 flags = r.readUint16Big(); - r.readUint16Big(); - u32 offsets[8]; - for (int i = 0; i < 8; ++i) - offsets[i] = r.readUint32Big(); - u32 dataStart = r.position(); - for (int i = 0; i < 8; ++i) { - r.seek(dataStart + offsets[i], athena::SeekOrigin::Begin); - int chFlags = (flags >> (i * 2)) & 0x3; - - zeus::CAABox pos, neg, res; - aabb.splitZ(neg, pos); - if (i & 4) { - zeus::CAABox(pos).splitY(neg, pos); - if (i & 2) { - zeus::CAABox(pos).splitX(neg, pos); - if (i & 1) - res = pos; - else - res = neg; - } else { - zeus::CAABox(neg).splitX(neg, pos); - if (i & 1) - res = pos; - else - res = neg; - } - } else { - zeus::CAABox(neg).splitY(neg, pos); - if (i & 2) { - zeus::CAABox(pos).splitX(neg, pos); - if (i & 1) - res = pos; - else - res = neg; - } else { - zeus::CAABox(neg).splitX(neg, pos); - if (i & 1) - res = pos; - else - res = neg; - } - } - - OutputOctreeNode(os, r, BspNodeType(chFlags), res); - } - } else if (type == BspNodeType::Leaf) { - zeus::CVector3f pos = aabb.center(); - zeus::CVector3f extent = aabb.extents(); - os.format( - "obj = bpy.data.objects.new('Leaf', None)\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "obj.location = (%f,%f,%f)\n" - "obj.scale = (%f,%f,%f)\n" - "obj.empty_display_type = 'CUBE'\n" - "obj.layers[1] = True\n" - "obj.layers[0] = False\n", - pos.x, pos.y, pos.z, extent.x, extent.y, extent.z); - } -} - -static const uint32_t AROTChildCounts[] = {0, 2, 2, 4, 2, 4, 4, 8}; - -/* AROT octree dumper */ -static void OutputOctreeNode(hecl::blender::PyOutStream& os, athena::io::IStreamReader& r, const zeus::CAABox& aabb) { - r.readUint16Big(); - u16 flags = r.readUint16Big(); - if (flags) { - u32 childCount = AROTChildCounts[flags]; - r.seek(2 * childCount); - - zeus::CAABox Z[2] = {aabb}; - if ((flags & 0x4) != 0) - aabb.splitZ(Z[0], Z[1]); - for (int k = 0; k < 1 + ((flags & 0x4) != 0); ++k) { - zeus::CAABox Y[2] = {Z[k]}; - if ((flags & 0x2) != 0) - Z[k].splitY(Y[0], Y[1]); - for (int j = 0; j < 1 + ((flags & 0x2) != 0); ++j) { - zeus::CAABox X[2] = {Y[j]}; - if ((flags & 0x1) != 0) - Y[j].splitX(X[0], X[1]); - for (int i = 0; i < 1 + ((flags & 0x1) != 0); ++i) { - OutputOctreeNode(os, r, X[i]); - } - } - } - } else { - zeus::CVector3f pos = aabb.center(); - zeus::CVector3f extent = aabb.extents(); - os.format( - "obj = bpy.data.objects.new('Leaf', None)\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "obj.location = (%f,%f,%f)\n" - "obj.scale = (%f,%f,%f)\n" - "obj.empty_display_type = 'CUBE'\n" - "obj.layers[1] = True\n" - "obj.layers[0] = False\n", - pos.x, pos.y, pos.z, extent.x, extent.y, extent.z); - } -} -#endif - -bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function) { - using RigPair = std::pair, std::pair>; - RigPair dummy = {}; - - if (!force && outPath.isFile()) - return true; - - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Area)) - return false; - - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os << "import bpy\n" - "import bmesh\n" - "from mathutils import Vector\n" - "bpy.context.scene.render.fps = 60\n" - "\n"; - os.format(FMT_STRING("bpy.context.scene.name = '{}'\n"), pakRouter.getBestEntryName(entry, false)); - DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath()); - MaterialSet::RegisterMaterialProps(os); - os << "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "bpy.types.Light.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n" - "bpy.types.Light.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n" - "bpy.types.Object.retro_disable_enviro_visor = bpy.props.BoolProperty(name='Retro: Disable in Combat/Scan " - "Visor')\n" - "bpy.types.Object.retro_disable_thermal_visor = bpy.props.BoolProperty(name='Retro: Disable in Thermal " - "Visor')\n" - "bpy.types.Object.retro_disable_xray_visor = bpy.props.BoolProperty(name='Retro: Disable in X-Ray Visor')\n" - "bpy.types.Object.retro_thermal_level = bpy.props.EnumProperty(items=[('COOL', 'Cool', 'Cool Temperature')," - "('HOT', 'Hot', 'Hot Temperature')," - "('WARM', 'Warm', 'Warm Temperature')]," - "name='Retro: Thermal Visor Level')\n" - "\n"; - - /* One shared material set for all meshes */ - os << "# Materials\n" - "materials = []\n" - "\n"; - MaterialSet matSet; - atUint64 secStart = rs.position(); - matSet.read(rs); - matSet.readToBlender(os, pakRouter, entry, 0); - rs.seek(secStart + head.secSizes[0], athena::SeekOrigin::Begin); - std::vector vertAttribs; - DNACMDL::GetVertexAttributes(matSet, vertAttribs); - - /* Read meshes */ - atUint32 curSec = 1; - for (atUint32 m = 0; m < head.meshCount; ++m) { - MeshHeader mHeader; - secStart = rs.position(); - mHeader.read(rs); - rs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - curSec += DNACMDL::ReadGeomSectionsToBlender, MaterialSet, RigPair, DNACMDL::SurfaceHeader_1>( - os, rs, pakRouter, entry, dummy, true, true, vertAttribs, m, head.secCount, 0, &head.secSizes[curSec]); - os.format(FMT_STRING("obj.retro_disable_enviro_visor = {}\n" - "obj.retro_disable_thermal_visor = {}\n" - "obj.retro_disable_xray_visor = {}\n" - "obj.retro_thermal_level = '{}'\n"), - mHeader.visorFlags.disableEnviro() ? "True" : "False", - mHeader.visorFlags.disableThermal() ? "True" : "False", - mHeader.visorFlags.disableXray() ? "True" : "False", mHeader.visorFlags.thermalLevelStr()); - } - - /* Skip AROT */ - secStart = rs.position(); - rs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Read SCLY layers */ - secStart = rs.position(); - SCLY scly; - scly.read(rs); - scly.exportToLayerDirectories(entry, pakRouter, force); - rs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Read collision meshes */ - DeafBabe collision; - secStart = rs.position(); - collision.read(rs); - DeafBabe::BlenderInit(os); - collision.sendToBlender(os); - rs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Skip unknown section */ - rs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - - /* Read BABEDEAD Lights as Cycles emissives */ - secStart = rs.position(); - ReadBabeDeadToBlender_1_2(os, rs); - rs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Dump VISI entities */ - secStart = rs.position(); - if (head.secSizes[curSec] && rs.readUint32Big() == 'VISI') { - { - rs.seek(secStart, athena::SeekOrigin::Begin); - auto visiData = rs.readUBytes(head.secSizes[curSec]); - athena::io::FileWriter visiOut(outPath.getWithExtension(".visi", true).getAbsolutePath()); - visiOut.writeUBytes(visiData.get(), head.secSizes[curSec]); - rs.seek(secStart + 4, athena::SeekOrigin::Begin); - } - - athena::io::YAMLDocWriter visiWriter("VISI"); - if (auto __vec = visiWriter.enterSubVector("entities")) { - rs.seek(18, athena::SeekOrigin::Current); - uint32_t entityCount = rs.readUint32Big(); - rs.seek(8, athena::SeekOrigin::Current); - for (uint32_t i = 0; i < entityCount; ++i) { - uint32_t entityId = rs.readUint32Big(); - visiWriter.writeUint32(entityId); - } - } - hecl::ProjectPath visiMetadataPath(outPath.getParentPath(), "!visi.yaml"); - athena::io::FileWriter visiMetadata(visiMetadataPath.getAbsolutePath()); - visiWriter.finish(&visiMetadata); - } - - /* Origins to center of mass */ - os << "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = False\n" - "bpy.ops.object.select_by_type(type='MESH')\n" - "bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')\n" - "bpy.ops.object.select_all(action='DESELECT')\n" - "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = True\n"; - - /* Link MLVL scene as background */ - os.linkBackground(fmt::format(FMT_STRING("//../!world_{}.blend"), pakRouter.getCurrentBridge().getLevelId()), - "World"sv); - - os.centerView(); - os.close(); - return conn.saveBlend(); -} - -void MREA::Name(const SpecBase& dataSpec, PAKEntryReadStream& rs, PAKRouter& pakRouter, PAK::Entry& entry) { - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* One shared material set for all meshes */ - atUint64 secStart = rs.position(); - MaterialSet matSet; - matSet.read(rs); - matSet.nameTextures(pakRouter, fmt::format(FMT_STRING("MREA_{}"), entry.id).c_str(), -1); - rs.seek(secStart + head.secSizes[0], athena::SeekOrigin::Begin); - - /* Skip to SCLY */ - atUint32 curSec = 1; - secStart = rs.position(); - while (curSec != head.sclySecIdx) - secStart += head.secSizes[curSec++]; - rs.seek(secStart, athena::SeekOrigin::Begin); - SCLY scly; - scly.read(rs); - scly.nameIDs(pakRouter); - - /* Skip to PATH */ - while (curSec != head.pathSecIdx) - secStart += head.secSizes[curSec++]; - rs.seek(secStart, athena::SeekOrigin::Begin); - - UniqueID32 pathID(rs); - const nod::Node* node; - PAK::Entry* pathEnt = (PAK::Entry*)pakRouter.lookupEntry(pathID, &node); - pathEnt->name = entry.name + "_path"; -} - -void MREA::MeshHeader::VisorFlags::setFromBlenderProps(const std::unordered_map& props) { - auto search = props.find("retro_disable_enviro_visor"); - if (search != props.cend() && search->second == "1") - setDisableEnviro(true); - search = props.find("retro_disable_thermal_visor"); - if (search != props.cend() && search->second == "1") - setDisableThermal(true); - search = props.find("retro_disable_xray_visor"); - if (search != props.cend() && search->second == "1") - setDisableXray(true); - search = props.find("retro_thermal_level"); - if (search != props.cend()) { - if (search->second == "0") - setThermalLevel(ThermalLevel::Cool); - else if (search->second == "1") - setThermalLevel(ThermalLevel::Hot); - else if (search->second == "2") - setThermalLevel(ThermalLevel::Warm); - } -} - -bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, - const std::vector& meshes, const ColMesh& cMesh, const std::vector& lights, - hecl::blender::Token& btok, const hecl::blender::Matrix4f* xf, bool pc) { - /* Discover area layers */ - hecl::ProjectPath areaDirPath = inPath.getParentPath(); - std::vector layerScriptPaths; - { - hecl::DirectoryEnumerator dEnum(inPath.getParentPath().getAbsolutePath(), - hecl::DirectoryEnumerator::Mode::DirsSorted, false, false, true); - for (const hecl::DirectoryEnumerator::Entry& ent : dEnum) { - hecl::ProjectPath layerScriptPath(areaDirPath, ent.m_name + "/!objects.yaml"); - if (layerScriptPath.isFile()) - layerScriptPaths.push_back(std::move(layerScriptPath)); - } - } - - size_t secCount = 1 + meshes.size() * (pc ? 5 : 7); /* (materials, 5/7 fixed model secs) */ - - /* tally up surfaces */ - for (const DNACMDL::Mesh& mesh : meshes) - secCount += mesh.surfaces.size(); - - /* Header */ - Header head = {}; - head.magic = 0xDEADBEEF; - head.version = pc ? 0x1000F : 0xF; - if (xf) { - head.localToWorldMtx[0] = xf->val[0]; - head.localToWorldMtx[1] = xf->val[1]; - head.localToWorldMtx[2] = xf->val[2]; - } else { - head.localToWorldMtx[0].simd[0] = 1.f; - head.localToWorldMtx[1].simd[1] = 1.f; - head.localToWorldMtx[2].simd[2] = 1.f; - } - head.meshCount = meshes.size(); - head.geomSecIdx = 0; - head.arotSecIdx = secCount++; - head.sclySecIdx = secCount++; - head.collisionSecIdx = secCount++; - head.unkSecIdx = secCount++; - head.lightSecIdx = secCount++; - head.visiSecIdx = secCount++; - head.pathSecIdx = secCount++; - head.secCount = secCount; - - std::vector> secs; - secs.reserve(secCount + 2); - - /* Header section */ - { - size_t secSz = 0; - head.binarySize(secSz); - secs.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); - head.write(w); - int i = w.position(); - int end = ROUND_UP_32(i); - for (; i < end; ++i) - w.writeByte(0); - } - - /* Sizes section */ - secs.emplace_back(); - - /* Pre-emptively build full AABB and mesh AABBs in world coords */ - zeus::CAABox fullAabb; - std::vector meshAabbs; - meshAabbs.reserve(meshes.size()); - - /* Models */ - if (pc) { - if (!DNACMDL::WriteHMDLMREASecs(secs, inPath, meshes, - fullAabb, meshAabbs)) - return false; - } else { - if (!DNACMDL::WriteMREASecs(secs, inPath, meshes, fullAabb, - meshAabbs)) - return false; - } - - /* AROT */ - { - AROTBuilder arotBuilder; - arotBuilder.build(secs, fullAabb, meshAabbs, meshes); - -#if DUMP_OCTREE - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(inPath.getWithExtension(".octree.blend", true), hecl::blender::BlendType::Area)) - return false; - - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os.format( - "import bpy\n" - "import bmesh\n" - "from mathutils import Vector\n" - "\n" - "bpy.context.scene.name = '%s'\n", - inPath.getLastComponent().data()); - - athena::io::MemoryReader reader(secs.back().data(), secs.back().size()); - reader.readUint32Big(); - reader.readUint32Big(); - u32 numMeshBitmaps = reader.readUint32Big(); - u32 meshBitCount = reader.readUint32Big(); - u32 numNodes = reader.readUint32Big(); - auto aabbMin = reader.readVec3fBig(); - auto aabbMax = reader.readVec3fBig(); - reader.seekAlign32(); - reader.seek(ROUND_UP_32(meshBitCount) / 8 * numMeshBitmaps + numNodes * 4); - zeus::CAABox arotAABB(aabbMin, aabbMax); - OutputOctreeNode(os, reader, arotAABB); - - os.centerView(); - os.close(); - conn.saveBlend(); -#endif - } - - /* SCLY */ - DNAMP1::SCLY sclyData = {}; - { - sclyData.fourCC = FOURCC('SCLY'); - sclyData.version = 1; - for (const hecl::ProjectPath& layer : layerScriptPaths) { - athena::io::FileReader freader(layer.getAbsolutePath()); - if (!freader.isOpen()) - continue; - if (!athena::io::ValidateFromYAMLStream(freader)) - continue; - - athena::io::YAMLDocReader reader; - if (!reader.parse(&freader)) - continue; - - sclyData.layers.emplace_back(); - sclyData.layers.back().read(reader); - size_t layerSize = 0; - sclyData.layers.back().binarySize(layerSize); - sclyData.layerSizes.push_back(layerSize); - } - sclyData.layerCount = sclyData.layers.size(); - - size_t secSz = 0; - sclyData.binarySize(secSz); - secs.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); - sclyData.write(w); - } - - /* Collision */ - { - DeafBabe collision = {}; - DeafBabeBuildFromBlender(collision, cMesh); - -#if DUMP_OCTREE - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(inPath.getWithExtension(".coctree.blend", true), hecl::blender::BlendType::Area)) - return false; - - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os.format( - "import bpy\n" - "import bmesh\n" - "from mathutils import Vector\n" - "\n" - "bpy.context.scene.name = '%s'\n", - inPath.getLastComponent().data()); - - athena::io::MemoryReader reader(collision.bspTree.get(), collision.bspSize); - zeus::CAABox colAABB(collision.aabb[0], collision.aabb[1]); - OutputOctreeNode(os, reader, collision.rootNodeType, colAABB); - - os.centerView(); - os.close(); - conn.saveBlend(); -#endif - - size_t secSz = 0; - collision.binarySize(secSz); - secs.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); - collision.write(w); - } - - /* Unk */ - { - secs.emplace_back(8, 0); - athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); - w.writeUint32Big(1); - } - - /* Lights */ - std::vector lightsVisi[2]; - { - int actualCounts[2] = {}; - for (const Light& l : lights) - if (l.layer == 0 || l.layer == 1) - ++actualCounts[l.layer]; - lightsVisi[0].reserve(actualCounts[0]); - lightsVisi[1].reserve(actualCounts[1]); - - secs.emplace_back(12 + 65 * (actualCounts[0] + actualCounts[1]), 0); - athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); - w.writeUint32Big(0xBABEDEAD); - - for (uint32_t lay = 0; lay < 2; ++lay) { - int lightCount = 0; - for (const Light& l : lights) { - if (l.layer == lay) - ++lightCount; - } - w.writeUint32Big(lightCount); - for (const Light& l : lights) { - if (l.layer == lay) { - BabeDeadLight light = {}; - WriteBabeDeadLightFromBlender(light, l); - light.write(w); - lightsVisi[l.layer].push_back(light.position); - } - } - } - } - - /* VISI */ - hecl::ProjectPath visiMetadataPath(areaDirPath, "!visi.yaml"); - bool visiGood = false; - if (visiMetadataPath.isFile()) { - athena::io::FileReader visiReader(visiMetadataPath.getAbsolutePath()); - athena::io::YAMLDocReader r; - if (r.parse(&visiReader)) { - size_t entityCount; - std::vector> entities; - if (auto __vec = r.enterSubVector("entities", entityCount)) { - entities.reserve(entityCount); - for (size_t i = 0; i < entityCount; ++i) { - uint32_t entityId = r.readUint32(); - for (const SCLY::ScriptLayer& layer : sclyData.layers) { - for (const std::unique_ptr& obj : layer.objects) { - if ((obj->id & ~0x03FF0000) == entityId) { - zeus::CAABox entAABB = obj->getVISIAABB(btok); - if (!entAABB.invalid()) - entities.emplace_back(entityId, entAABB); - } - } - } - } - } - - // Check if pre-generated visi exists, recycle if able - hecl::ProjectPath preVisiPath = inPath.getWithExtension(".visi", true); - if (preVisiPath.getPathType() == hecl::ProjectPath::Type::File) { - athena::io::FileReader preVisiReader(preVisiPath.getAbsolutePath()); - atUint64 preVisiLen = preVisiReader.length(); - if (preVisiLen > 26) { - auto preVisiData = preVisiReader.readUBytes(preVisiLen); - athena::io::MemoryReader preVisiDataReader(preVisiData.get(), preVisiLen); - - atUint32 preVisiFourCC = preVisiDataReader.readUint32Big(); - atUint32 preVisiVersion = preVisiDataReader.readUint32Big(); - preVisiDataReader.readBool(); - preVisiDataReader.readBool(); - atUint32 preFeatureCount = preVisiDataReader.readUint32Big(); - atUint32 preLightsCount = preVisiDataReader.readUint32Big(); - atUint32 preLayer2LightCount = preVisiDataReader.readUint32Big(); - atUint32 preEntityCount = preVisiDataReader.readUint32Big(); - - if (preVisiFourCC == 'VISI' && preVisiVersion == 2 && preFeatureCount == meshes.size() + entities.size() && - preLightsCount == lightsVisi[0].size() + lightsVisi[1].size() && - preLayer2LightCount == lightsVisi[1].size() && preEntityCount == entities.size()) { - secs.emplace_back(preVisiLen, 0); - memcpy(secs.back().data(), preVisiData.get(), preVisiLen); - visiGood = true; - } else { - // TODO: Fix visigen and remove this hack - secs.emplace_back(preVisiLen, 0); - memcpy(secs.back().data(), preVisiData.get(), preVisiLen); - visiGood = true; - } - } - } -// TODO: fix visigen so this can be re-enabled -#if 0 -#if !WINDOWS_STORE - if (!visiGood) { - hecl::ProjectPath visiIntOut = outPath.getWithExtension(".visiint"); - athena::io::FileWriter w(visiIntOut.getAbsolutePath()); - w.writeUint32Big(meshes.size()); - for (const DNACMDL::Mesh& mesh : meshes) { - w.writeUint32Big(uint32_t(mesh.topology)); - - w.writeUint32Big(mesh.pos.size()); - for (const auto& v : mesh.pos) { - atVec3f xfPos = hecl::blender::MtxVecMul4RM(mesh.sceneXf, v); - w.writeVec3fBig(xfPos); - } - - w.writeUint32Big(mesh.surfaces.size()); - for (const DNACMDL::Mesh::Surface& surf : mesh.surfaces) { - w.writeUint32Big(surf.verts.size()); - for (const DNACMDL::Mesh::Surface::Vert& vert : surf.verts) - w.writeUint32Big(vert.iPos); - const DNACMDL::Material& mat = mesh.materialSets[0][surf.materialIdx]; - w.writeBool(mat.blendMode != DNACMDL::Material::BlendMode::Opaque); - } - } - - w.writeUint32Big(entities.size()); - for (const auto& ent : entities) { - w.writeUint32Big(ent.first); - w.writeVec3fBig(ent.second.min); - w.writeVec3fBig(ent.second.max); - } - - w.writeUint32Big(lightsVisi[0].size() + lightsVisi[1].size()); - w.writeUint32Big(lightsVisi[1].size()); - for (const auto& light : lightsVisi[1]) - w.writeVec3fBig(light); - for (const auto& light : lightsVisi[0]) - w.writeVec3fBig(light); - - w.close(); - - std::string VisiGenPath = ExeDir + "/visigen"; -#if _WIN32 - VisiGenPath += ".exe"; -#endif - std::string thrIdx = fmt::format(FMT_STRING("{}"), hecl::ClientProcess::GetThreadWorkerIdx()); - std::string parPid; -#if _WIN32 - parPid = fmt::format(FMT_STRING("{}"), reinterpret_cast(GetCurrentProcess())); -#else - parPid = fmt::format(FMT_STRING("{}"), (unsigned long long)getpid()); -#endif - const char* args[] = {VisiGenPath.c_str(), - visiIntOut.getAbsolutePath().data(), - preVisiPath.getAbsolutePath().data(), - thrIdx.c_str(), - parPid.c_str(), - nullptr}; - if (0 == hecl::RunProcess(VisiGenPath.c_str(), args)) { - athena::io::FileReader r(preVisiPath.getAbsolutePath()); - size_t length = r.length(); - secs.emplace_back(length, 0); - r.readBytesToBuf(secs.back().data(), length); - visiGood = true; - } else { - Log.report(logvisor::Fatal, FMT_STRING("Unable to launch {}"), VisiGenPath); - } - } -#endif -#endif - } - } - if (!visiGood) - secs.emplace_back(4, 0); - - /* PATH */ - { - const hecl::ProjectPath pathPath = GetPathBeginsWith(inPath.getParentPath(), "!path"); - UniqueID32 pathId; - if (pathPath.isFile()) - pathId = pathPath; - secs.emplace_back(4, 0); - athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); - pathId.write(w); - } - - /* Assemble sizes and add padding */ - { - std::vector& sizesSec = secs[1]; - sizesSec.assign((((head.secCount) + 7) & ~7) * 4, 0); - athena::io::MemoryWriter w(sizesSec.data(), sizesSec.size()); - for (auto it = secs.begin() + 2; it != secs.end(); ++it) { - std::vector& sec = *it; - int i = sec.size(); - int end = ROUND_UP_32(i); - sec.resize(end); - w.writeUint32Big(end); - } - } - - /* Output all padded sections to file */ - athena::io::FileWriter writer(outPath.getAbsolutePath()); - for (const std::vector& sec : secs) - writer.writeUBytes(sec.data(), sec.size()); - - return true; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/MREA.hpp b/DataSpec/DNAMP1/MREA.hpp deleted file mode 100644 index d0c0b46e5..000000000 --- a/DataSpec/DNAMP1/MREA.hpp +++ /dev/null @@ -1,113 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "CMDLMaterials.hpp" -#include "CSKR.hpp" - -namespace DataSpec::DNAMP1 { - -struct MREA { - struct Header : BigDNA { - AT_DECL_DNA - Value magic; - Value version; - Value localToWorldMtx[3]; - Value meshCount; - Value secCount; - Value geomSecIdx; - Value sclySecIdx; - Value collisionSecIdx; - Value unkSecIdx; - Value lightSecIdx; - Value visiSecIdx; - Value pathSecIdx; - Value arotSecIdx; - Vector secSizes; - }; - - struct MeshHeader : BigDNA { - AT_DECL_DNA - struct VisorFlags : BigDNA { - AT_DECL_DNA - Value flags; - enum class ThermalLevel { Cool, Hot, Warm }; - static const char* GetThermalLevelStr(ThermalLevel t) { - switch (t) { - case ThermalLevel::Cool: - return "COOL"; - case ThermalLevel::Hot: - return "HOT"; - case ThermalLevel::Warm: - return "WARM"; - default: - break; - } - return nullptr; - } - bool disableEnviro() const { return flags >> 1 & 0x1; } - void setDisableEnviro(bool v) { - flags &= ~0x2; - flags |= v << 1; - } - bool disableThermal() const { return flags >> 2 & 0x1; } - void setDisableThermal(bool v) { - flags &= ~0x4; - flags |= v << 2; - } - bool disableXray() const { return flags >> 3 & 0x1; } - void setDisableXray(bool v) { - flags &= ~0x8; - flags |= v << 3; - } - ThermalLevel thermalLevel() const { return ThermalLevel(flags >> 4 & 0x3); } - void setThermalLevel(ThermalLevel v) { - flags &= ~0x30; - flags |= atUint32(v) << 4; - } - const char* thermalLevelStr() const { return GetThermalLevelStr(thermalLevel()); } - void setFromBlenderProps(const std::unordered_map& props); - } visorFlags; - Value xfMtx[3]; - Value aabb[2]; - }; - - struct BabeDeadLight : BigDNA { - AT_DECL_DNA - enum class LightType : atUint32 { LocalAmbient, Directional, Custom, Spot, Spot2, LocalAmbient2 }; - enum class Falloff : atUint32 { Constant, Linear, Quadratic }; - Value lightType; - Value color; - Value position; - Value direction; - Value q; - Value spotCutoff; - Value unk5; - Value castShadows; - Value unk7; - Value falloff; - Value unk9; - }; - - static void ReadBabeDeadToBlender_1_2(hecl::blender::PyOutStream& os, athena::io::IStreamReader& rs); - - static void AddCMDLRigPairs(PAKEntryReadStream& rs, PAKRouter& pakRouter, - CharacterAssociations& charAssoc); - - static UniqueID32 GetPATHId(PAKEntryReadStream& rs); - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool, hecl::blender::Token& btok, - std::function); - - static void Name(const SpecBase& dataSpec, PAKEntryReadStream& rs, PAKRouter& pakRouter, - PAK::Entry& entry); - - using ColMesh = hecl::blender::ColMesh; - using Light = hecl::blender::Light; - - static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, - const std::vector& meshes, const ColMesh& cMesh, const std::vector& lights, - hecl::blender::Token& btok, const hecl::blender::Matrix4f* xf, bool pc); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/MazeSeeds.hpp b/DataSpec/DNAMP1/MazeSeeds.hpp deleted file mode 100644 index d3826b357..000000000 --- a/DataSpec/DNAMP1/MazeSeeds.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include - -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { -struct MazeSeeds : BigDNA { - AT_DECL_DNA_YAML - Value seeds[300]; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/PAK.cpp b/DataSpec/DNAMP1/PAK.cpp deleted file mode 100644 index 2c00da70d..000000000 --- a/DataSpec/DNAMP1/PAK.cpp +++ /dev/null @@ -1,189 +0,0 @@ -#include -#include -#include "DNAMP1.hpp" -#include "PAK.hpp" -#include "AGSC.hpp" -#include "DataSpec/AssetNameMap.hpp" - -namespace DataSpec::DNAMP1 { - -template <> -void PAK::Enumerate(typename Read::StreamT& reader) { - atUint32 version = reader.readUint32Big(); - if (version != 0x00030005) - Log.report(logvisor::Fatal, FMT_STRING("unexpected PAK magic")); - reader.readUint32Big(); - - atUint32 nameCount = reader.readUint32Big(); - m_nameEntries.clear(); - m_nameEntries.reserve(nameCount); - for (atUint32 n = 0; n < nameCount; ++n) { - m_nameEntries.emplace_back(); - m_nameEntries.back().read(reader); - } - - atUint32 count = reader.readUint32Big(); - m_entries.clear(); - m_entries.reserve(count); - m_firstEntries.clear(); - m_firstEntries.reserve(count); - std::vector entries; - entries.reserve(count); - for (atUint32 e = 0; e < count; ++e) { - entries.emplace_back(); - entries.back().read(reader); - } - for (atUint32 e = 0; e < count; ++e) { - Entry& entry = entries[e]; - if (entry.compressed && m_useLzo) - entry.compressed = 2; - - auto search = m_entries.find(entry.id); - if (search == m_entries.end()) { - m_firstEntries.push_back(entry.id); - m_entries[entry.id] = std::move(entry); - } else { - /* Find next MREA to record which area has dupes */ - for (atUint32 e2 = e + 1; e2 < count; ++e2) { - Entry& entry2 = entries[e2]; - if (entry2.type != FOURCC('MREA')) - continue; - m_dupeMREAs.insert(entry2.id); - break; - } - } - } - - m_nameMap.clear(); - m_nameMap.reserve(nameCount); - for (NameEntry& entry : m_nameEntries) - m_nameMap[entry.name] = entry.id; -} - -template <> -void PAK::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(0x00030005); - writer.writeUint32Big(0); - - writer.writeUint32Big((atUint32)m_nameEntries.size()); - for (const NameEntry& entry : m_nameEntries) { - NameEntry copy = entry; - copy.nameLen = copy.name.size(); - copy.write(writer); - } - - writer.writeUint32Big(m_entries.size()); - for (const auto& entry : m_entries) { - Entry tmp = entry.second; - if (tmp.compressed) - tmp.compressed = 1; - tmp.write(writer); - } -} - -template <> -void PAK::Enumerate(typename BinarySize::StreamT& s) { - s += 12; - - for (const NameEntry& entry : m_nameEntries) - s += 12 + entry.name.size(); - - s += m_entries.size() * 20 + 4; -} - -std::unique_ptr PAK::Entry::getBuffer(const nod::Node& pak, atUint64& szOut) const { - if (compressed) { - std::unique_ptr strm = pak.beginReadStream(offset); - - atUint32 decompSz; - strm->read(&decompSz, 4); - decompSz = hecl::SBig(decompSz); - std::unique_ptr buf{new atUint8[decompSz]}; - atUint8* bufCur = buf.get(); - - atUint8 compBuf[0x8000]; - if (compressed == 1) { - atUint32 compRem = size - 4; - z_stream zs = {}; - inflateInit(&zs); - zs.avail_out = decompSz; - zs.next_out = buf.get(); - while (zs.avail_out) { - atUint64 readSz = strm->read(compBuf, std::min(compRem, atUint32(0x8000))); - compRem -= readSz; - zs.avail_in = readSz; - zs.next_in = compBuf; - inflate(&zs, Z_FINISH); - } - inflateEnd(&zs); - } else { - atUint32 rem = decompSz; - while (rem) { - atUint16 chunkSz; - strm->read(&chunkSz, 2); - chunkSz = hecl::SBig(chunkSz); - strm->read(compBuf, chunkSz); - size_t dsz; - lzokay::decompress(compBuf, chunkSz, bufCur, rem, dsz); - bufCur += dsz; - rem -= dsz; - } - } - - szOut = decompSz; - return buf; - } else { - std::unique_ptr buf{new atUint8[size]}; - pak.beginReadStream(offset)->read(buf.get(), size); - szOut = size; - return buf; - } -} - -const PAK::Entry* PAK::lookupEntry(const UniqueID32& id) const { - auto result = m_entries.find(id); - if (result != m_entries.end()) - return &result->second; - return nullptr; -} - -const PAK::Entry* PAK::lookupEntry(std::string_view name) const { - // TODO: Heterogeneous lookup when C++20 available - auto result = m_nameMap.find(name.data()); - if (result != m_nameMap.end()) { - auto result1 = m_entries.find(result->second); - if (result1 != m_entries.end()) - return &result1->second; - } - return nullptr; -} - -std::string PAK::bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const { - std::unordered_map::const_iterator search; - if (entry.type == FOURCC('AGSC') && (search = m_entries.find(entry.id)) != m_entries.cend()) { - /* Use internal AGSC name for entry */ - auto rs = search->second.beginReadStream(pakNode); - AGSC::Header header; - header.read(rs); - catalogueName = header.groupName; - return fmt::format(FMT_STRING("{}_{}"), header.groupName, entry.id); - } - - /* Prefer named entries first */ - for (const NameEntry& nentry : m_nameEntries) { - if (nentry.id == entry.id) { - catalogueName = nentry.name; - return fmt::format(FMT_STRING("{}_{}"), nentry.name, entry.id); - } - } - - /* Prefer asset name map second */ - if (const auto* name = AssetNameMap::TranslateIdToName(entry.id)) { - return fmt::format(FMT_STRING("{}_{}"), *name, entry.id); - } - - /* Otherwise return ID format string */ - return fmt::format(FMT_STRING("{}_{}"), entry.type, entry.id); -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/PAK.hpp b/DataSpec/DNAMP1/PAK.hpp deleted file mode 100644 index 0d2362ad6..000000000 --- a/DataSpec/DNAMP1/PAK.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include - -#include -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAMP1 { - -struct PAK : BigDNA { - bool m_useLzo; - bool m_noShare; - PAK(bool useLzo, bool noShare) : m_useLzo(useLzo), m_noShare(noShare) {} - AT_DECL_EXPLICIT_DNA - - struct NameEntry : BigDNA { - AT_DECL_DNA - DNAFourCC type; - UniqueID32 id; - Value nameLen; - String name; - }; - - struct Entry : BigDNA { - AT_DECL_DNA - Value compressed; - DNAFourCC type; - UniqueID32 id; - Value size; - Value offset; - UniqueResult unique; - std::string name; /* backreferencing name for RE purposes */ - - std::unique_ptr getBuffer(const nod::Node& pak, atUint64& szOut) const; - inline PAKEntryReadStream beginReadStream(const nod::Node& pak, atUint64 off = 0) const { - atUint64 sz; - std::unique_ptr buf = getBuffer(pak, sz); - return PAKEntryReadStream(std::move(buf), sz, off); - } - }; - - std::vector m_nameEntries; - std::unordered_map m_entries; - std::vector m_firstEntries; - std::unordered_map m_nameMap; - std::unordered_set m_dupeMREAs; - - const Entry* lookupEntry(const UniqueID32& id) const; - const Entry* lookupEntry(std::string_view name) const; - std::string bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const; - - bool mreaHasDupeResources(const UniqueID32& id) const { return m_dupeMREAs.find(id) != m_dupeMREAs.cend(); } - - using IDType = UniqueID32; -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/PATH.hpp b/DataSpec/DNAMP1/PATH.hpp deleted file mode 100644 index 07f0179f8..000000000 --- a/DataSpec/DNAMP1/PATH.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include "DataSpec/DNACommon/PATH.hpp" - -namespace DataSpec::DNAMP1 { -using PATH = DNAPATH::PATH; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/SAVW.hpp b/DataSpec/DNAMP1/SAVW.hpp deleted file mode 100644 index 54e52bbaf..000000000 --- a/DataSpec/DNAMP1/SAVW.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/SAVWCommon.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { -struct Scan : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 scanId; - Value category; - - Scan() = default; - Scan(const UniqueID32& id) : scanId(id), category(SAVWCommon::EScanCategory::None) {} -}; - -struct SAVW : BigDNA { - AT_DECL_DNA_YAML - SAVWCommon::Header header; - Value skippableCutsceneCount; - Vector skippableCutscenes; - Value relayCount; - Vector relays; - Value layerCount; - Vector layers; - Value doorCount; - Vector doors; - Value scanCount; - Vector scans; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/SCAN.cpp b/DataSpec/DNAMP1/SCAN.cpp deleted file mode 100644 index 5fa82ce7c..000000000 --- a/DataSpec/DNAMP1/SCAN.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "SCAN.hpp" - -#include -#include - -namespace DataSpec::DNAMP1 { - -constexpr std::array PaneNames{ - "imagepane_pane0"sv, "imagepane_pane1"sv, "imagepane_pane2"sv, "imagepane_pane3"sv, "imagepane_pane01"sv, - "imagepane_pane12"sv, "imagepane_pane23"sv, "imagepane_pane012"sv, "imagepane_pane123"sv, "imagepane_pane0123"sv, - "imagepane_pane4"sv, "imagepane_pane5"sv, "imagepane_pane6"sv, "imagepane_pane7"sv, "imagepane_pane45"sv, - "imagepane_pane56"sv, "imagepane_pane67"sv, "imagepane_pane456"sv, "imagepane_pane567"sv, "imagepane_pane4567"sv, -}; - -template <> -void SCAN::Texture::Enumerate(typename Read::StreamT& r) { - texture.read(r); - appearanceRange = r.readFloatBig(); - position = Position(r.readUint32Big()); - width = r.readUint32Big(); - height = r.readUint32Big(); - interval = r.readFloatBig(); - fadeDuration = r.readFloatBig(); -} - -template <> -void SCAN::Texture::Enumerate(typename Write::StreamT& w) { - texture.write(w); - w.writeFloatBig(appearanceRange); - w.writeUint32Big(atUint32(position)); - w.writeUint32Big(width); - w.writeUint32Big(height); - w.writeFloatBig(interval); - w.writeFloatBig(fadeDuration); -} - -template <> -void SCAN::Texture::Enumerate(typename ReadYaml::StreamT& r) { - r.enumerate("texture", texture); - appearanceRange = r.readFloat("appearanceRange"); - std::string tmp = r.readString("position"); - - auto idx = std::find(PaneNames.begin(), PaneNames.end(), tmp); - if (idx != PaneNames.end()) - position = Position(idx - PaneNames.begin()); - else - position = Position::Invalid; - - width = r.readUint32("width"); - height = r.readUint32("height"); - interval = r.readFloat("interval"); - fadeDuration = r.readFloat("fadeDuration"); -} - -template <> -void SCAN::Texture::Enumerate(typename WriteYaml::StreamT& w) { - w.enumerate("texture", texture); - w.writeFloat("appearanceRange", appearanceRange); - if (position != Position::Invalid) - w.writeString("position", PaneNames.at(atUint32(position))); - else - w.writeString("position", "undefined"); - w.writeUint32("width", width); - w.writeUint32("height", height); - w.writeFloat("interval", interval); - w.writeFloat("fadeDuration", fadeDuration); -} - -std::string_view SCAN::Texture::DNAType() { return "DNAMP1::SCAN::Texture"sv; } - -template <> -void SCAN::Texture::Enumerate(typename BinarySize::StreamT& s) { - texture.binarySize(s); - s += 24; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/SCAN.hpp b/DataSpec/DNAMP1/SCAN.hpp deleted file mode 100644 index f806fe69d..000000000 --- a/DataSpec/DNAMP1/SCAN.hpp +++ /dev/null @@ -1,109 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { -struct SCAN : BigDNA { - AT_DECL_DNA_YAML - Value version; - Value magic; - UniqueID32 frame; - UniqueID32 string; - - enum class ScanSpeed : atUint32 { Normal, Slow }; - Value scanSpeed; - - enum class Category : atUint32 { None, SpacePirateData, ChozoLore, Creatures, Research }; - - Value category; - - Value isImportant; - - struct Texture : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - UniqueID32 texture; - Value appearanceRange; - enum class Position : atInt32 { - Pane0, - Pane1, - Pane2, - Pane3, - Pane01, - Pane12, - Pane23, - Pane012, - Pane123, - Pane0123, - Pane4, - Pane5, - Pane6, - Pane7, - Pane45, - Pane56, - Pane67, - Pane456, - Pane567, - Pane4567, - Invalid = -1 - }; - Value position; - Value width; // width of animation cell - Value height; // height of animation cell - Value interval; // 0.0 - 1.0 - Value fadeDuration; // 0.0 - 1.0 - }; - - Texture textures[4]; - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - SCAN scan; - scan.read(rs); - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(scan, writer); - return true; - } - - static bool Cook(const SCAN& scan, const hecl::ProjectPath& outPath) { - athena::io::FileWriter ws(outPath.getAbsolutePath()); - scan.write(ws); - return true; - } - - static Category GetCategory(const hecl::ProjectPath& inPath) { - SCAN scan; - athena::io::FileReader reader(inPath.getAbsolutePath()); - if (reader.hasError()) - return Category::None; - if (!athena::io::FromYAMLStream(scan, reader)) - return Category::None; - return scan.category; - } - - static void Name(const SpecBase& dataSpec, PAKEntryReadStream& rs, PAKRouter& pakRouter, - PAK::Entry& entry) { - SCAN scan; - scan.read(rs); - if (scan.string.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(scan.string); - ent->name = fmt::format(FMT_STRING("SCAN_{}_strg"), entry.id); - } - for (int i = 0; i < 4; ++i) { - const Texture& tex = scan.textures[i]; - if (tex.texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(tex.texture); - ent->name = fmt::format(FMT_STRING("SCAN_{}_tex{}"), entry.id, i + 1); - } - } - } - - void gatherDependencies(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(frame, pathsOut); - g_curSpec->flattenDependencies(string, pathsOut); - for (int i = 0; i < 4; ++i) - g_curSpec->flattenDependencies(textures[i].texture, pathsOut); - } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/SCLY.cpp b/DataSpec/DNAMP1/SCLY.cpp deleted file mode 100644 index 8ac610788..000000000 --- a/DataSpec/DNAMP1/SCLY.cpp +++ /dev/null @@ -1,198 +0,0 @@ -#include "SCLY.hpp" -#include "ScriptObjects/ScriptTypes.hpp" - -namespace DataSpec::DNAMP1 { - -template <> -void SCLY::Enumerate(athena::io::IStreamReader& rs) { - fourCC.read(rs); - version = rs.readUint32Big(); - layerCount = rs.readUint32Big(); - rs.enumerateBig(layerSizes, layerCount); - atUint32 i = 0; - rs.enumerate(layers, layerCount, [&i, this](athena::io::IStreamReader& rs, ScriptLayer& layer) { - atUint64 start = rs.position(); - layer.read(rs); - rs.seek(start + layerSizes[i++], athena::SeekOrigin::Begin); - }); -} - -template <> -void SCLY::Enumerate(athena::io::IStreamWriter& ws) { - fourCC.write(ws); - ws.writeUint32Big(version); - ws.writeUint32Big(layerCount); - ws.enumerateBig(layerSizes); - ws.enumerate(layers); -} - -template <> -void SCLY::Enumerate(size_t& __isz) { - __isz += 12; - __isz += layerSizes.size() * 4; - for (const ScriptLayer& layer : layers) - layer.binarySize(__isz); -} - -void SCLY::exportToLayerDirectories(const PAK::Entry& entry, PAKRouter& pakRouter, bool force) const { - for (atUint32 i = 0; i < layerCount; i++) { - bool active; - hecl::ProjectPath layerPath = pakRouter.getAreaLayerWorking(entry.id, i, active); - if (layerPath.isNone()) - layerPath.makeDirChain(true); - - if (active) { - const hecl::ProjectPath activePath(layerPath, "!defaultactive"); - [[maybe_unused]] const auto fp = hecl::FopenUnique(activePath.getAbsolutePath().data(), "wb"); - } - - hecl::ProjectPath yamlFile(layerPath, "!objects.yaml"); - if (force || yamlFile.isNone()) { - athena::io::FileWriter writer(yamlFile.getAbsolutePath()); - athena::io::ToYAMLStream(layers[i], writer); - } - } -} - -void SCLY::addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const { - for (const ScriptLayer& layer : layers) - layer.addCMDLRigPairs(pakRouter, charAssoc); -} - -void SCLY::ScriptLayer::addCMDLRigPairs(PAKRouter& pakRouter, - CharacterAssociations& charAssoc) const { - for (const std::unique_ptr& obj : objects) - obj->addCMDLRigPairs(pakRouter, charAssoc); -} - -void SCLY::nameIDs(PAKRouter& pakRouter) const { - for (const ScriptLayer& layer : layers) - layer.nameIDs(pakRouter); -} - -void SCLY::ScriptLayer::nameIDs(PAKRouter& pakRouter) const { - for (const std::unique_ptr& obj : objects) - obj->nameIDs(pakRouter); -} - -template <> -void SCLY::Enumerate(athena::io::YAMLDocReader& docin) { - Do(athena::io::PropId{"fourCC"}, fourCC, docin); - version = docin.readUint32("version"); - layerCount = docin.enumerate("layerSizes", layerSizes); - docin.enumerate("layers", layers); -} - -template <> -void SCLY::Enumerate(athena::io::YAMLDocWriter& docout) { - Do(athena::io::PropId{"fourCC"}, fourCC, docout); - docout.writeUint32("version", version); - docout.enumerate("layerSizes", layerSizes); - docout.enumerate("layers", layers); -} - -std::string_view SCLY::DNAType() { return "DNAMP1::SCLY"sv; } - -template <> -void SCLY::ScriptLayer::Enumerate(athena::io::IStreamReader& rs) { - unknown = rs.readUByte(); - objectCount = rs.readUint32Big(); - objects.clear(); - objects.reserve(objectCount); - for (atUint32 i = 0; i < objectCount; i++) { - atUint8 type = rs.readUByte(); - atUint32 len = rs.readUint32Big(); - atUint64 start = rs.position(); - - auto iter = std::find_if(SCRIPT_OBJECT_DB.begin(), SCRIPT_OBJECT_DB.end(), - [&type](const ScriptObjectSpec* obj) -> bool { return obj->type == type; }); - - if (iter != SCRIPT_OBJECT_DB.end()) { - std::unique_ptr obj((*iter)->loader()); - obj->type = type; - obj->read(rs); - objects.push_back(std::move(obj)); - size_t actualLen = rs.position() - start; - if (actualLen != len) - Log.report(logvisor::Fatal, - FMT_STRING("Error while reading object of type 0x{:02X}, did not read the expected amount of " - "data, read 0x{:x}, expected 0x{:x}"), - (atUint32)type, actualLen, len); - rs.seek(start + len, athena::SeekOrigin::Begin); - } else { - Log.report(logvisor::Fatal, FMT_STRING("Unable to find type 0x{:X} in object database"), - (atUint32)type); - } - } -} - -template <> -void SCLY::ScriptLayer::Enumerate(athena::io::YAMLDocReader& rs) { - unknown = rs.readUByte("unknown"); - size_t objCount; - objects.clear(); - if (auto v = rs.enterSubVector("objects", objCount)) { - objectCount = objCount; - objects.reserve(objCount); - for (atUint32 i = 0; i < objectCount; i++) { - if (auto rec = rs.enterSubRecord()) { - atUint8 type = rs.readUByte("type"); - auto iter = std::find_if(SCRIPT_OBJECT_DB.begin(), SCRIPT_OBJECT_DB.end(), - [&type](const ScriptObjectSpec* obj) -> bool { return obj->type == type; }); - - if (iter != SCRIPT_OBJECT_DB.end()) { - std::unique_ptr obj((*iter)->loader()); - obj->read(rs); - obj->type = type; - objects.push_back(std::move(obj)); - } else - Log.report(logvisor::Fatal, FMT_STRING("Unable to find type 0x{:X} in object database"), - (atUint32)type); - } - } - } else - objectCount = 0; -} - -template <> -void SCLY::ScriptLayer::Enumerate(athena::io::IStreamWriter& ws) { - ws.writeUByte(unknown); - ws.writeUint32Big(objectCount); - for (const std::unique_ptr& obj : objects) { - ws.writeByte(obj->type); - size_t expLen = 0; - obj->binarySize(expLen); - ws.writeUint32Big(expLen); - auto start = ws.position(); - obj->write(ws); - auto wrote = ws.position() - start; - if (wrote != expLen) - Log.report(logvisor::Error, FMT_STRING("expected writing {} byte SCLY obj; wrote {}"), expLen, wrote); - } -} - -template <> -void SCLY::ScriptLayer::Enumerate(size_t& __isz) { - __isz += 5; - for (const std::unique_ptr& obj : objects) { - __isz += 5; - obj->binarySize(__isz); - } -} - -template <> -void SCLY::ScriptLayer::Enumerate(athena::io::YAMLDocWriter& ws) { - ws.writeUByte("unknown", unknown); - if (auto v = ws.enterSubVector("objects")) { - for (const std::unique_ptr& obj : objects) { - if (auto rec = ws.enterSubRecord()) { - ws.writeUByte("type", obj->type); - obj->write(ws); - } - } - } -} - -std::string_view SCLY::ScriptLayer::DNAType() { return "DNAMP1::SCLY::ScriptLayer"sv; } - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/SCLY.hpp b/DataSpec/DNAMP1/SCLY.hpp deleted file mode 100644 index 0104d52d2..000000000 --- a/DataSpec/DNAMP1/SCLY.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "ScriptObjects/IScriptObject.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { -struct SCLY : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - DNAFourCC fourCC; - Value version; - Value layerCount; - - Vector layerSizes; - - struct ScriptLayer : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - Value unknown; - Value objectCount; - Vector, AT_DNA_COUNT(objectCount)> objects; - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const; - void nameIDs(PAKRouter& pakRouter) const; - }; - Vector layers; - - void exportToLayerDirectories(const PAK::Entry&, PAKRouter&, bool) const; - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const; - void nameIDs(PAKRouter& pakRouter) const; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/SFX/Atomic.h b/DataSpec/DNAMP1/SFX/Atomic.h deleted file mode 100644 index 055d91c43..000000000 --- a/DataSpec/DNAMP1/SFX/Atomic.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Atomic - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPAtomic 1 - -#define SFXelu_a_elec_lp_00 42 -#define SFXat2_b_fly_lp_00 43 -#define SFXatm_b_fly_lp_00 44 -#define SFXatm_b_fly_lp_01 45 -#define SFXatm_a_bombdrp_00 46 -#define SFXsfx002F 47 -#define SFXsfx0030 48 -#define SFXsfx0031 49 -#define SFXsfx0032 50 -#define SFXsfx0033 51 -#define SFXsfx0034 52 -#define SFXsfx0035 53 -#define SFXsfx0036 54 -#define SFXsfx0037 55 -#define SFXsfx0038 56 -#define SFXsfx0039 57 -#define SFXsfx003A 58 -#define SFXsfx003B 59 diff --git a/DataSpec/DNAMP1/SFX/BetaBeetle.h b/DataSpec/DNAMP1/SFX/BetaBeetle.h deleted file mode 100644 index 5bc2728cf..000000000 --- a/DataSpec/DNAMP1/SFX/BetaBeetle.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: BetaBeetle - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPBetaBeetle 2 - -#define SFXsfx003C 60 -#define SFXsfx003D 61 -#define SFXsfx003E 62 -#define SFXsfx003F 63 -#define SFXsfx0040 64 -#define SFXsfx0041 65 -#define SFXsfx0042 66 -#define SFXsfx0043 67 -#define SFXsfx0044 68 -#define SFXsfx0045 69 -#define SFXsfx0046 70 -#define SFXsfx0047 71 -#define SFXsfx0048 72 -#define SFXsfx0049 73 -#define SFXsfx004A 74 -#define SFXsfx004B 75 -#define SFXsfx004C 76 -#define SFXsfx004D 77 -#define SFXsfx004E 78 -#define SFXsfx004F 79 -#define SFXsfx0050 80 -#define SFXsfx0051 81 -#define SFXsfx0052 82 -#define SFXsfx0053 83 -#define SFXsfx0054 84 -#define SFXsfx0055 85 -#define SFXsfx0056 86 -#define SFXsfx0057 87 -#define SFXsfx0058 88 -#define SFXsfx0059 89 -#define SFXsfx005A 90 -#define SFXsfx005B 91 diff --git a/DataSpec/DNAMP1/SFX/Bird.h b/DataSpec/DNAMP1/SFX/Bird.h deleted file mode 100644 index c58f7c470..000000000 --- a/DataSpec/DNAMP1/SFX/Bird.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Bird - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPBird 3 - -#define SFXsfx005C 92 -#define SFXsfx005D 93 -#define SFXsfx005E 94 -#define SFXsfx005F 95 -#define SFXsfx0060 96 -#define SFXsfx0061 97 -#define SFXsfx0062 98 diff --git a/DataSpec/DNAMP1/SFX/BloodFlower.h b/DataSpec/DNAMP1/SFX/BloodFlower.h deleted file mode 100644 index 3fa8e974c..000000000 --- a/DataSpec/DNAMP1/SFX/BloodFlower.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: BloodFlower - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPBloodFlower 4 - -#define SFXblf_a_btmspit_00 99 -#define SFXblf_a_bulb_00 100 -#define SFXsfx0065 101 -#define SFXsfx0066 102 -#define SFXsfx0067 103 -#define SFXblf_b_active_00 104 -#define SFXblf_b_active_01 105 -#define SFXsfx006A 106 -#define SFXblf_b_breathe_00 107 -#define SFXsfx006C 108 -#define SFXsfx006D 109 -#define SFXsfx006E 110 -#define SFXsfx006F 111 -#define SFXblf_r_death_00 112 -#define SFXblf_r_death_01 113 -#define SFXblf_r_impact_00 114 -#define SFXfir_x_crispfire6voice_lp_00 115 -#define SFXsfx0074 116 -#define SFXsfx0075 117 -#define SFXsfx0076 118 -#define SFXsfx0077 119 diff --git a/DataSpec/DNAMP1/SFX/Burrower.h b/DataSpec/DNAMP1/SFX/Burrower.h deleted file mode 100644 index b7cb10005..000000000 --- a/DataSpec/DNAMP1/SFX/Burrower.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Burrower - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPBurrower 5 - -#define SFXbur_a_attack_00 120 -#define SFXbur_b_burrow_lp_00 121 -#define SFXbur_b_idle_00 122 -#define SFXbur_b_idle_01 123 -#define SFXbur_b_walk_00 124 -#define SFXbur_b_walk_01 125 -#define SFXbur_b_walk_02 126 -#define SFXbur_r_death_00 127 -#define SFXsfx0080 128 -#define SFXsfx0081 129 -#define SFXsfx0082 130 -#define SFXsfx0083 131 -#define SFXsfx0084 132 -#define SFXsfx0085 133 -#define SFXsfx0086 134 -#define SFXsfx0087 135 -#define SFXsfx0088 136 -#define SFXsfx0089 137 -#define SFXsfx008A 138 -#define SFXsfx008B 139 diff --git a/DataSpec/DNAMP1/SFX/CMakeLists.txt b/DataSpec/DNAMP1/SFX/CMakeLists.txt deleted file mode 100644 index c0de54e48..000000000 --- a/DataSpec/DNAMP1/SFX/CMakeLists.txt +++ /dev/null @@ -1,79 +0,0 @@ -unset(DNAMP1_SFX_SOURCES) -macro(add_sfx_header HEADER SYMBOL) - bintoc("DNAMP1/SFX/${SYMBOL}.cpp" "DNAMP1/SFX/${HEADER}" "${SYMBOL}") - list(APPEND DNAMP1_SFX_SOURCES "DNAMP1/SFX/${SYMBOL}.cpp" "DNAMP1/SFX/${HEADER}") -endmacro(add_sfx_header) - -add_sfx_header(Atomic.h Atomic_H) -add_sfx_header(BetaBeetle.h BetaBeetle_H) -add_sfx_header(Bird.h Bird_H) -add_sfx_header(BloodFlower.h BloodFlower_H) -add_sfx_header(Burrower.h Burrower_H) -add_sfx_header(ChozoGhost.h ChozoGhost_H) -add_sfx_header(ChubbWeed.h ChubbWeed_H) -add_sfx_header(CineBoots.h CineBoots_H) -add_sfx_header(CineGeneral.h CineGeneral_H) -add_sfx_header(CineGun.h CineGun_H) -add_sfx_header(CineMorphball.h CineMorphball_H) -add_sfx_header(CineSuit.h CineSuit_H) -add_sfx_header(CineVisor.h CineVisor_H) -add_sfx_header(Crater.h Crater_H) -add_sfx_header(Crystallite.h Crystallite_H) -add_sfx_header(Drones.h Drones_H) -add_sfx_header(EliteSpacePirate.h EliteSpacePirate_H) -add_sfx_header(FireFlea.h FireFlea_H) -add_sfx_header(Flaaghra.h Flaaghra_H) -add_sfx_header(FlickerBat.h FlickerBat_H) -add_sfx_header(FlyingPirate.h FlyingPirate_H) -add_sfx_header(FrontEnd.h FrontEnd_H) -add_sfx_header(GagantuanBeatle.h GagantuanBeatle_H) -add_sfx_header(Gnats.h Gnats_H) -add_sfx_header(Gryzbee.h Gryzbee_H) -add_sfx_header(IceCrack.h IceCrack_H) -add_sfx_header(IceWorld.h IceWorld_H) -add_sfx_header(InjuredPirates.h InjuredPirates_H) -add_sfx_header(IntroBoss.h IntroBoss_H) -add_sfx_header(IntroWorld.h IntroWorld_H) -add_sfx_header(JellyZap.h JellyZap_H) -add_sfx_header(LavaWorld.h LavaWorld_H) -add_sfx_header(Magdolite.h Magdolite_H) -add_sfx_header(Metaree.h Metaree_H) -add_sfx_header(MetroidPrime.h MetroidPrime_H) -add_sfx_header(Metroid.h Metroid_H) -add_sfx_header(MinesWorld.h MinesWorld_H) -add_sfx_header(MiscSamus.h MiscSamus_H) -add_sfx_header(Misc.h Misc_H) -add_sfx_header(OmegaPirate.h OmegaPirate_H) -add_sfx_header(OverWorld.h OverWorld_H) -add_sfx_header(Parasite.h Parasite_H) -add_sfx_header(PhazonGun.h PhazonGun_H) -add_sfx_header(Phazon.h Phazon_H) -add_sfx_header(PuddleSpore.h PuddleSpore_H) -add_sfx_header(PuddleToad.h PuddleToad_H) -add_sfx_header(Puffer.h Puffer_H) -add_sfx_header(ReactorDoor.h ReactorDoor_H) -add_sfx_header(Ridley.h Ridley_H) -add_sfx_header(Ripper.h Ripper_H) -add_sfx_header(RuinsWorld.h RuinsWorld_H) -add_sfx_header(SamusShip.h SamusShip_H) -add_sfx_header(Scarab.h Scarab_H) -add_sfx_header(Seedling.h Seedling_H) -add_sfx_header(SheeGoth.h SheeGoth_H) -add_sfx_header(SnakeWeed.h SnakeWeed_H) -add_sfx_header(Sova.h Sova_H) -add_sfx_header(SpacePirate.h SpacePirate_H) -add_sfx_header(SpankWeed.h SpankWeed_H) -add_sfx_header(Thardus.h Thardus_H) -add_sfx_header(TheEnd.h TheEnd_H) -add_sfx_header(Torobyte.h Torobyte_H) -add_sfx_header(Triclops.h Triclops_H) -add_sfx_header(Turret.h Turret_H) -add_sfx_header(UI.h UI_H) -add_sfx_header(WarWasp.h WarWasp_H) -add_sfx_header(Weapons.h Weapons_H) -add_sfx_header(ZZZ.h ZZZ_H) -add_sfx_header(Zoomer.h Zoomer_H) -add_sfx_header(lumigek.h lumigek_H) -add_sfx_header(test.h test_H) - -list(APPEND DNAMP1_SFX_SOURCES "DNAMP1/SFX/SFX.h") diff --git a/DataSpec/DNAMP1/SFX/ChozoGhost.h b/DataSpec/DNAMP1/SFX/ChozoGhost.h deleted file mode 100644 index 33bddf359..000000000 --- a/DataSpec/DNAMP1/SFX/ChozoGhost.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: ChozoGhost - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPChozoGhost 6 - -#define SFXchg_a_dball_00 140 -#define SFXchg_a_dcharge_00 141 -#define SFXchg_a_dfire_00 142 -#define SFXsfx008F 143 -#define SFXsfx0090 144 -#define SFXsfx0091 145 -#define SFXsfx0092 146 -#define SFXsfx0093 147 -#define SFXsfx0094 148 -#define SFXchg_a_pball_00 149 -#define SFXchg_a_pfire_00 150 -#define SFXsfx0097 151 -#define SFXsfx0098 152 -#define SFXsfx0099 153 -#define SFXsfx009A 154 -#define SFXchg_b_fadein_00 155 -#define SFXsfx009C 156 -#define SFXchg_b_float_00 157 -#define SFXchg_b_growl_00 158 -#define SFXchg_b_jump_00 159 -#define SFXsfx00A0 160 -#define SFXsfx00A1 161 -#define SFXsfx00A2 162 -#define SFXsfx00A3 163 -#define SFXsfx00A4 164 -#define SFXchg_r_death_00 165 -#define SFXchg_r_hit_00 166 -#define SFXchg_a_pcharge_00 167 -#define SFXsfx00A8 168 -#define SFXsfx00A9 169 -#define SFXchg_b_growl_01 170 -#define SFXchg_b_scrape_00 171 -#define SFXchg_r_death_01 172 -#define SFXsfx00AD 173 -#define SFXchg_b_growl_03 174 -#define SFXchg_b_growl_04 175 -#define SFXsfx00B0 176 -#define SFXchg_b_voxalert_00 177 -#define SFXsfx00B2 178 -#define SFXchg_b_warpin_00 179 -#define SFXsfx00B4 180 -#define SFXsfx00B5 181 -#define SFXsfx00B6 182 -#define SFXsfx00B7 183 -#define SFXsfx00B8 184 -#define SFXsfx00B9 185 -#define SFXsfx00BA 186 -#define SFXsfx00BB 187 -#define SFXsfx00BC 188 -#define SFXsfx00BD 189 -#define SFXsfx00BE 190 -#define SFXsfx00BF 191 diff --git a/DataSpec/DNAMP1/SFX/ChubbWeed.h b/DataSpec/DNAMP1/SFX/ChubbWeed.h deleted file mode 100644 index 3f33f7989..000000000 --- a/DataSpec/DNAMP1/SFX/ChubbWeed.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: ChubbWeed - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPChubbWeed 7 - -#define SFXchb_r_scream_00 192 -#define SFXchb_r_alert_00_lp 193 -#define SFXsfx00C2 194 -#define SFXsfx00C3 195 -#define SFXsfx00C4 196 -#define SFXsfx00C5 197 -#define SFXsfx00C6 198 diff --git a/DataSpec/DNAMP1/SFX/CineBoots.h b/DataSpec/DNAMP1/SFX/CineBoots.h deleted file mode 100644 index 5109d62ad..000000000 --- a/DataSpec/DNAMP1/SFX/CineBoots.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: CineBoots - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPCineBoots 59 - -#define SFXci7_x_jump_00 2972 -#define SFXsja_c_electric_lp_00 2973 -#define SFXsfx0B9E 2974 -#define SFXsfx0B9F 2975 -#define SFXsfx0BA0 2976 -#define SFXsfx0BA1 2977 -#define SFXsfx0BA2 2978 -#define SFXsfx0BA3 2979 -#define SFXsfx0BA4 2980 -#define SFXsfx0BA5 2981 -#define SFXsfx0BA6 2982 -#define SFXsfx0BA7 2983 -#define SFXsfx0BA8 2984 -#define SFXsfx0BA9 2985 -#define SFXsfx0BAA 2986 -#define SFXsfx0BAB 2987 -#define SFXsfx0BAC 2988 -#define SFXsfx0BAD 2989 -#define SFXsfx0BAE 2990 -#define SFXsfx0BAF 2991 diff --git a/DataSpec/DNAMP1/SFX/CineGeneral.h b/DataSpec/DNAMP1/SFX/CineGeneral.h deleted file mode 100644 index 6edef7c24..000000000 --- a/DataSpec/DNAMP1/SFX/CineGeneral.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: CineGeneral - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPCineGeneral 60 - -#define SFXsfx0BB0 2992 -#define SFXsfx0BB1 2993 -#define SFXci5_x_mapdown_00 2994 -#define SFXci5_x_mapload_lp_00 2995 -#define SFXci5_x_mapspin_lp_00 2996 -#define SFXci5_x_mapup_00 2997 -#define SFXepr_b_grenup_00 2998 -#define SFXpi2_x_missile_00 2999 -#define SFXpi2_x_healthsm_00 3000 -#define SFXpi2_x_smissile_00 3001 -#define SFXsfx0BBA 3002 -#define SFXsfx0BBB 3003 -#define SFXsfx0BBC 3004 -#define SFXsfx0BBD 3005 -#define SFXci9_x_nrg_lp_00 3006 -#define SFXsfx0BBF 3007 -#define SFXci9_x_insert_00 3008 -#define SFXsfx0BC1 3009 -#define SFXsfx0BC2 3010 -#define SFXsfx0BC3 3011 -#define SFXsfx0BC4 3012 -#define SFXsfx0BC5 3013 -#define SFXsfx0BC6 3014 -#define SFXsfx0BC7 3015 -#define SFXsfx0BC8 3016 -#define SFXsfx0BC9 3017 -#define SFXsfx0BCA 3018 -#define SFXsfx0BCB 3019 -#define SFXsfx0BCC 3020 -#define SFXsfx0BCD 3021 -#define SFXsfx0BCE 3022 -#define SFXsfx0BCF 3023 -#define SFXsfx0BD0 3024 -#define SFXsfx0BD1 3025 -#define SFXsfx0BD2 3026 -#define SFXsfx0BD3 3027 -#define SFXsfx0BD4 3028 -#define SFXsfx0BD5 3029 -#define SFXsfx0BD6 3030 -#define SFXsfx0BD7 3031 -#define SFXsfx0BD8 3032 diff --git a/DataSpec/DNAMP1/SFX/CineGun.h b/DataSpec/DNAMP1/SFX/CineGun.h deleted file mode 100644 index 37e176a80..000000000 --- a/DataSpec/DNAMP1/SFX/CineGun.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: CineGun - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPCineGun 62 - -#define SFXsfx0BE5 3045 -#define SFXci3_x_clank_00 3046 -#define SFXci4_x_clank_00 3047 -#define SFXsfx0BE8 3048 -#define SFXci3_c_ridiclaw_00 3049 -#define SFXsfx0BEA 3050 -#define SFXsfx0BEB 3051 -#define SFXsfx0BEC 3052 -#define SFXsfx0BED 3053 -#define SFXsfx0BEE 3054 -#define SFXsfx0BEF 3055 -#define SFXsfx0BF0 3056 -#define SFXsfx0BF1 3057 -#define SFXsfx0BF2 3058 diff --git a/DataSpec/DNAMP1/SFX/CineMorphball.h b/DataSpec/DNAMP1/SFX/CineMorphball.h deleted file mode 100644 index 862a9be10..000000000 --- a/DataSpec/DNAMP1/SFX/CineMorphball.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: CineMorphball - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPCineMorphball 63 - -#define SFXsfx0BF3 3059 -#define SFXsfx0BF4 3060 -#define SFXsfx0BF5 3061 -#define SFXsfx0BF6 3062 -#define SFXsfx0BF7 3063 -#define SFXsfx0BF8 3064 -#define SFXsfx0BF9 3065 -#define SFXsfx0BFA 3066 -#define SFXsfx0BFB 3067 -#define SFXsfx0BFC 3068 diff --git a/DataSpec/DNAMP1/SFX/CineSuit.h b/DataSpec/DNAMP1/SFX/CineSuit.h deleted file mode 100644 index fda09dc9c..000000000 --- a/DataSpec/DNAMP1/SFX/CineSuit.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: CineSuit - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPCineSuit 64 - -#define SFXci2_x_energy_lp_00 3069 -#define SFXci2_x_energy_lp_01 3070 -#define SFXsfx0BFF 3071 -#define SFXsfx0C00 3072 -#define SFXci2_x_jump_00 3073 -#define SFXsfx0C02 3074 -#define SFXci2_x_lights_lp_00 3075 -#define SFXci2_x_pad_lp_00 3076 -#define SFXsfx0C05 3077 -#define SFXsfx0C06 3078 -#define SFXci3_x_energy_02 3079 -#define SFXsfx0C08 3080 -#define SFXsfx0C09 3081 -#define SFXci3_x_whoosh_00 3082 -#define SFXsfx0C0B 3083 -#define SFXsfx0C0C 3084 -#define SFXsfx0C0D 3085 -#define SFXsfx0C0E 3086 -#define SFXsfx0C0F 3087 -#define SFXsfx0C10 3088 -#define SFXsfx0C11 3089 -#define SFXsfx0C12 3090 -#define SFXsfx0C13 3091 -#define SFXsfx0C14 3092 -#define SFXsfx0C15 3093 diff --git a/DataSpec/DNAMP1/SFX/CineVisor.h b/DataSpec/DNAMP1/SFX/CineVisor.h deleted file mode 100644 index ad8fe85ac..000000000 --- a/DataSpec/DNAMP1/SFX/CineVisor.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: CineVisor - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPCineVisor 61 - -#define SFXcin_x_visor_00 3033 -#define SFXsfx0BDA 3034 -#define SFXsfx0BDB 3035 -#define SFXsfx0BDC 3036 -#define SFXsfx0BDD 3037 -#define SFXsfx0BDE 3038 -#define SFXsfx0BDF 3039 -#define SFXsfx0BE0 3040 -#define SFXsfx0BE1 3041 -#define SFXsfx0BE2 3042 -#define SFXsfx0BE3 3043 -#define SFXsfx0BE4 3044 diff --git a/DataSpec/DNAMP1/SFX/Crater.h b/DataSpec/DNAMP1/SFX/Crater.h deleted file mode 100644 index c7d0d97d5..000000000 --- a/DataSpec/DNAMP1/SFX/Crater.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Crater - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPCrater 44 - -#define SFXsfx0764 1892 -#define SFXsfx0765 1893 -#define SFXsfx0766 1894 -#define SFXsfx0767 1895 -#define SFXsfx0768 1896 -#define SFXsfx0769 1897 -#define SFXsfx076A 1898 -#define SFXsfx076B 1899 -#define SFXsfx076C 1900 -#define SFXsfx076D 1901 -#define SFXsfx076E 1902 -#define SFXsfx076F 1903 -#define SFXsfx0770 1904 -#define SFXsfx0771 1905 -#define SFXsfx0772 1906 -#define SFXsfx0773 1907 -#define SFXsfx0774 1908 -#define SFXsfx0775 1909 -#define SFXsfx0776 1910 -#define SFXsfx0777 1911 -#define SFXsfx0778 1912 -#define SFXsfx0779 1913 -#define SFXsfx077A 1914 -#define SFXsfx077B 1915 -#define SFXsfx077C 1916 -#define SFXsfx077D 1917 -#define SFXsfx077E 1918 -#define SFXsfx077F 1919 -#define SFXsfx0780 1920 -#define SFXsfx0781 1921 diff --git a/DataSpec/DNAMP1/SFX/Crystallite.h b/DataSpec/DNAMP1/SFX/Crystallite.h deleted file mode 100644 index f142471ce..000000000 --- a/DataSpec/DNAMP1/SFX/Crystallite.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Crystallite - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPCrystallite 8 - -#define SFXcry_b_idle_00 199 -#define SFXsfx00C8 200 -#define SFXsfx00C9 201 -#define SFXsfx00CA 202 -#define SFXsfx00CB 203 -#define SFXsfx00CC 204 -#define SFXsfx00CD 205 -#define SFXsfx00CE 206 -#define SFXsfx00CF 207 -#define SFXsfx00D0 208 diff --git a/DataSpec/DNAMP1/SFX/Drones.h b/DataSpec/DNAMP1/SFX/Drones.h deleted file mode 100644 index 8f05c4963..000000000 --- a/DataSpec/DNAMP1/SFX/Drones.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Drones - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPDrones 9 - -#define SFXepr_a_shockhit_00 209 -#define SFXsfx00D2 210 -#define SFXdrn_b_burst_00 211 -#define SFXsfx00D4 212 -#define SFXsfx00D5 213 -#define SFXsfx00D6 214 -#define SFXsfx00D7 215 -#define SFXdrn_b_patrol_lp_00 216 -#define SFXdrn_b_henshin_00 217 -#define SFXdrn_b_rocket_lp_00 218 -#define SFXdrn_b_rocket_lp_01 219 -#define SFXdrn_b_rocket_lp_02 220 -#define SFXsfx00DD 221 -#define SFXdrn_r_death_00 222 -#define SFXsfx00DF 223 -#define SFXsfx00E0 224 -#define SFXdrn_r_impact_00 225 -#define SFXsfx00E2 226 -#define SFXdrn_a_blast_00 227 -#define SFXsfx00E4 228 -#define SFXdrn_r_death_lp_00 229 -#define SFXsfx00E6 230 -#define SFXdrn_b_alert_00 231 -#define SFXsfx00E8 232 -#define SFXdrn_a_laser_00 233 -#define SFXsfx00EA 234 -#define SFXsfx00EB 235 -#define SFXsfx00EC 236 -#define SFXsfx00ED 237 -#define SFXdrn_r_impact_01 238 -#define SFXsfx00EF 239 -#define SFXdrn_a_blast_01 240 -#define SFXsfx00F1 241 -#define SFXsfx00F2 242 -#define SFXdrn_b_henshin_01 243 -#define SFXdrn_b_talk_00 244 -#define SFXsfx00F5 245 -#define SFXdrn_r_death_lp_01 246 -#define SFXdrn_a_charge_00 247 -#define SFXdrn_b_beep_03 248 -#define SFXsfx00F9 249 -#define SFXdrn_r_empblast_01 250 -#define SFXsfx00FB 251 -#define SFXsfx00FC 252 -#define SFXdrn_b_patrolun_lp_00 253 -#define SFXdrn_a_laserun_00 254 -#define SFXopr_a_shockhit_00 255 -#define SFXsfx0100 256 -#define SFXsfx0101 257 -#define SFXsfx0102 258 -#define SFXsfx0103 259 -#define SFXsfx0104 260 -#define SFXsfx0105 261 -#define SFXsfx0106 262 -#define SFXsfx0107 263 -#define SFXsfx0108 264 -#define SFXsfx0109 265 -#define SFXsfx010A 266 -#define SFXsfx010B 267 -#define SFXsfx010C 268 diff --git a/DataSpec/DNAMP1/SFX/EliteSpacePirate.h b/DataSpec/DNAMP1/SFX/EliteSpacePirate.h deleted file mode 100644 index 41e0e69aa..000000000 --- a/DataSpec/DNAMP1/SFX/EliteSpacePirate.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: EliteSpacePirate - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPEliteSpacePirate 10 - -#define SFXepr_a_grenade_00 269 -#define SFXsfx010E 270 -#define SFXsfx010F 271 -#define SFXepr_b_hitglass_00 272 -#define SFXepr_a_swoosh_00 273 -#define SFXepr_b_run_00 274 -#define SFXepr_b_run_01 275 -#define SFXepr_a_shokwave_00 276 -#define SFXsfx0115 277 -#define SFXepr_a_attack_00 278 -#define SFXepr_a_attack_01 279 -#define SFXepr_b_land_00 280 -#define SFXepr_b_alert_00 281 -#define SFXepr_b_walk_00 282 -#define SFXepr_b_walk_01 283 -#define SFXepr_b_alert_01 284 -#define SFXepr_b_absorb_lp_00 285 -#define SFXepr_b_idle_00 286 -#define SFXepr_b_idle_01 287 -#define SFXepr_a_hitgrnd_00 288 -#define SFXepr_b_walklite_00 289 -#define SFXepr_b_walklite_01 290 -#define SFXepr_r_pissed_00 291 -#define SFXsfx0124 292 -#define SFXsfx0125 293 -#define SFXepr_a_swoosh_01 294 -#define SFXepr_b_taunt_00 295 -#define SFXopr_a_swoosh_00 296 -#define SFXopr_a_swoosh_01 297 -#define SFXepr_b_blokvox_00 298 -#define SFXsfx012B 299 -#define SFXopr_a_shokwave_00 300 -#define SFXsfx012D 301 -#define SFXopr_b_absorb_lp_00 302 -#define SFXsfx012F 303 -#define SFXsfx0130 304 -#define SFXsfx0131 305 -#define SFXsfx0132 306 -#define SFXsfx0133 307 -#define SFXsfx0134 308 -#define SFXsfx0135 309 -#define SFXsfx0136 310 -#define SFXsfx0137 311 -#define SFXsfx0138 312 -#define SFXsfx0139 313 -#define SFXsfx013A 314 -#define SFXsfx013B 315 -#define SFXsfx013C 316 -#define SFXsfx013D 317 -#define SFXsfx013E 318 -#define SFXsfx013F 319 -#define SFXsfx0140 320 -#define SFXsfx0141 321 -#define SFXsfx0142 322 diff --git a/DataSpec/DNAMP1/SFX/FireFlea.h b/DataSpec/DNAMP1/SFX/FireFlea.h deleted file mode 100644 index 9657afe45..000000000 --- a/DataSpec/DNAMP1/SFX/FireFlea.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: FireFlea - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPFireFlea 11 - -#define SFXfif_b_idle_lp_00 323 -#define SFXsfx0144 324 -#define SFXfif_b_light_00 325 -#define SFXfif_r_death_00 326 -#define SFXfif_r_death_01 327 -#define SFXfif_r_explode_00 328 -#define SFXfif_r_impact_00 329 -#define SFXsfx014A 330 -#define SFXsfx014B 331 -#define SFXsfx014C 332 -#define SFXsfx014D 333 -#define SFXsfx014E 334 -#define SFXsfx014F 335 diff --git a/DataSpec/DNAMP1/SFX/Flaaghra.h b/DataSpec/DNAMP1/SFX/Flaaghra.h deleted file mode 100644 index c7d328a51..000000000 --- a/DataSpec/DNAMP1/SFX/Flaaghra.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Flaaghra - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPFlaaghra 52 - -#define SFXfla_a_hitgrnd_00 2600 -#define SFXfla_a_swoosh_00 2601 -#define SFXfla_a_swoosh_01 2602 -#define SFXfla_a_voxattak_00 2603 -#define SFXfla_a_voxattak_01 2604 -#define SFXfla_b_grow_00 2605 -#define SFXfla_b_idle_00 2606 -#define SFXsfx0A2F 2607 -#define SFXfla_b_voxangry_00 2608 -#define SFXfla_b_voxangry_01 2609 -#define SFXfla_r_death_00 2610 -#define SFXfla_r_death_01 2611 -#define SFXfla_r_death_02 2612 -#define SFXsfx0A35 2613 -#define SFXfla_r_faint_01 2614 -#define SFXfla_r_pain_00 2615 -#define SFXsfx0A38 2616 -#define SFXfla_a_shoot_00 2617 -#define SFXfla_a_spit_00 2618 -#define SFXfla_a_spit_01 2619 -#define SFXsfx0A3C 2620 -#define SFXsfx0A3D 2621 -#define SFXfla_a_charge_00 2622 -#define SFXsfx0A3F 2623 -#define SFXsfx0A40 2624 -#define SFXfla_b_idlesm_00 2625 -#define SFXfla_a_chargevox_00 2626 -#define SFXsfx0A43 2627 -#define SFXsfx0A44 2628 -#define SFXsfx0A45 2629 -#define SFXfla_a_shootvox_00 2630 -#define SFXsfx0A47 2631 -#define SFXsfx0A48 2632 -#define SFXsfx0A49 2633 -#define SFXsfx0A4A 2634 -#define SFXsfx0A4B 2635 -#define SFXfla_a_spitvox_00 2636 -#define SFXfla_a_spitvox_01 2637 -#define SFXsfx0A4E 2638 -#define SFXsfx0A4F 2639 -#define SFXsfx0A50 2640 -#define SFXsfx0A51 2641 -#define SFXsfx0A52 2642 -#define SFXfla_a_sporevox_01 2643 -#define SFXfla_a_hitgrnd_01 2644 -#define SFXsfx0A55 2645 -#define SFXfla_r_landgrnd_00 2646 -#define SFXsfx0A57 2647 -#define SFXsfx0A58 2648 -#define SFXfla_b_grow_01 2649 -#define SFXfla_b_rise_lp_00 2650 -#define SFXsfx0A5B 2651 -#define SFXfla_b_dizzy_00 2652 -#define SFXsfx0A5D 2653 -#define SFXsfx0A5E 2654 -#define SFXfla_r_painsh_00 2655 -#define SFXsfx0A60 2656 -#define SFXfla_b_humor_00 2657 -#define SFXfla_r_painbig_00 2658 -#define SFXfla_b_dizzyout_00 2659 -#define SFXfla_b_faintout_00 2660 -#define SFXsfx0A65 2661 -#define SFXfla_b_dizzy_lp_01 2662 -#define SFXsfx0A67 2663 -#define SFXsfx0A68 2664 -#define SFXsfx0A69 2665 -#define SFXsfx0A6A 2666 -#define SFXfla_b_voxshrnk_00 2667 -#define SFXsfx0A6C 2668 -#define SFXsfx0A6D 2669 -#define SFXfla_b_voxshrnk_03 2670 -#define SFXsfx0A6F 2671 -#define SFXsfx0A70 2672 -#define SFXsfx0A71 2673 -#define SFXsfx0A72 2674 -#define SFXsfx0A73 2675 -#define SFXsfx0A74 2676 -#define SFXsfx0A75 2677 -#define SFXsfx0A76 2678 -#define SFXsfx0A77 2679 -#define SFXsfx0A78 2680 diff --git a/DataSpec/DNAMP1/SFX/FlickerBat.h b/DataSpec/DNAMP1/SFX/FlickerBat.h deleted file mode 100644 index cd0b38c6e..000000000 --- a/DataSpec/DNAMP1/SFX/FlickerBat.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: FlickerBat - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPFlickerBat 12 - -#define SFXflk_b_flicker_00 336 -#define SFXflk_b_talk_00 337 -#define SFXflk_b_talk_01 338 -#define SFXsfx0153 339 -#define SFXsfx0154 340 -#define SFXflk_r_impact_00 341 -#define SFXsfx0156 342 -#define SFXsfx0157 343 -#define SFXsfx0158 344 -#define SFXsfx0159 345 -#define SFXsfx015A 346 -#define SFXsfx015B 347 diff --git a/DataSpec/DNAMP1/SFX/FlyingPirate.h b/DataSpec/DNAMP1/SFX/FlyingPirate.h deleted file mode 100644 index 183c0f297..000000000 --- a/DataSpec/DNAMP1/SFX/FlyingPirate.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: FlyingPirate - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPFlyingPirate 13 - -#define SFXsfx015C 348 -#define SFXfpr_a_chaff_00 349 -#define SFXsfx015E 350 -#define SFXupr_a_mislfire_00 351 -#define SFXsfx0160 352 -#define SFXsfx0161 353 -#define SFXfpr_a_mislfire_00 354 -#define SFXfpr_b_thrust_01 355 -#define SFXsfx0164 356 -#define SFXfpr_b_engine_lp_00 357 -#define SFXfpr_b_engine_lp_01 358 -#define SFXfpr_b_engine_lp_02 359 -#define SFXfpr_b_voxangry_02 360 -#define SFXfpr_b_thrust_00 361 -#define SFXsfx016A 362 -#define SFXfpr_r_die_00 363 -#define SFXfpr_b_intruder_00 364 -#define SFXfpr_b_voxalert_00 365 -#define SFXfpr_a_mislload_00 366 -#define SFXfpr_b_voxangry_00 367 -#define SFXsfx0170 368 -#define SFXfpr_r_impact_00 369 -#define SFXsfx0172 370 -#define SFXsfx0173 371 -#define SFXsfx0174 372 -#define SFXfpr_b_engidle_lp_00 373 -#define SFXsfx0176 374 -#define SFXfpr_b_blastoff_lp_00 375 -#define SFXfpr_b_blastoff_01 376 -#define SFXupr_a_mislload_00 377 -#define SFXupr_b_engidle_lp_00 378 -#define SFXupr_b_engine_lp_00 379 -#define SFXupr_b_engine_lp_01 380 -#define SFXupr_b_engine_lp_02 381 -#define SFXsfx017E 382 -#define SFXsfx017F 383 -#define SFXupr_b_voxalert_00 384 -#define SFXsfx0181 385 -#define SFXupr_b_voxangry_00 386 -#define SFXsfx0183 387 -#define SFXupr_b_voxangry_02 388 -#define SFXupr_r_die_00 389 -#define SFXupr_r_impact_00 390 -#define SFXsfx0187 391 -#define SFXsfx0188 392 -#define SFXsfx0189 393 -#define SFXsfx018A 394 -#define SFXsfx018B 395 -#define SFXsfx018C 396 -#define SFXsfx018D 397 -#define SFXsfx018E 398 -#define SFXsfx018F 399 -#define SFXsfx0190 400 -#define SFXsfx0191 401 -#define SFXsfx0192 402 -#define SFXsfx0193 403 -#define SFXsfx0194 404 -#define SFXsfx0195 405 -#define SFXsfx0196 406 diff --git a/DataSpec/DNAMP1/SFX/FrontEnd.h b/DataSpec/DNAMP1/SFX/FrontEnd.h deleted file mode 100644 index 7aa483660..000000000 --- a/DataSpec/DNAMP1/SFX/FrontEnd.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: FrontEnd - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPFrontEnd 38 - -#define SFXfnt_transfore_00L 1090 -#define SFXfnt_advance_R 1091 -#define SFXsfx0444 1092 -#define SFXfnt_selection_change 1093 -#define SFXfnt_back 1094 -#define SFXfnt_enum_change 1095 -#define SFXfnt_advance_L 1096 -#define SFXfnt_transfore_00R 1097 -#define SFXfnt_transfore_01L 1098 -#define SFXfnt_transfore_01R 1099 -#define SFXfnt_transfore_02L 1100 -#define SFXfnt_transfore_02R 1101 -#define SFXfnt_transback_00L 1102 -#define SFXfnt_transback_00R 1103 -#define SFXfnt_transback_01L 1104 -#define SFXfnt_transback_01R 1105 -#define SFXfnt_transback_02L 1106 -#define SFXfnt_transback_02R 1107 -#define SFXfnt_tofusion_L 1108 -#define SFXfnt_tofusion_R 1109 -#define SFXfnt_fromfusion_L 1110 -#define SFXfnt_fromfusion_R 1111 -#define SFXsfx0458 1112 -#define SFXsfx0459 1113 -#define SFXsfx045A 1114 -#define SFXsfx045B 1115 -#define SFXsfx045C 1116 -#define SFXsfx045D 1117 -#define SFXsfx045E 1118 -#define SFXsfx045F 1119 -#define SFXsfx0460 1120 -#define SFXsfx0461 1121 -#define SFXsfx0462 1122 -#define SFXsfx0463 1123 -#define SFXsfx0464 1124 -#define SFXsfx0465 1125 -#define SFXsfx0466 1126 -#define SFXsfx0467 1127 diff --git a/DataSpec/DNAMP1/SFX/GagantuanBeatle.h b/DataSpec/DNAMP1/SFX/GagantuanBeatle.h deleted file mode 100644 index 3c29321d1..000000000 --- a/DataSpec/DNAMP1/SFX/GagantuanBeatle.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: GagantuanBeatle - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPGagantuanBeatle 14 - -#define SFXgab_r_hitlight_01 407 -#define SFXga2_b_digexplod_00 408 -#define SFXga2_b_digscream_00 409 -#define SFXga2_b_idle_01 410 -#define SFXga2_b_scrapedirt_00 411 -#define SFXgab_b_walkdirt_02 412 -#define SFXgab_b_rundirt_00 413 -#define SFXgab_b_rundirt_01 414 -#define SFXsfx019F 415 -#define SFXgab_a_attack_00 416 -#define SFXgab_a_attack_01 417 -#define SFXgab_b_idle_03 418 -#define SFXgab_b_digexplod_00 419 -#define SFXfla_b_scrapedirt_00 420 -#define SFXgab_b_idle_02 421 -#define SFXgab_b_idle_00 422 -#define SFXgab_b_idle_01 423 -#define SFXgab_b_walkdirt_00 424 -#define SFXgab_b_walkdirt_01 425 -#define SFXgab_r_collide_00 426 -#define SFXsfx01AB 427 -#define SFXgab_r_death_01 428 -#define SFXgab_r_detect_00 429 -#define SFXgab_r_hitlight_00 430 -#define SFXgab_b_digscream_00 431 -#define SFXgab_b_scrapedirt_00 432 -#define SFXga2_b_dig_lp_00 433 -#define SFXga2_b_rundirt_00 434 -#define SFXgab_b_dig_lp_00 435 -#define SFXga2_b_rundirt_01 436 -#define SFXga2_b_rundirt_02 437 -#define SFXga2_b_walkdirt_00 438 -#define SFXga2_b_walkdirt_01 439 -#define SFXga2_b_walkdirt_02 440 -#define SFXga2_r_collide_00 441 -#define SFXga2_a_attack_00 442 -#define SFXsfx01BB 443 -#define SFXsfx01BC 444 -#define SFXsfx01BD 445 -#define SFXsfx01BE 446 -#define SFXsfx01BF 447 -#define SFXsfx01C0 448 -#define SFXsfx01C1 449 -#define SFXsfx01C2 450 -#define SFXsfx01C3 451 -#define SFXsfx01C4 452 -#define SFXsfx01C5 453 -#define SFXsfx01C6 454 -#define SFXsfx01C7 455 -#define SFXsfx01C8 456 -#define SFXsfx01C9 457 -#define SFXsfx01CA 458 diff --git a/DataSpec/DNAMP1/SFX/Gnats.h b/DataSpec/DNAMP1/SFX/Gnats.h deleted file mode 100644 index a704da839..000000000 --- a/DataSpec/DNAMP1/SFX/Gnats.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Gnats - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPGnats 15 - -#define SFXsfx01CB 459 -#define SFXsfx01CC 460 -#define SFXsfx01CD 461 -#define SFXsfx01CE 462 -#define SFXsfx01CF 463 -#define SFXsfx01D0 464 -#define SFXsfx01D1 465 diff --git a/DataSpec/DNAMP1/SFX/Gryzbee.h b/DataSpec/DNAMP1/SFX/Gryzbee.h deleted file mode 100644 index f525e1a01..000000000 --- a/DataSpec/DNAMP1/SFX/Gryzbee.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Gryzbee - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPGryzbee 16 - -#define SFXgrz_b_idle_00 466 -#define SFXsfx01D3 467 -#define SFXsfx01D4 468 -#define SFXsfx01D5 469 -#define SFXsfx01D6 470 -#define SFXsfx01D7 471 -#define SFXsfx01D8 472 -#define SFXsfx01D9 473 -#define SFXsfx01DA 474 -#define SFXsfx01DB 475 -#define SFXsfx01DC 476 -#define SFXsfx01DD 477 diff --git a/DataSpec/DNAMP1/SFX/IceCrack.h b/DataSpec/DNAMP1/SFX/IceCrack.h deleted file mode 100644 index 8ba2aef58..000000000 --- a/DataSpec/DNAMP1/SFX/IceCrack.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: IceCrack - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPIceCrack 67 - -#define SFXsfx0C31 3121 -#define SFXsfx0C32 3122 -#define SFXsfx0C33 3123 -#define SFXsfx0C34 3124 -#define SFXsfx0C35 3125 -#define SFXsfx0C36 3126 -#define SFXcrk_break_subsequent 3127 -#define SFXcrk_break_initial 3128 -#define SFXcrk_break_final 3129 -#define SFXsfx0C3A 3130 -#define SFXsfx0C3B 3131 -#define SFXsfx0C3C 3132 -#define SFXsfx0C3D 3133 -#define SFXsfx0C3E 3134 -#define SFXsfx0C3F 3135 -#define SFXsfx0C40 3136 -#define SFXsfx0C41 3137 -#define SFXsfx0C42 3138 -#define SFXsfx0C43 3139 -#define SFXsfx0C44 3140 diff --git a/DataSpec/DNAMP1/SFX/IceWorld.h b/DataSpec/DNAMP1/SFX/IceWorld.h deleted file mode 100644 index 138ec27c6..000000000 --- a/DataSpec/DNAMP1/SFX/IceWorld.h +++ /dev/null @@ -1,129 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: IceWorld - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPIceWorld 45 - -#define SFXice_x_gateopen_lp_00 1922 -#define SFXice_x_gatestop_00 1923 -#define SFXsfx0784 1924 -#define SFXice_x_towercrk_00 1925 -#define SFXice_ballroll_ice 1926 -#define SFXice_ballroll_snow 1927 -#define SFXsfx0788 1928 -#define SFXice_x_towerlnd_00 1929 -#define SFXsfx078A 1930 -#define SFXice_x_towerlnd_01 1931 -#define SFXice_x_towercrk_01 1932 -#define SFXice_x_towercrk_02 1933 -#define SFXsfx078E 1934 -#define SFXsfx078F 1935 -#define SFXsfx0790 1936 -#define SFXsfx0791 1937 -#define SFXsfx0792 1938 -#define SFXsfx0793 1939 -#define SFXsfx0794 1940 -#define SFXsfx0795 1941 -#define SFXsfx0796 1942 -#define SFXsfx0797 1943 -#define SFXsfx0798 1944 -#define SFXsfx0799 1945 -#define SFXsfx079A 1946 -#define SFXsfx079B 1947 -#define SFXsfx079C 1948 -#define SFXsfx079D 1949 -#define SFXsfx079E 1950 -#define SFXsfx079F 1951 -#define SFXsfx07A0 1952 -#define SFXsfx07A1 1953 -#define SFXsfx07A2 1954 -#define SFXsfx07A3 1955 -#define SFXsfx07A4 1956 -#define SFXsfx07A5 1957 -#define SFXsfx07A6 1958 -#define SFXsfx07A7 1959 -#define SFXsfx07A8 1960 -#define SFXsfx07A9 1961 -#define SFXsfx07AA 1962 -#define SFXsfx07AB 1963 -#define SFXsfx07AC 1964 -#define SFXsfx07AD 1965 -#define SFXsfx07AE 1966 -#define SFXsfx07AF 1967 -#define SFXtha_b_rockup_lp_00 1968 -#define SFXsfx07B1 1969 -#define SFXsfx07B2 1970 -#define SFXice_x_ridflap_00 1971 -#define SFXsfx07B4 1972 -#define SFXsfx07B5 1973 -#define SFXsfx07B6 1974 -#define SFXice_x_pump_00 1975 -#define SFXsfx07B8 1976 -#define SFXsfx07B9 1977 -#define SFXsfx07BA 1978 -#define SFXsfx07BB 1979 -#define SFXsfx07BC 1980 -#define SFXsfx07BD 1981 -#define SFXice_x_piston_00 1982 -#define SFXice_x_piston_lp_00 1983 -#define SFXsfx07C0 1984 -#define SFXsfx07C1 1985 -#define SFXsfx07C2 1986 -#define SFXsfx07C3 1987 -#define SFXsfx07C4 1988 -#define SFXsfx07C5 1989 -#define SFXsfx07C6 1990 -#define SFXsfx07C7 1991 -#define SFXsfx07C8 1992 -#define SFXsfx07C9 1993 -#define SFXtha_b_debris_00 1994 -#define SFXtha_b_debris_01 1995 -#define SFXsfx07CC 1996 -#define SFXsfx07CD 1997 -#define SFXsfx07CE 1998 -#define SFXsfx07CF 1999 -#define SFXsfx07D0 2000 -#define SFXsfx07D1 2001 -#define SFXsfx07D2 2002 -#define SFXsfx07D3 2003 -#define SFXsfx07D4 2004 -#define SFXsfx07D5 2005 -#define SFXsfx07D6 2006 -#define SFXsfx07D7 2007 -#define SFXsfx07D8 2008 -#define SFXsfx07D9 2009 -#define SFXsfx07DA 2010 -#define SFXsfx07DB 2011 -#define SFXsfx07DC 2012 -#define SFXsfx07DD 2013 -#define SFXsfx07DE 2014 -#define SFXsfx07DF 2015 -#define SFXsfx07E0 2016 -#define SFXsfx07E1 2017 -#define SFXsfx07E2 2018 -#define SFXsfx07E3 2019 -#define SFXsfx07E4 2020 -#define SFXsfx07E5 2021 -#define SFXsfx07E6 2022 -#define SFXsfx07E7 2023 -#define SFXsfx07E8 2024 -#define SFXsfx07E9 2025 -#define SFXsfx07EA 2026 -#define SFXsfx07EB 2027 -#define SFXsfx07EC 2028 -#define SFXsfx07ED 2029 -#define SFXsfx07EE 2030 -#define SFXsfx07EF 2031 -#define SFXsfx07F0 2032 -#define SFXsfx07F1 2033 -#define SFXsfx07F2 2034 -#define SFXsfx07F3 2035 -#define SFXsfx07F4 2036 -#define SFXsfx07F5 2037 -#define SFXsfx07F6 2038 -#define SFXsfx07F7 2039 -#define SFXsfx07F8 2040 -#define SFXsfx07F9 2041 diff --git a/DataSpec/DNAMP1/SFX/InjuredPirates.h b/DataSpec/DNAMP1/SFX/InjuredPirates.h deleted file mode 100644 index 3ffa19559..000000000 --- a/DataSpec/DNAMP1/SFX/InjuredPirates.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: InjuredPirates - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPInjuredPirates 17 - -#define SFXsfx01DE 478 -#define SFXsfx01DF 479 -#define SFXspr_b_exhale_00 480 -#define SFXsfx01E1 481 -#define SFXspr_b_moan_00 482 -#define SFXsfx01E3 483 -#define SFXsfx01E4 484 -#define SFXsfx01E5 485 -#define SFXsfx01E6 486 -#define SFXsfx01E7 487 -#define SFXsfx01E8 488 -#define SFXsfx01E9 489 -#define SFXsfx01EA 490 -#define SFXsfx01EB 491 -#define SFXsfx01EC 492 -#define SFXsfx01ED 493 -#define SFXsfx01EE 494 -#define SFXsfx01EF 495 -#define SFXsfx01F0 496 -#define SFXsfx01F1 497 -#define SFXsfx01F2 498 -#define SFXsfx01F3 499 -#define SFXsfx01F4 500 -#define SFXsfx01F5 501 -#define SFXsfx01F6 502 -#define SFXsfx01F7 503 -#define SFXsfx01F8 504 -#define SFXsfx01F9 505 -#define SFXsfx01FA 506 -#define SFXsfx01FB 507 diff --git a/DataSpec/DNAMP1/SFX/IntroBoss.h b/DataSpec/DNAMP1/SFX/IntroBoss.h deleted file mode 100644 index 2f52833bd..000000000 --- a/DataSpec/DNAMP1/SFX/IntroBoss.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: IntroBoss - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPIntroBoss 0 - -#define SFXsfx0000 0 -#define SFXsfx0001 1 -#define SFXsfx0002 2 -#define SFXpaq_a_spit_lp_00 3 -#define SFXpaq_b_squawk_00 4 -#define SFXpaq_b_creak_00 5 -#define SFXpaq_b_creak_01 6 -#define SFXpaq_b_growl_00 7 -#define SFXpaq_b_growl_01 8 -#define SFXpaq_b_land_00 9 -#define SFXpaq_b_roar_00 10 -#define SFXpaq_b_roar_01 11 -#define SFXsfx000C 12 -#define SFXpaq_b_walk_00 13 -#define SFXpaq_b_walk_01 14 -#define SFXpaq_r_impact_00 15 -#define SFXpaq_r_impact_01 16 -#define SFXpaq_r_ldeath_00 17 -#define SFXpaq_r_sdeath_01 18 -#define SFXpaq_b_swish_00 19 -#define SFXsfx0014 20 -#define SFXsfx0015 21 -#define SFXsfx0016 22 -#define SFXpaq_b_land_01 23 -#define SFXpaq_b_run_00 24 -#define SFXpaq_b_run_01 25 -#define SFXsfx001A 26 -#define SFXsfx001B 27 -#define SFXsfx001C 28 -#define SFXsfx001D 29 -#define SFXsfx001E 30 -#define SFXsfx001F 31 -#define SFXsfx0020 32 -#define SFXsfx0021 33 -#define SFXsfx0022 34 -#define SFXsfx0023 35 -#define SFXsfx0024 36 -#define SFXsfx0025 37 -#define SFXsfx0026 38 -#define SFXsfx0027 39 -#define SFXsfx0028 40 -#define SFXsfx0029 41 diff --git a/DataSpec/DNAMP1/SFX/IntroWorld.h b/DataSpec/DNAMP1/SFX/IntroWorld.h deleted file mode 100644 index 02121538d..000000000 --- a/DataSpec/DNAMP1/SFX/IntroWorld.h +++ /dev/null @@ -1,148 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: IntroWorld - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPIntroWorld 46 - -#define SFXsfx07FA 2042 -#define SFXsfx07FB 2043 -#define SFXsfx07FC 2044 -#define SFXsfx07FD 2045 -#define SFXsfx07FE 2046 -#define SFXint_c_suitsprk_lp_01 2047 -#define SFXsfx0800 2048 -#define SFXsfx0801 2049 -#define SFXsfx0802 2050 -#define SFXsfx0803 2051 -#define SFXsfx0804 2052 -#define SFXsfx0805 2053 -#define SFXsfx0806 2054 -#define SFXsfx0807 2055 -#define SFXsfx0808 2056 -#define SFXsfx0809 2057 -#define SFXsfx080A 2058 -#define SFXsfx080B 2059 -#define SFXsfx080C 2060 -#define SFXsfx080D 2061 -#define SFXsfx080E 2062 -#define SFXsfx080F 2063 -#define SFXsfx0810 2064 -#define SFXsfx0811 2065 -#define SFXsfx0812 2066 -#define SFXsfx0813 2067 -#define SFXsfx0814 2068 -#define SFXsfx0815 2069 -#define SFXsfx0816 2070 -#define SFXsfx0817 2071 -#define SFXsfx0818 2072 -#define SFXsfx0819 2073 -#define SFXsfx081A 2074 -#define SFXsfx081B 2075 -#define SFXsfx081C 2076 -#define SFXsfx081D 2077 -#define SFXsfx081E 2078 -#define SFXsfx081F 2079 -#define SFXsfx0820 2080 -#define SFXsfx0821 2081 -#define SFXsfx0822 2082 -#define SFXsfx0823 2083 -#define SFXsfx0824 2084 -#define SFXsfx0825 2085 -#define SFXsfx0826 2086 -#define SFXsfx0827 2087 -#define SFXsfx0828 2088 -#define SFXsfx0829 2089 -#define SFXsfx082A 2090 -#define SFXsfx082B 2091 -#define SFXsfx082C 2092 -#define SFXsfx082D 2093 -#define SFXsfx082E 2094 -#define SFXsfx082F 2095 -#define SFXsfx0830 2096 -#define SFXsfx0831 2097 -#define SFXsfx0832 2098 -#define SFXsfx0833 2099 -#define SFXsfx0834 2100 -#define SFXsfx0835 2101 -#define SFXsfx0836 2102 -#define SFXsfx0837 2103 -#define SFXsfx0838 2104 -#define SFXsfx0839 2105 -#define SFXsfx083A 2106 -#define SFXsfx083B 2107 -#define SFXsfx083C 2108 -#define SFXint_x_frtdoor_00 2109 -#define SFXint_x_frtdoor_01 2110 -#define SFXsfx083F 2111 -#define SFXsfx0840 2112 -#define SFXsfx0841 2113 -#define SFXsfx0842 2114 -#define SFXsfx0843 2115 -#define SFXsfx0844 2116 -#define SFXsfx0845 2117 -#define SFXsfx0846 2118 -#define SFXsfx0847 2119 -#define SFXsfx0848 2120 -#define SFXsfx0849 2121 -#define SFXsfx084A 2122 -#define SFXsfx084B 2123 -#define SFXsfx084C 2124 -#define SFXsfx084D 2125 -#define SFXint_c_suitbrst_01 2126 -#define SFXsfx084F 2127 -#define SFXsfx0850 2128 -#define SFXsfx0851 2129 -#define SFXint_c_shipthst_00 2130 -#define SFXsfx0853 2131 -#define SFXsfx0854 2132 -#define SFXsfx0855 2133 -#define SFXsfx0856 2134 -#define SFXsfx0857 2135 -#define SFXsfx0858 2136 -#define SFXsfx0859 2137 -#define SFXsfx085A 2138 -#define SFXsfx085B 2139 -#define SFXsfx085C 2140 -#define SFXsfx085D 2141 -#define SFXsfx085E 2142 -#define SFXsfx085F 2143 -#define SFXsfx0860 2144 -#define SFXsfx0861 2145 -#define SFXsfx0862 2146 -#define SFXsfx0863 2147 -#define SFXsfx0864 2148 -#define SFXsfx0865 2149 -#define SFXsfx0866 2150 -#define SFXsfx0867 2151 -#define SFXsfx0868 2152 -#define SFXsfx0869 2153 -#define SFXsfx086A 2154 -#define SFXsfx086B 2155 -#define SFXsfx086C 2156 -#define SFXsfx086D 2157 -#define SFXsfx086E 2158 -#define SFXsfx086F 2159 -#define SFXsfx0870 2160 -#define SFXint_x_clampstp_00 2161 -#define SFXint_x_clamp_00 2162 -#define SFXint_x_clamp_01 2163 -#define SFXsfx0874 2164 -#define SFXsfx0875 2165 -#define SFXsfx0876 2166 -#define SFXsfx0877 2167 -#define SFXsfx0878 2168 -#define SFXsfx0879 2169 -#define SFXsfx087A 2170 -#define SFXsfx087B 2171 -#define SFXsfx087C 2172 -#define SFXsfx087D 2173 -#define SFXsfx087E 2174 -#define SFXsfx087F 2175 -#define SFXsfx0880 2176 -#define SFXsfx0881 2177 -#define SFXsfx0882 2178 -#define SFXsfx0883 2179 -#define SFXsfx0884 2180 diff --git a/DataSpec/DNAMP1/SFX/JellyZap.h b/DataSpec/DNAMP1/SFX/JellyZap.h deleted file mode 100644 index 7d89c7bec..000000000 --- a/DataSpec/DNAMP1/SFX/JellyZap.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: JellyZap - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPJellyZap 18 - -#define SFXjzp_a_shock_00 508 -#define SFXjzp_a_suck_lp_00 509 -#define SFXjzp_b_bubbles_00 510 -#define SFXjzp_b_growl_00 511 -#define SFXsfx0200 512 -#define SFXsfx0201 513 -#define SFXsfx0202 514 -#define SFXsfx0203 515 -#define SFXsfx0204 516 -#define SFXsfx0205 517 diff --git a/DataSpec/DNAMP1/SFX/LavaWorld.h b/DataSpec/DNAMP1/SFX/LavaWorld.h deleted file mode 100644 index c8acf9d9d..000000000 --- a/DataSpec/DNAMP1/SFX/LavaWorld.h +++ /dev/null @@ -1,112 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: LavaWorld - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPLavaWorld 47 - -#define SFXsfx0885 2181 -#define SFXsfx0886 2182 -#define SFXlav_wlklava_00 2183 -#define SFXlav_wlklava_01 2184 -#define SFXsfx0889 2185 -#define SFXlav_ballroll_lava 2186 -#define SFXsfx088B 2187 -#define SFXsfx088C 2188 -#define SFXsfx088D 2189 -#define SFXlav_landlava_00 2190 -#define SFXsfx088F 2191 -#define SFXsfx0890 2192 -#define SFXsfx0891 2193 -#define SFXsfx0892 2194 -#define SFXsfx0893 2195 -#define SFXsfx0894 2196 -#define SFXsfx0895 2197 -#define SFXsfx0896 2198 -#define SFXsfx0897 2199 -#define SFXsfx0898 2200 -#define SFXsfx0899 2201 -#define SFXsfx089A 2202 -#define SFXsfx089B 2203 -#define SFXsfx089C 2204 -#define SFXsfx089D 2205 -#define SFXsfx089E 2206 -#define SFXsfx089F 2207 -#define SFXsfx08A0 2208 -#define SFXsfx08A1 2209 -#define SFXsfx08A2 2210 -#define SFXsfx08A3 2211 -#define SFXsfx08A4 2212 -#define SFXsfx08A5 2213 -#define SFXsfx08A6 2214 -#define SFXsfx08A7 2215 -#define SFXlav_x_piston_lp_00 2216 -#define SFXsfx08A9 2217 -#define SFXlav_x_piststop_00 2218 -#define SFXlav_x_piststop_01 2219 -#define SFXsfx08AC 2220 -#define SFXsfx08AD 2221 -#define SFXswp_x_03bridgestop_00 2222 -#define SFXsfx08AF 2223 -#define SFXsfx08B0 2224 -#define SFXsfx08B1 2225 -#define SFXsfx08B2 2226 -#define SFXsfx08B3 2227 -#define SFXsfx08B4 2228 -#define SFXsfx08B5 2229 -#define SFXsfx08B6 2230 -#define SFXsfx08B7 2231 -#define SFXsfx08B8 2232 -#define SFXsfx08B9 2233 -#define SFXsfx08BA 2234 -#define SFXsfx08BB 2235 -#define SFXsfx08BC 2236 -#define SFXsfx08BD 2237 -#define SFXsfx08BE 2238 -#define SFXmag_b_rise_00 2239 -#define SFXsfx08C0 2240 -#define SFXsfx08C1 2241 -#define SFXsfx08C2 2242 -#define SFXsfx08C3 2243 -#define SFXsfx08C4 2244 -#define SFXsfx08C5 2245 -#define SFXsfx08C6 2246 -#define SFXsfx08C7 2247 -#define SFXsfx08C8 2248 -#define SFXsfx08C9 2249 -#define SFXsfx08CA 2250 -#define SFXsfx08CB 2251 -#define SFXsfx08CC 2252 -#define SFXlav_x_gateup_lp_00 2253 -#define SFXsfx08CE 2254 -#define SFXlav_x_refrig_00 2255 -#define SFXlav_x_gatestop_00 2256 -#define SFXsfx08D1 2257 -#define SFXsfx08D2 2258 -#define SFXsfx08D3 2259 -#define SFXsfx08D4 2260 -#define SFXsfx08D5 2261 -#define SFXsfx08D6 2262 -#define SFXlav_landlava_02 2263 -#define SFXsfx08D8 2264 -#define SFXsfx08D9 2265 -#define SFXsfx08DA 2266 -#define SFXsfx08DB 2267 -#define SFXsfx08DC 2268 -#define SFXsfx08DD 2269 -#define SFXsfx08DE 2270 -#define SFXsfx08DF 2271 -#define SFXsfx08E0 2272 -#define SFXsfx08E1 2273 -#define SFXsfx08E2 2274 -#define SFXsfx08E3 2275 -#define SFXsfx08E4 2276 -#define SFXsfx08E5 2277 -#define SFXsfx08E6 2278 -#define SFXsfx08E7 2279 -#define SFXsfx08E8 2280 -#define SFXsfx08E9 2281 -#define SFXsfx08EA 2282 -#define SFXsfx08EB 2283 diff --git a/DataSpec/DNAMP1/SFX/Magdolite.h b/DataSpec/DNAMP1/SFX/Magdolite.h deleted file mode 100644 index e038dac11..000000000 --- a/DataSpec/DNAMP1/SFX/Magdolite.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Magdolite - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPMagdolite 19 - -#define SFXmag_b_alert_00 518 -#define SFXmag_b_idle_00 519 -#define SFXsfx0208 520 -#define SFXmag_r_pain_00 521 -#define SFXmag_a_bite_00 522 -#define SFXmag_r_death_00 523 -#define SFXmag_a_breath_00 524 -#define SFXmag_a_flame_lp_00 525 -#define SFXmag_r_yelp_00 526 -#define SFXsfx020F 527 -#define SFXsfx0210 528 -#define SFXsfx0211 529 -#define SFXsfx0212 530 -#define SFXsfx0213 531 -#define SFXsfx0214 532 -#define SFXsfx0215 533 -#define SFXsfx0216 534 -#define SFXsfx0217 535 -#define SFXsfx0218 536 -#define SFXsfx0219 537 -#define SFXsfx021A 538 -#define SFXsfx021B 539 -#define SFXsfx021C 540 -#define SFXsfx021D 541 -#define SFXsfx021E 542 -#define SFXsfx021F 543 -#define SFXsfx0220 544 -#define SFXsfx0221 545 -#define SFXsfx0222 546 -#define SFXsfx0223 547 diff --git a/DataSpec/DNAMP1/SFX/Metaree.h b/DataSpec/DNAMP1/SFX/Metaree.h deleted file mode 100644 index 96d6964a9..000000000 --- a/DataSpec/DNAMP1/SFX/Metaree.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Metaree - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPMetaree 20 - -#define SFXmtr_a_scream_00 548 -#define SFXsfx0225 549 -#define SFXmtr_b_spin_lp_06 550 -#define SFXmtr_b_spin_lp_07 551 -#define SFXsfx0228 552 -#define SFXsfx0229 553 -#define SFXsfx022A 554 -#define SFXsfx022B 555 -#define SFXsfx022C 556 -#define SFXsfx022D 557 -#define SFXsfx022E 558 diff --git a/DataSpec/DNAMP1/SFX/Metroid.h b/DataSpec/DNAMP1/SFX/Metroid.h deleted file mode 100644 index 0810b54f3..000000000 --- a/DataSpec/DNAMP1/SFX/Metroid.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Metroid - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPMetroid 21 - -#define SFXsfx022F 559 -#define SFXsfx0230 560 -#define SFXmtd_a_facehug_02 561 -#define SFXmtd_a_swoosh_00 562 -#define SFXmtd_a_swoosh_01 563 -#define SFXmtd_a_thunk_00 564 -#define SFXmtd_b_fadein_00 565 -#define SFXmtd_b_fadeout_00 566 -#define SFXmtd_b_float_lp_00 567 -#define SFXmtd_b_float_lp_01 568 -#define SFXmtd_b_idle_00 569 -#define SFXmtd_b_idle_01 570 -#define SFXsfx023B 571 -#define SFXsfx023C 572 -#define SFXsfx023D 573 -#define SFXsfx023E 574 -#define SFXsfx023F 575 -#define SFXmtd_b_squish_00 576 -#define SFXmtd_b_squish_01 577 -#define SFXsfx0242 578 -#define SFXmtd_b_voxangry_00 579 -#define SFXsfx0244 580 -#define SFXsfx0245 581 -#define SFXmtd_r_impact_00 582 -#define SFXsfx0247 583 -#define SFXsfx0248 584 -#define SFXmt2_a_facehug_02 585 -#define SFXsfx024A 586 -#define SFXsfx024B 587 -#define SFXsfx024C 588 -#define SFXsfx024D 589 -#define SFXmt2_b_float_lp_00 590 -#define SFXmt2_b_float_lp_01 591 -#define SFXsfx0250 592 -#define SFXsfx0251 593 -#define SFXsfx0252 594 -#define SFXmt2_b_idle_02 595 -#define SFXsfx0254 596 -#define SFXsfx0255 597 -#define SFXmt2_b_leech_lp_00 598 -#define SFXsfx0257 599 -#define SFXsfx0258 600 -#define SFXmt2_b_voxangry_00 601 -#define SFXmt2_b_voxangry_01 602 -#define SFXsfx025B 603 -#define SFXmt2_r_impact_00 604 -#define SFXmtd_b_grow_00 605 -#define SFXmtd_b_suck_lp_00 606 -#define SFXmtd_r_death_00 607 -#define SFXmt2_b_float_lp_02 608 -#define SFXsfx0261 609 -#define SFXmtd_b_voxcalm_00 610 -#define SFXsfx0263 611 -#define SFXsfx0264 612 -#define SFXsfx0265 613 -#define SFXsfx0266 614 -#define SFXsfx0267 615 -#define SFXsfx0268 616 -#define SFXsfx0269 617 -#define SFXsfx026A 618 -#define SFXsfx026B 619 -#define SFXsfx026C 620 -#define SFXsfx026D 621 -#define SFXsfx026E 622 -#define SFXsfx026F 623 diff --git a/DataSpec/DNAMP1/SFX/MetroidPrime.h b/DataSpec/DNAMP1/SFX/MetroidPrime.h deleted file mode 100644 index 8542b06d3..000000000 --- a/DataSpec/DNAMP1/SFX/MetroidPrime.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: MetroidPrime - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPMetroidPrime 58 - -#define SFXmtb_b_voxtaunt_00 2891 -#define SFXsfx0B4C 2892 -#define SFXmtb_a_claw_00 2893 -#define SFXmtb_a_swoosh 2894 -#define SFXmtb_b_voxattak_00 2895 -#define SFXmtb_b_walk_00 2896 -#define SFXmtb_b_walk_01 2897 -#define SFXmtb_b_walk_02 2898 -#define SFXmtb_b_voxidle_00 2899 -#define SFXsfx0B54 2900 -#define SFXmtb_r_painbig_00 2901 -#define SFXmtb_r_painsm_00 2902 -#define SFXmtb_b_voxattak_01 2903 -#define SFXmtb_a_icewave_lp_00 2904 -#define SFXsfx0B59 2905 -#define SFXsfx0B5A 2906 -#define SFXmtb_b_voxangry_00 2907 -#define SFXmtb_b_voxangry_01 2908 -#define SFXmtb_a_flame_lp_00 2909 -#define SFXmtb_a_mirv_00 2910 -#define SFXsfx0B5F 2911 -#define SFXsfx0B60 2912 -#define SFXmth_b_dash_00 2913 -#define SFXmth_c_painbig_00 2914 -#define SFXmth_b_voxcall_00 2915 -#define SFXmth_b_voxidle_00 2916 -#define SFXmth_b_voxidle_01 2917 -#define SFXmth_b_voxtaunt_00 2918 -#define SFXsfx0B67 2919 -#define SFXmtb_a_hitwall_00 2920 -#define SFXmth_c_painsm_00 2921 -#define SFXsfx0B6A 2922 -#define SFXsfx0B6B 2923 -#define SFXmtb_a_flameup_lp_00 2924 -#define SFXsfx0B6D 2925 -#define SFXsfx0B6E 2926 -#define SFXsfx0B6F 2927 -#define SFXsfx0B70 2928 -#define SFXsfx0B71 2929 -#define SFXmth_b_emerge_00 2930 -#define SFXsfx0B73 2931 -#define SFXmth_b_voxattak_01 2932 -#define SFXsfx0B75 2933 -#define SFXmth_b_float_lp_00 2934 -#define SFXsfx0B77 2935 -#define SFXmth_a_blast_lp_00 2936 -#define SFXsfx0B79 2937 -#define SFXsfx0B7A 2938 -#define SFXsfx0B7B 2939 -#define SFXmth_a_blasthit_00 2940 -#define SFXsfx0B7D 2941 -#define SFXsfx0B7E 2942 -#define SFXmtb_c_cinemove_00 2943 -#define SFXsfx0B80 2944 -#define SFXmtb_c_land_00 2945 -#define SFXmtb_c_wakeup_00 2946 -#define SFXsfx0B83 2947 -#define SFXsfx0B84 2948 -#define SFXsfx0B85 2949 -#define SFXsfx0B86 2950 -#define SFXsfx0B87 2951 -#define SFXmtb_a_tractor_lp_00 2952 -#define SFXmth_a_swing_00 2953 -#define SFXsfx0B8A 2954 -#define SFXsfx0B8B 2955 -#define SFXsfx0B8C 2956 -#define SFXsfx0B8D 2957 -#define SFXsfx0B8E 2958 -#define SFXmtb_b_land_00 2959 -#define SFXmth_c_blur_00 2960 -#define SFXsfx0B91 2961 -#define SFXsfx0B92 2962 -#define SFXsfx0B93 2963 -#define SFXsfx0B94 2964 -#define SFXsfx0B95 2965 -#define SFXsfx0B96 2966 -#define SFXmtb_a_nrgchg_00 2967 -#define SFXsfx0B98 2968 -#define SFXmtb_a_nrgfire_lp_00 2969 -#define SFXsfx0B9A 2970 -#define SFXsfx0B9B 2971 diff --git a/DataSpec/DNAMP1/SFX/MinesWorld.h b/DataSpec/DNAMP1/SFX/MinesWorld.h deleted file mode 100644 index d10721cc0..000000000 --- a/DataSpec/DNAMP1/SFX/MinesWorld.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: MinesWorld - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPMinesWorld 48 - -#define SFXsfx08EC 2284 -#define SFXsfx08ED 2285 -#define SFXsfx08EE 2286 -#define SFXsfx08EF 2287 -#define SFXsfx08F0 2288 -#define SFXsfx08F1 2289 -#define SFXmin_x_cranestop_00 2290 -#define SFXsfx08F3 2291 -#define SFXmin_x_piston_00 2292 -#define SFXsfx08F5 2293 -#define SFXsfx08F6 2294 -#define SFXsfx08F7 2295 -#define SFXsfx08F8 2296 -#define SFXmin_x_crane_lp_00 2297 -#define SFXsfx08FA 2298 -#define SFXsfx08FB 2299 -#define SFXsfx08FC 2300 -#define SFXsfx08FD 2301 -#define SFXsfx08FE 2302 -#define SFXsfx08FF 2303 -#define SFXsfx0900 2304 -#define SFXsfx0901 2305 -#define SFXsfx0902 2306 -#define SFXopr_c_land_00 2307 -#define SFXsfx0904 2308 -#define SFXsfx0905 2309 -#define SFXsfx0906 2310 -#define SFXsfx0907 2311 -#define SFXsfx0908 2312 -#define SFXmin_x_gears_lp_01 2313 -#define SFXsfx090A 2314 -#define SFXsfx090B 2315 -#define SFXsfx090C 2316 -#define SFXsfx090D 2317 -#define SFXsfx090E 2318 -#define SFXsfx090F 2319 -#define SFXsfx0910 2320 -#define SFXsfx0911 2321 -#define SFXsfx0912 2322 -#define SFXsfx0913 2323 -#define SFXsfx0914 2324 -#define SFXsfx0915 2325 -#define SFXsfx0916 2326 -#define SFXmin_x_turbine_lp_00 2327 -#define SFXsfx0918 2328 -#define SFXsfx0919 2329 -#define SFXsfx091A 2330 -#define SFXsfx091B 2331 -#define SFXsfx091C 2332 -#define SFXsfx091D 2333 -#define SFXsfx091E 2334 -#define SFXsfx091F 2335 -#define SFXsfx0920 2336 -#define SFXsfx0921 2337 -#define SFXsfx0922 2338 -#define SFXsfx0923 2339 -#define SFXsfx0924 2340 -#define SFXsfx0925 2341 -#define SFXsfx0926 2342 -#define SFXsfx0927 2343 -#define SFXsfx0928 2344 -#define SFXsfx0929 2345 -#define SFXsfx092A 2346 -#define SFXsfx092B 2347 -#define SFXsfx092C 2348 -#define SFXsfx092D 2349 -#define SFXsfx092E 2350 -#define SFXsfx092F 2351 -#define SFXsfx0930 2352 -#define SFXsfx0931 2353 -#define SFXsfx0932 2354 -#define SFXsfx0933 2355 -#define SFXsfx0934 2356 -#define SFXsfx0935 2357 -#define SFXsfx0936 2358 -#define SFXsfx0937 2359 -#define SFXsfx0938 2360 -#define SFXsfx0939 2361 -#define SFXsfx093A 2362 -#define SFXsfx093B 2363 -#define SFXsfx093C 2364 diff --git a/DataSpec/DNAMP1/SFX/Misc.h b/DataSpec/DNAMP1/SFX/Misc.h deleted file mode 100644 index eb07c5fa8..000000000 --- a/DataSpec/DNAMP1/SFX/Misc.h +++ /dev/null @@ -1,256 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Misc - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPMisc 39 - -#define SFXdor_x_close_00 1128 -#define SFXdor_x_open_00 1129 -#define SFXsfx046A 1130 -#define SFXpik_x_idle_00 1131 -#define SFXsfx046C 1132 -#define SFXamb_x_rumble_lp_00 1133 -#define SFXsfx046E 1134 -#define SFXpik_x_morphamb_lp_00 1135 -#define SFXpik_x_powerup_00 1136 -#define SFXsfx0471 1137 -#define SFXsfx0472 1138 -#define SFXsfx0473 1139 -#define SFXsfx0474 1140 -#define SFXamb_x_splash_02 1141 -#define SFXsfx0476 1142 -#define SFXsfx0477 1143 -#define SFXsfx0478 1144 -#define SFXsfx0479 1145 -#define SFXsfx047A 1146 -#define SFXpik_x_elevamb_lp_00 1147 -#define SFXsfx047C 1148 -#define SFXeff_x_largeburndeath_lp_00 1149 -#define SFXeff_x_smallburndeath_lp_00 1150 -#define SFXeff_x_fire_lp_00 1151 -#define SFXsfx0480 1152 -#define SFXsfx0481 1153 -#define SFXci2_x_eletric_00 1154 -#define SFXci3_x_electric_lp_00 1155 -#define SFXmac_x_fire_lp_00 1156 -#define SFXsfx0485 1157 -#define SFXci4_x_electric_lp_00 1158 -#define SFXsfx0487 1159 -#define SFXsfx0488 1160 -#define SFXsfx0489 1161 -#define SFXsfx048A 1162 -#define SFXsfx048B 1163 -#define SFXdrn_b_smoke_lp_00 1164 -#define SFXga2_r_explode_00 1165 -#define SFXsfx048E 1166 -#define SFXsfx048F 1167 -#define SFXsfx0490 1168 -#define SFXsfx0491 1169 -#define SFXmag_r_explode_00 1170 -#define SFXsfx0493 1171 -#define SFXsfx0494 1172 -#define SFXsfx0495 1173 -#define SFXsfx0496 1174 -#define SFXsfx0497 1175 -#define SFXeff_x_icebrk_00 1176 -#define SFXeff_x_icebrk_01 1177 -#define SFXsfx049A 1178 -#define SFXsfx049B 1179 -#define SFXsfx049C 1180 -#define SFXsfx049D 1181 -#define SFXsfx049E 1182 -#define SFXsfx049F 1183 -#define SFXsfx04A0 1184 -#define SFXsfx04A1 1185 -#define SFXmac_x_fireup_00 1186 -#define SFXsfx04A3 1187 -#define SFXsfx04A4 1188 -#define SFXsfx04A5 1189 -#define SFXsfx04A6 1190 -#define SFXsfx04A7 1191 -#define SFXsfx04A8 1192 -#define SFXsfx04A9 1193 -#define SFXsfx04AA 1194 -#define SFXsfx04AB 1195 -#define SFXsfx04AC 1196 -#define SFXeff_x_electro_lp_00 1197 -#define SFXeff_x_electro_lp_01 1198 -#define SFXsfx04AF 1199 -#define SFXsfx04B0 1200 -#define SFXsfx04B1 1201 -#define SFXsfx04B2 1202 -#define SFXsfx04B3 1203 -#define SFXsfx04B4 1204 -#define SFXsfx04B5 1205 -#define SFXsfx04B6 1206 -#define SFXsfx04B7 1207 -#define SFXsfx04B8 1208 -#define SFXsfx04B9 1209 -#define SFXsfx04BA 1210 -#define SFXsfx04BB 1211 -#define SFXsfx04BC 1212 -#define SFXsfx04BD 1213 -#define SFXsfx04BE 1214 -#define SFXsfx04BF 1215 -#define SFXsfx04C0 1216 -#define SFXsfx04C1 1217 -#define SFXsfx04C2 1218 -#define SFXocu_b_gas_lp_00 1219 -#define SFXsfx04C4 1220 -#define SFXsfx04C5 1221 -#define SFXsfx04C6 1222 -#define SFXtha_a_electric_00 1223 -#define SFXsfx04C8 1224 -#define SFXdrn_r_empelec_00 1225 -#define SFXeff_x_frozen_00 1226 -#define SFXeff_x_frozen_01 1227 -#define SFXsfx04CC 1228 -#define SFXsfx04CD 1229 -#define SFXsfx04CE 1230 -#define SFXsfx04CF 1231 -#define SFXsfx04D0 1232 -#define SFXsfx04D1 1233 -#define SFXepr_b_elec_lp_00 1234 -#define SFXsfx04D3 1235 -#define SFXsfx04D4 1236 -#define SFXsfx04D5 1237 -#define SFXsfx04D6 1238 -#define SFXsfx04D7 1239 -#define SFXamb_x_gatestop_00 1240 -#define SFXsfx04D9 1241 -#define SFXsfx04DA 1242 -#define SFXsfx04DB 1243 -#define SFXsfx04DC 1244 -#define SFXsfx04DD 1245 -#define SFXsfx04DE 1246 -#define SFXsfx04DF 1247 -#define SFXsfx04E0 1248 -#define SFXsfx04E1 1249 -#define SFXsfx04E2 1250 -#define SFXsfx04E3 1251 -#define SFXsfx04E4 1252 -#define SFXsfx04E5 1253 -#define SFXsfx04E6 1254 -#define SFXsfx04E7 1255 -#define SFXsfx04E8 1256 -#define SFXsfx04E9 1257 -#define SFXsfx04EA 1258 -#define SFXsfx04EB 1259 -#define SFXsfx04EC 1260 -#define SFXsfx04ED 1261 -#define SFXsfx04EE 1262 -#define SFXsfx04EF 1263 -#define SFXsfx04F0 1264 -#define SFXsfx04F1 1265 -#define SFXsfx04F2 1266 -#define SFXsfx04F3 1267 -#define SFXsfx04F4 1268 -#define SFXamb_x_gateup_00 1269 -#define SFXsfx04F6 1270 -#define SFXsfx04F7 1271 -#define SFXsfx04F8 1272 -#define SFXsfx04F9 1273 -#define SFXsfx04FA 1274 -#define SFXrid_r_explode_00 1275 -#define SFXsfx04FC 1276 -#define SFXsfx04FD 1277 -#define SFXsfx04FE 1278 -#define SFXsfx04FF 1279 -#define SFXsfx0500 1280 -#define SFXsfx0501 1281 -#define SFXsfx0502 1282 -#define SFXsfx0503 1283 -#define SFXsfx0504 1284 -#define SFXsfx0505 1285 -#define SFXamb_x_steamsml_lp_00 1286 -#define SFXsfx0507 1287 -#define SFXsfx0508 1288 -#define SFXsfx0509 1289 -#define SFXamb_c_suitlose_lp_00 1290 -#define SFXsfx050B 1291 -#define SFXsfx050C 1292 -#define SFXsfx050D 1293 -#define SFXsfx050E 1294 -#define SFXsfx050F 1295 -#define SFXsfx0510 1296 -#define SFXsfx0511 1297 -#define SFXsfx0512 1298 -#define SFXsfx0513 1299 -#define SFXsfx0514 1300 -#define SFXsfx0515 1301 -#define SFXsfx0516 1302 -#define SFXsfx0517 1303 -#define SFXsfx0518 1304 -#define SFXsfx0519 1305 -#define SFXsfx051A 1306 -#define SFXsfx051B 1307 -#define SFXsfx051C 1308 -#define SFXsfx051D 1309 -#define SFXsfx051E 1310 -#define SFXsfx051F 1311 -#define SFXsfx0520 1312 -#define SFXsfx0521 1313 -#define SFXsfx0522 1314 -#define SFXsfx0523 1315 -#define SFXsfx0524 1316 -#define SFXsfx0525 1317 -#define SFXsfx0526 1318 -#define SFXsfx0527 1319 -#define SFXsfx0528 1320 -#define SFXsfx0529 1321 -#define SFXsfx052A 1322 -#define SFXsfx052B 1323 -#define SFXrid_c_elec_lp_00 1324 -#define SFXsfx052D 1325 -#define SFXsfx052E 1326 -#define SFXsfx052F 1327 -#define SFXsfx0530 1328 -#define SFXsfx0531 1329 -#define SFXsfx0532 1330 -#define SFXsfx0533 1331 -#define SFXsfx0534 1332 -#define SFXsfx0535 1333 -#define SFXsfx0536 1334 -#define SFXsfx0537 1335 -#define SFXsfx0538 1336 -#define SFXsfx0539 1337 -#define SFXsfx053A 1338 -#define SFXsfx053B 1339 -#define SFXsfx053C 1340 -#define SFXsfx053D 1341 -#define SFXsfx053E 1342 -#define SFXsfx053F 1343 -#define SFXsfx0540 1344 -#define SFXsfx0541 1345 -#define SFXsfx0542 1346 -#define SFXsfx0543 1347 -#define SFXsfx0544 1348 -#define SFXsfx0545 1349 -#define SFXsfx0546 1350 -#define SFXsfx0547 1351 -#define SFXsfx0548 1352 -#define SFXsfx0549 1353 -#define SFXsfx054A 1354 -#define SFXsfx054B 1355 -#define SFXsfx054C 1356 -#define SFXsfx054D 1357 -#define SFXsfx054E 1358 -#define SFXsfx054F 1359 -#define SFXsfx0550 1360 -#define SFXsfx0551 1361 -#define SFXsfx0552 1362 -#define SFXsfx0553 1363 -#define SFXsfx0554 1364 -#define SFXsfx0555 1365 -#define SFXsfx0556 1366 -#define SFXsfx0557 1367 -#define SFXsfx0558 1368 -#define SFXsfx0559 1369 -#define SFXsfx055A 1370 -#define SFXsfx055B 1371 -#define SFXsfx055C 1372 -#define SFXsfx055D 1373 -#define SFXsfx055E 1374 diff --git a/DataSpec/DNAMP1/SFX/MiscSamus.h b/DataSpec/DNAMP1/SFX/MiscSamus.h deleted file mode 100644 index c40e3871b..000000000 --- a/DataSpec/DNAMP1/SFX/MiscSamus.h +++ /dev/null @@ -1,268 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: MiscSamus - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPMiscSamus 41 - -#define SFXsam_wlkstone_00 1465 -#define SFXsam_wlkstone_01 1466 -#define SFXsam_suit_damage 1467 -#define SFXsam_ball_jump 1468 -#define SFXsam_b_highland_00 1469 -#define SFXsam_b_jump_00 1470 -#define SFXsam_firstjump 1471 -#define SFXsam_landdirt_00 1472 -#define SFXsfx05C1 1473 -#define SFXsfx05C2 1474 -#define SFXsam_ballland_stone 1475 -#define SFXsam_ball_boost 1476 -#define SFXsam_ball_charge_lp 1477 -#define SFXsam_b_morphin_00 1478 -#define SFXsam_b_morphout_00 1479 -#define SFXsam_ballroll_dirt 1480 -#define SFXsfx05C9 1481 -#define SFXsfx05CA 1482 -#define SFXsfx05CB 1483 -#define SFXsam_wlkwater_00 1484 -#define SFXsam_wlkwater_01 1485 -#define SFXsam_damage_poison_lp 1486 -#define SFXsfx05CF 1487 -#define SFXsfx05D0 1488 -#define SFXsam_vox_damage 1489 -#define SFXsam_landmetl_00 1490 -#define SFXsam_ball_damage 1491 -#define SFXsam_b_movearm_00 1492 -#define SFXsam_wlkgrate_00 1493 -#define SFXsam_wlkgrate_01 1494 -#define SFXsam_wlkmetal_00 1495 -#define SFXsam_wlkmetal_01 1496 -#define SFXsam_wlkdirt_00 1497 -#define SFXsam_ballland_grate 1498 -#define SFXsam_wlkdirt_01 1499 -#define SFXsam_ballroll_grate 1500 -#define SFXsam_ballroll_metal 1501 -#define SFXsam_ballroll_stone 1502 -#define SFXsfx05DF 1503 -#define SFXsam_ballland_metal 1504 -#define SFXsam_b_movearm_01 1505 -#define SFXsfx05E2 1506 -#define SFXsam_landgrate_00 1507 -#define SFXsam_landstone_00 1508 -#define SFXsfx05E5 1509 -#define SFXsfx05E6 1510 -#define SFXsam_vox_damage15 1511 -#define SFXsam_vox_damage30 1512 -#define SFXsam_ball_damage15 1513 -#define SFXsam_ball_damage30 1514 -#define SFXsfx05EB 1515 -#define SFXsam_death 1516 -#define SFXsfx05ED 1517 -#define SFXsfx05EE 1518 -#define SFXsam_b_landmetl_01 1519 -#define SFXsfx05F0 1520 -#define SFXsfx05F1 1521 -#define SFXsfx05F2 1522 -#define SFXsam_spider_lp 1523 -#define SFXsfx05F4 1524 -#define SFXsam_ball_wallhit 1525 -#define SFXsam_grapple_fire 1526 -#define SFXsam_grapple_lp 1527 -#define SFXsam_grapple_swoosh 1528 -#define SFXsam_wlkwood_00 1529 -#define SFXsam_wlkwood_01 1530 -#define SFXsam_landwood_00 1531 -#define SFXsam_b_movefla_00 1532 -#define SFXsam_ballland_wood 1533 -#define SFXsam_ballroll_wood 1534 -#define SFXsfx05FF 1535 -#define SFXsfx0600 1536 -#define SFXsfx0601 1537 -#define SFXsfx0602 1538 -#define SFXsfx0603 1539 -#define SFXsfx0604 1540 -#define SFXsam_b_jumpcine_00 1541 -#define SFXsam_landphazon_00 1542 -#define SFXsfx0607 1543 -#define SFXsfx0608 1544 -#define SFXsam_ballland_phazon 1545 -#define SFXsfx060A 1546 -#define SFXsam_ballroll_phazon 1547 -#define SFXsam_b_voxland_00 1548 -#define SFXsfx060D 1549 -#define SFXsam_voxland_02 1550 -#define SFXsfx060F 1551 -#define SFXsfx0610 1552 -#define SFXsam_wlkphazon_00 1553 -#define SFXsam_wlkphazon_01 1554 -#define SFXpds_b_water_03 1555 -#define SFXsam_b_butpress_00 1556 -#define SFXsam_b_butpress_01 1557 -#define SFXsam_b_panlclos_00 1558 -#define SFXsam_b_panlopen_00 1559 -#define SFXsam_dash 1560 -#define SFXsam_b_move_00 1561 -#define SFXsam_b_move_01 1562 -#define SFXsam_b_voxjump_00 1563 -#define SFXsfx061C 1564 -#define SFXsfx061D 1565 -#define SFXsfx061E 1566 -#define SFXsam_b_wlkmetal_02 1567 -#define SFXsam_b_wlkmetal_03 1568 -#define SFXsam_landgrass_00 1569 -#define SFXsam_b_wlkgrass_00 1570 -#define SFXsam_b_wlkgrass_01 1571 -#define SFXsam_b_spin_lp_00 1572 -#define SFXsam_b_landorg_00 1573 -#define SFXsfx0626 1574 -#define SFXsam_ballland_org 1575 -#define SFXsam_ballroll_org 1576 -#define SFXsam_b_wlkorg_00 1577 -#define SFXsam_b_wlkorg_01 1578 -#define SFXsam_landmud_00 1579 -#define SFXsam_ballland_grass 1580 -#define SFXsam_ballland_mud 1581 -#define SFXsfx062E 1582 -#define SFXsam_ballroll_grass 1583 -#define SFXsam_ballroll_mud 1584 -#define SFXsam_wlkmud_00 1585 -#define SFXsam_wlkmud_01 1586 -#define SFXsam_b_landcine_01 1587 -#define SFXsfx0634 1588 -#define SFXsfx0635 1589 -#define SFXsfx0636 1590 -#define SFXsam_vox_exhausted 1591 -#define SFXsam_landsnow_00 1592 -#define SFXsam_b_landsnow_01 1593 -#define SFXsam_wlksnow_00 1594 -#define SFXsam_wlksnow_01 1595 -#define SFXsam_b_wlksnow_02 1596 -#define SFXsam_b_wlksnow_03 1597 -#define SFXsfx063E 1598 -#define SFXsfx063F 1599 -#define SFXsam_b_landcine_00 1600 -#define SFXgab_b_wlksnow_00 1601 -#define SFXgab_b_wlksnow_01 1602 -#define SFXsfx0643 1603 -#define SFXsam_r_hithelm_00 1604 -#define SFXsfx0645 1605 -#define SFXsfx0646 1606 -#define SFXsam_landgrass_02 1607 -#define SFXsam_landgrate_02 1608 -#define SFXsfx0649 1609 -#define SFXsfx064A 1610 -#define SFXsam_b_landmetl_02 1611 -#define SFXsam_landmud_02 1612 -#define SFXsam_landorg_02 1613 -#define SFXsam_landphazon_02 1614 -#define SFXsam_landdirt_02 1615 -#define SFXsam_landsnow_02 1616 -#define SFXsam_landstone_02 1617 -#define SFXsam_landwood_02 1618 -#define SFXsam_wlkice_00 1619 -#define SFXsam_wlkice_01 1620 -#define SFXsfx0655 1621 -#define SFXsfx0656 1622 -#define SFXsam_b_landgras_01 1623 -#define SFXsam_landice_00 1624 -#define SFXsfx0659 1625 -#define SFXsam_landice_02 1626 -#define SFXsam_ballland_ice 1627 -#define SFXsam_ballland_snow 1628 -#define SFXpar_b_wlksnow_00 1629 -#define SFXpar_b_wlksnow_01 1630 -#define SFXsfx065F 1631 -#define SFXsfx0660 1632 -#define SFXsam_vox_damage_poison 1633 -#define SFXsfx0662 1634 -#define SFXsfx0663 1635 -#define SFXsam_c_suithit_00 1636 -#define SFXsam_c_suithit_01 1637 -#define SFXsam_c_suithitv_00 1638 -#define SFXsam_c_suitmov1_00 1639 -#define SFXsam_r_phazhit_lp_00 1640 -#define SFXsam_c_suitfall_00 1641 -#define SFXsam_c_suitfall_01 1642 -#define SFXsam_c_suitmov2_00 1643 -#define SFXsam_c_suitmov2_01 1644 -#define SFXsfx066D 1645 -#define SFXsfx066E 1646 -#define SFXfpr_b_land_00 1647 -#define SFXfpr_b_land_01 1648 -#define SFXsfx0671 1649 -#define SFXspr_b_land_00 1650 -#define SFXspr_b_land_01 1651 -#define SFXsfx0674 1652 -#define SFXsam_vox_damage_phazon 1653 -#define SFXsfx0676 1654 -#define SFXsfx0677 1655 -#define SFXsam_vox_damage_heat 1656 -#define SFXsfx0679 1657 -#define SFXsfx067A 1658 -#define SFXsfx067B 1659 -#define SFXsam_b_wlkstone_02 1660 -#define SFXsam_b_wlkstone_03 1661 -#define SFXsam_b_wlkdirt_02 1662 -#define SFXsam_b_wlkdirt_03 1663 -#define SFXsam_b_move_02 1664 -#define SFXsam_b_move_03 1665 -#define SFXsfx0682 1666 -#define SFXsam_c_mpwlkorg_00 1667 -#define SFXsam_c_mpwlkorg_01 1668 -#define SFXci7_x_spin_lp_00 1669 -#define SFXsfx0686 1670 -#define SFXsam_c_butpress_00 1671 -#define SFXsam_c_butpress_01 1672 -#define SFXsam_c_intrmove_02 1673 -#define SFXsam_c_intrmove_03 1674 -#define SFXsam_c_intrspin_lp_00 1675 -#define SFXsam_c_iwlkmetal_02 1676 -#define SFXsam_c_iwlkmetal_03 1677 -#define SFXsam_c_movearm_00 1678 -#define SFXsam_c_movearm_01 1679 -#define SFXsam_c_moveend_00 1680 -#define SFXsam_c_moveend_01 1681 -#define SFXsam_c_spinend_lp_00 1682 -#define SFXsfx0693 1683 -#define SFXsam_landlavastone_00 1684 -#define SFXsfx0695 1685 -#define SFXsam_landlavastone_02 1686 -#define SFXsam_ballland_lava 1687 -#define SFXsam_ballroll_lavastone 1688 -#define SFXsam_wlklavastone_00 1689 -#define SFXsam_wlklavastone_01 1690 -#define SFXsfx069B 1691 -#define SFXsfx069C 1692 -#define SFXsfx069D 1693 -#define SFXsfx069E 1694 -#define SFXsfx069F 1695 -#define SFXsfx06A0 1696 -#define SFXsfx06A1 1697 -#define SFXsfx06A2 1698 -#define SFXsfx06A3 1699 -#define SFXsfx06A4 1700 -#define SFXsfx06A5 1701 -#define SFXsfx06A6 1702 -#define SFXsfx06A7 1703 -#define SFXsfx06A8 1704 -#define SFXsfx06A9 1705 -#define SFXsfx06AA 1706 -#define SFXsfx06AB 1707 -#define SFXsfx06AC 1708 -#define SFXsfx06AD 1709 -#define SFXsfx06AE 1710 -#define SFXsfx06AF 1711 -#define SFXsfx06B0 1712 -#define SFXsfx06B1 1713 -#define SFXsfx06B2 1714 -#define SFXsfx06B3 1715 -#define SFXsfx06B4 1716 -#define SFXsfx06B5 1717 -#define SFXsfx06B6 1718 -#define SFXsfx06B7 1719 -#define SFXsfx06B8 1720 -#define SFXsfx06B9 1721 -#define SFXsfx06BA 1722 -#define SFXsfx06BB 1723 diff --git a/DataSpec/DNAMP1/SFX/OmegaPirate.h b/DataSpec/DNAMP1/SFX/OmegaPirate.h deleted file mode 100644 index e21222ce1..000000000 --- a/DataSpec/DNAMP1/SFX/OmegaPirate.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: OmegaPirate - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPOmegaPirate 57 - -#define SFXsfx0B0F 2831 -#define SFXsfx0B10 2832 -#define SFXopr_b_voxcall_00 2833 -#define SFXopr_b_voxcall_01 2834 -#define SFXopr_b_voxlaugh_00 2835 -#define SFXopr_r_moan_00 2836 -#define SFXsfx0B15 2837 -#define SFXsfx0B16 2838 -#define SFXopr_b_run_01 2839 -#define SFXsfx0B18 2840 -#define SFXopr_b_voxalert_00 2841 -#define SFXopr_b_voxalert_01 2842 -#define SFXopr_b_voxattak_00 2843 -#define SFXopr_b_voxattak_01 2844 -#define SFXopr_b_voxblok_00 2845 -#define SFXopr_b_voxidle_00 2846 -#define SFXopr_b_voxidle_01 2847 -#define SFXopr_b_voxpiss_00 2848 -#define SFXopr_b_voxtaunt_00 2849 -#define SFXopr_b_walklite_00 2850 -#define SFXopr_b_walklite_01 2851 -#define SFXopr_b_walk_00 2852 -#define SFXopr_b_walk_01 2853 -#define SFXopr_b_healnrg_lp_00 2854 -#define SFXsfx0B27 2855 -#define SFXsfx0B28 2856 -#define SFXsfx0B29 2857 -#define SFXopr_r_pain_00 2858 -#define SFXopr_r_pain_01 2859 -#define SFXsfx0B2C 2860 -#define SFXopr_b_invis_00 2861 -#define SFXopr_b_voxready_00 2862 -#define SFXsfx0B2F 2863 -#define SFXsfx0B30 2864 -#define SFXopr_r_pain_02 2865 -#define SFXsfx0B32 2866 -#define SFXopr_a_grenchrg_00 2867 -#define SFXsfx0B34 2868 -#define SFXopr_a_grenade_00 2869 -#define SFXsfx0B36 2870 -#define SFXsfx0B37 2871 -#define SFXsfx0B38 2872 -#define SFXsfx0B39 2873 -#define SFXsfx0B3A 2874 -#define SFXsfx0B3B 2875 -#define SFXsfx0B3C 2876 -#define SFXsfx0B3D 2877 -#define SFXopr_r_death_01 2878 -#define SFXsfx0B3F 2879 -#define SFXopr_c_samswoosh_00 2880 -#define SFXsfx0B41 2881 -#define SFXsfx0B42 2882 -#define SFXsfx0B43 2883 -#define SFXsfx0B44 2884 -#define SFXsfx0B45 2885 -#define SFXsfx0B46 2886 -#define SFXsfx0B47 2887 -#define SFXsfx0B48 2888 -#define SFXsfx0B49 2889 -#define SFXsfx0B4A 2890 diff --git a/DataSpec/DNAMP1/SFX/OverWorld.h b/DataSpec/DNAMP1/SFX/OverWorld.h deleted file mode 100644 index f39633383..000000000 --- a/DataSpec/DNAMP1/SFX/OverWorld.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: OverWorld - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPOverWorld 51 - -#define SFXsfx09E0 2528 -#define SFXsfx09E1 2529 -#define SFXsfx09E2 2530 -#define SFXsfx09E3 2531 -#define SFXsfx09E4 2532 -#define SFXsfx09E5 2533 -#define SFXsfx09E6 2534 -#define SFXsfx09E7 2535 -#define SFXsfx09E8 2536 -#define SFXsfx09E9 2537 -#define SFXsfx09EA 2538 -#define SFXsfx09EB 2539 -#define SFXsfx09EC 2540 -#define SFXsfx09ED 2541 -#define SFXsfx09EE 2542 -#define SFXsfx09EF 2543 -#define SFXsfx09F0 2544 -#define SFXsfx09F1 2545 -#define SFXcrb_b_hiss_00 2546 -#define SFXcrb_b_idle_00 2547 -#define SFXsfx09F4 2548 -#define SFXsfx09F5 2549 -#define SFXsfx09F6 2550 -#define SFXsfx09F7 2551 -#define SFXsfx09F8 2552 -#define SFXove_x_spinbars_lp 2553 -#define SFXsfx09FA 2554 -#define SFXsfx09FB 2555 -#define SFXsfx09FC 2556 -#define SFXsfx09FD 2557 -#define SFXsfx09FE 2558 -#define SFXsfx09FF 2559 -#define SFXsfx0A00 2560 -#define SFXsfx0A01 2561 -#define SFXsfx0A02 2562 -#define SFXsfx0A03 2563 -#define SFXsfx0A04 2564 -#define SFXsfx0A05 2565 -#define SFXsfx0A06 2566 -#define SFXsfx0A07 2567 -#define SFXsfx0A08 2568 -#define SFXsfx0A09 2569 -#define SFXsfx0A0A 2570 -#define SFXsfx0A0B 2571 -#define SFXsfx0A0C 2572 -#define SFXsfx0A0D 2573 -#define SFXsfx0A0E 2574 -#define SFXsfx0A0F 2575 -#define SFXsfx0A10 2576 -#define SFXsfx0A11 2577 -#define SFXsfx0A12 2578 -#define SFXsfx0A13 2579 -#define SFXsfx0A14 2580 -#define SFXlbm_c_beam_lp_01 2581 -#define SFXsfx0A16 2582 -#define SFXsfx0A17 2583 -#define SFXsfx0A18 2584 -#define SFXsfx0A19 2585 -#define SFXsfx0A1A 2586 -#define SFXsfx0A1B 2587 -#define SFXsfx0A1C 2588 -#define SFXsfx0A1D 2589 -#define SFXsfx0A1E 2590 -#define SFXsfx0A1F 2591 -#define SFXsfx0A20 2592 -#define SFXsfx0A21 2593 -#define SFXsfx0A22 2594 -#define SFXsfx0A23 2595 -#define SFXsfx0A24 2596 -#define SFXsfx0A25 2597 -#define SFXsfx0A26 2598 -#define SFXsfx0A27 2599 diff --git a/DataSpec/DNAMP1/SFX/Parasite.h b/DataSpec/DNAMP1/SFX/Parasite.h deleted file mode 100644 index 5769165f0..000000000 --- a/DataSpec/DNAMP1/SFX/Parasite.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Parasite - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPParasite 22 - -#define SFXpar_a_voxangry_00 624 -#define SFXsfx0271 625 -#define SFXsfx0272 626 -#define SFXsfx0273 627 -#define SFXsfx0274 628 -#define SFXpar_b_idle_02 629 -#define SFXpar_b_munch_00 630 -#define SFXsfx0277 631 -#define SFXpar_b_run_00 632 -#define SFXpar_b_run_01 633 -#define SFXsfx027A 634 -#define SFXpar_b_walk_00 635 -#define SFXpar_b_walk_01 636 -#define SFXsfx027D 637 -#define SFXpar_b_idlelone_02 638 -#define SFXpar_r_impact_00 639 -#define SFXsfx0280 640 -#define SFXsfx0281 641 -#define SFXsfx0282 642 -#define SFXsfx0283 643 -#define SFXsfx0284 644 -#define SFXsfx0285 645 -#define SFXsfx0286 646 -#define SFXsfx0287 647 diff --git a/DataSpec/DNAMP1/SFX/Phazon.h b/DataSpec/DNAMP1/SFX/Phazon.h deleted file mode 100644 index 3c85f44b5..000000000 --- a/DataSpec/DNAMP1/SFX/Phazon.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Phazon - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPPhazon 66 - -#define SFXphz_damage_lp 3114 -#define SFXsfx0C2B 3115 -#define SFXsfx0C2C 3116 -#define SFXsfx0C2D 3117 -#define SFXsfx0C2E 3118 -#define SFXsfx0C2F 3119 -#define SFXsfx0C30 3120 diff --git a/DataSpec/DNAMP1/SFX/PhazonGun.h b/DataSpec/DNAMP1/SFX/PhazonGun.h deleted file mode 100644 index a916967dd..000000000 --- a/DataSpec/DNAMP1/SFX/PhazonGun.h +++ /dev/null @@ -1,11 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: PhazonGun - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPPhazonGun 68 - -#define SFXphg_charge_lp 3141 -#define SFXsfx0C46 3142 diff --git a/DataSpec/DNAMP1/SFX/PuddleSpore.h b/DataSpec/DNAMP1/SFX/PuddleSpore.h deleted file mode 100644 index e949065fd..000000000 --- a/DataSpec/DNAMP1/SFX/PuddleSpore.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: PuddleSpore - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPPuddleSpore 23 - -#define SFXsfx0288 648 -#define SFXpds_a_voxactive_00 649 -#define SFXpds_b_bubbles_00 650 -#define SFXpds_b_open_00 651 -#define SFXpds_b_slam_00 652 -#define SFXpds_b_voxopen_lp_00 653 -#define SFXpds_b_voxslam_00 654 -#define SFXpds_b_water_00 655 -#define SFXpds_b_water_01 656 -#define SFXpds_lava_damage_lp 657 -#define SFXsfx0292 658 -#define SFXpds_r_voxpain_02 659 -#define SFXsfx0294 660 -#define SFXsfx0295 661 -#define SFXsfx0296 662 -#define SFXsfx0297 663 -#define SFXsfx0298 664 -#define SFXsfx0299 665 -#define SFXsfx029A 666 -#define SFXsfx029B 667 -#define SFXsfx029C 668 -#define SFXsfx029D 669 -#define SFXsfx029E 670 -#define SFXsfx029F 671 -#define SFXsfx02A0 672 -#define SFXsfx02A1 673 -#define SFXsfx02A2 674 diff --git a/DataSpec/DNAMP1/SFX/PuddleToad.h b/DataSpec/DNAMP1/SFX/PuddleToad.h deleted file mode 100644 index e18b320db..000000000 --- a/DataSpec/DNAMP1/SFX/PuddleToad.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: PuddleToad - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPPuddleToad 24 - -#define SFXpud_a_suckin_00 675 -#define SFXpud_a_spitout_00 676 -#define SFXsfx02A5 677 -#define SFXpud_b_close_00 678 -#define SFXpud_b_splat_00 679 -#define SFXsfx02A8 680 -#define SFXsfx02A9 681 -#define SFXsfx02AA 682 -#define SFXpud_b_voxclose_00 683 -#define SFXpud_a_suckin_lp_01 684 -#define SFXsfx02AD 685 -#define SFXsfx02AE 686 -#define SFXpud_b_growl_00 687 -#define SFXpud_b_squish_lp_00 688 -#define SFXsfx02B1 689 -#define SFXsfx02B2 690 -#define SFXsfx02B3 691 -#define SFXsfx02B4 692 -#define SFXsfx02B5 693 -#define SFXsfx02B6 694 -#define SFXsfx02B7 695 -#define SFXsfx02B8 696 -#define SFXsfx02B9 697 -#define SFXsfx02BA 698 -#define SFXsfx02BB 699 -#define SFXsfx02BC 700 -#define SFXsfx02BD 701 -#define SFXsfx02BE 702 -#define SFXsfx02BF 703 diff --git a/DataSpec/DNAMP1/SFX/Puffer.h b/DataSpec/DNAMP1/SFX/Puffer.h deleted file mode 100644 index b34e47e21..000000000 --- a/DataSpec/DNAMP1/SFX/Puffer.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Puffer - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPPuffer 25 - -#define SFXpuf_b_fly_lp_00 704 -#define SFXsfx02C1 705 -#define SFXsfx02C2 706 -#define SFXsfx02C3 707 -#define SFXsfx02C4 708 -#define SFXsfx02C5 709 -#define SFXsfx02C6 710 diff --git a/DataSpec/DNAMP1/SFX/ReactorDoor.h b/DataSpec/DNAMP1/SFX/ReactorDoor.h deleted file mode 100644 index edc49bd02..000000000 --- a/DataSpec/DNAMP1/SFX/ReactorDoor.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: ReactorDoor - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPReactorDoor 49 - -#define SFXdor_x_close_01 2365 -#define SFXdor_x_open_01 2366 -#define SFXsfx093F 2367 -#define SFXint_x_reacdoor_01 2368 -#define SFXint_x_reacdoor_02 2369 -#define SFXint_x_reacdoor_03 2370 -#define SFXint_x_reacdoor_04 2371 -#define SFXint_x_reacdoor_lp_00 2372 -#define SFXsfx0945 2373 -#define SFXsfx0946 2374 -#define SFXsfx0947 2375 -#define SFXsfx0948 2376 -#define SFXsfx0949 2377 diff --git a/DataSpec/DNAMP1/SFX/Ridley.h b/DataSpec/DNAMP1/SFX/Ridley.h deleted file mode 100644 index f51f875e5..000000000 --- a/DataSpec/DNAMP1/SFX/Ridley.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Ridley - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPRidley 56 - -#define SFXrid_a_flamerake_00 2771 -#define SFXrid_a_flame_lp_00 2772 -#define SFXsfx0AD5 2773 -#define SFXrid_b_flap_00 2774 -#define SFXrid_b_land_00 2775 -#define SFXrid_b_passby_00 2776 -#define SFXrid_b_popup_00 2777 -#define SFXrid_b_voxangry_00 2778 -#define SFXrid_b_voxangry_01 2779 -#define SFXrid_b_voxattack_00 2780 -#define SFXrid_b_voxattack_01 2781 -#define SFXrid_b_voxidle_00 2782 -#define SFXsfx0ADF 2783 -#define SFXrid_b_voxtaunt_00 2784 -#define SFXrid_b_voxtaunt_01 2785 -#define SFXrid_b_walk_00 2786 -#define SFXrid_b_walk_01 2787 -#define SFXsfx0AE4 2788 -#define SFXrid_b_walksm_00 2789 -#define SFXrid_b_walksm_01 2790 -#define SFXrid_r_chestexp_00 2791 -#define SFXrid_r_death_00 2792 -#define SFXrid_r_painbig_00 2793 -#define SFXrid_r_pain_00 2794 -#define SFXsfx0AEB 2795 -#define SFXrid_a_chestglo_00 2796 -#define SFXrid_a_claw_00 2797 -#define SFXsfx0AEE 2798 -#define SFXrid_a_mirv_00 2799 -#define SFXsfx0AF0 2800 -#define SFXrid_a_tail_00 2801 -#define SFXsfx0AF2 2802 -#define SFXsfx0AF3 2803 -#define SFXsfx0AF4 2804 -#define SFXrid_r_pain_lp_00 2805 -#define SFXsfx0AF6 2806 -#define SFXsfx0AF7 2807 -#define SFXsfx0AF8 2808 -#define SFXrid_c_smallexp_00 2809 -#define SFXrid_c_painbig_00 2810 -#define SFXsfx0AFB 2811 -#define SFXsfx0AFC 2812 -#define SFXsfx0AFD 2813 -#define SFXsfx0AFE 2814 -#define SFXsfx0AFF 2815 -#define SFXsfx0B00 2816 -#define SFXsfx0B01 2817 -#define SFXsfx0B02 2818 -#define SFXsfx0B03 2819 -#define SFXsfx0B04 2820 -#define SFXsfx0B05 2821 -#define SFXsfx0B06 2822 -#define SFXsfx0B07 2823 -#define SFXsfx0B08 2824 -#define SFXsfx0B09 2825 -#define SFXsfx0B0A 2826 -#define SFXsfx0B0B 2827 -#define SFXsfx0B0C 2828 -#define SFXsfx0B0D 2829 -#define SFXsfx0B0E 2830 diff --git a/DataSpec/DNAMP1/SFX/Ripper.h b/DataSpec/DNAMP1/SFX/Ripper.h deleted file mode 100644 index 7bc667f86..000000000 --- a/DataSpec/DNAMP1/SFX/Ripper.h +++ /dev/null @@ -1,19 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Ripper - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPRipper 26 - -#define SFXrip_b_float_lp_00 711 -#define SFXrip_b_scream_00 712 -#define SFXsfx02C9 713 -#define SFXsfx02CA 714 -#define SFXrip_r_impact_00 715 -#define SFXsfx02CC 716 -#define SFXsfx02CD 717 -#define SFXsfx02CE 718 -#define SFXsfx02CF 719 -#define SFXsfx02D0 720 diff --git a/DataSpec/DNAMP1/SFX/RuinsWorld.h b/DataSpec/DNAMP1/SFX/RuinsWorld.h deleted file mode 100644 index 9240cf6bc..000000000 --- a/DataSpec/DNAMP1/SFX/RuinsWorld.h +++ /dev/null @@ -1,159 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: RuinsWorld - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPRuinsWorld 50 - -#define SFXsfx094A 2378 -#define SFXsfx094B 2379 -#define SFXsfx094C 2380 -#define SFXsfx094D 2381 -#define SFXeye_b_blink_00 2382 -#define SFXeye_b_impact_00 2383 -#define SFXsfx0950 2384 -#define SFXsfx0951 2385 -#define SFXsfx0952 2386 -#define SFXsfx0953 2387 -#define SFXsfx0954 2388 -#define SFXsfx0955 2389 -#define SFXsfx0956 2390 -#define SFXsfx0957 2391 -#define SFXsfx0958 2392 -#define SFXsfx0959 2393 -#define SFXsfx095A 2394 -#define SFXrui_x_leaves_00 2395 -#define SFXsfx095C 2396 -#define SFXsfx095D 2397 -#define SFXsfx095E 2398 -#define SFXsfx095F 2399 -#define SFXsfx0960 2400 -#define SFXmac_x_stop_00 2401 -#define SFXsfx0962 2402 -#define SFXsfx0963 2403 -#define SFXsfx0964 2404 -#define SFXsfx0965 2405 -#define SFXsfx0966 2406 -#define SFXsfx0967 2407 -#define SFXsfx0968 2408 -#define SFXsfx0969 2409 -#define SFXsfx096A 2410 -#define SFXsfx096B 2411 -#define SFXsfx096C 2412 -#define SFXsfx096D 2413 -#define SFXsfx096E 2414 -#define SFXsfx096F 2415 -#define SFXenc_x_genmove_lp_00 2416 -#define SFXsfx0971 2417 -#define SFXsfx0972 2418 -#define SFXsfx0973 2419 -#define SFXsfx0974 2420 -#define SFXhiv_x_fall_lp_00 2421 -#define SFXsfx0976 2422 -#define SFXsfx0977 2423 -#define SFXhiv_x_open_00 2424 -#define SFXsfx0979 2425 -#define SFXhiv_x_rotate_00 2426 -#define SFXhiv_x_stop_00 2427 -#define SFXsfx097C 2428 -#define SFXsfx097D 2429 -#define SFXrui_x_mapmove_lp_01 2430 -#define SFXsfx097F 2431 -#define SFXsfx0980 2432 -#define SFXsfx0981 2433 -#define SFXsfx0982 2434 -#define SFXsfx0983 2435 -#define SFXhiv_x_closered_lp_00 2436 -#define SFXhiv_x_openred_lp_00 2437 -#define SFXsfx0986 2438 -#define SFXsfx0987 2439 -#define SFXchz_b_balldrop_00 2440 -#define SFXchz_b_balldrop_01 2441 -#define SFXchz_b_release_00 2442 -#define SFXchz_x_down_lp_00 2443 -#define SFXsfx098C 2444 -#define SFXsfx098D 2445 -#define SFXsfx098E 2446 -#define SFXsfx098F 2447 -#define SFXsfx0990 2448 -#define SFXsfx0991 2449 -#define SFXsfx0992 2450 -#define SFXsfx0993 2451 -#define SFXsfx0994 2452 -#define SFXsfx0995 2453 -#define SFXsfx0996 2454 -#define SFXsfx0997 2455 -#define SFXsfx0998 2456 -#define SFXrui_x_mirstop_00 2457 -#define SFXsfx099A 2458 -#define SFXrui_x_slotstop_00 2459 -#define SFXfla_b_bulbopen_00 2460 -#define SFXsfx099D 2461 -#define SFXsfx099E 2462 -#define SFXsfx099F 2463 -#define SFXsfx09A0 2464 -#define SFXsfx09A1 2465 -#define SFXsfx09A2 2466 -#define SFXsfx09A3 2467 -#define SFXsfx09A4 2468 -#define SFXrui_x_flamarmr_00 2469 -#define SFXrui_x_flamarmr_01 2470 -#define SFXrui_x_flamarm_00 2471 -#define SFXrui_x_flamarm_01 2472 -#define SFXrui_x_flamarm_02 2473 -#define SFXrui_x_flamrise_00 2474 -#define SFXrui_x_flamrise_lp_00 2475 -#define SFXrui_x_flamhead_00 2476 -#define SFXrui_x_flamhead_lp_00 2477 -#define SFXrui_x_flamhead_lp_01 2478 -#define SFXsfx09AF 2479 -#define SFXsfx09B0 2480 -#define SFXsfx09B1 2481 -#define SFXsfx09B2 2482 -#define SFXsfx09B3 2483 -#define SFXsfx09B4 2484 -#define SFXsfx09B5 2485 -#define SFXsfx09B6 2486 -#define SFXsfx09B7 2487 -#define SFXsfx09B8 2488 -#define SFXrui_x_mapmove_lp_00 2489 -#define SFXsfx09BA 2490 -#define SFXrui_x_maparm_00 2491 -#define SFXrui_x_mapcover_00 2492 -#define SFXsfx09BD 2493 -#define SFXsfx09BE 2494 -#define SFXsfx09BF 2495 -#define SFXsfx09C0 2496 -#define SFXsfx09C1 2497 -#define SFXsfx09C2 2498 -#define SFXsfx09C3 2499 -#define SFXsfx09C4 2500 -#define SFXmac_x_changed_00 2501 -#define SFXsfx09C6 2502 -#define SFXrui_x_mapstop_00 2503 -#define SFXsfx09C8 2504 -#define SFXrui_x_gatedown_lp_00 2505 -#define SFXsfx09CA 2506 -#define SFXrui_x_gatestop_00 2507 -#define SFXrui_x_gateturn_lp_00 2508 -#define SFXsfx09CD 2509 -#define SFXrui_x_halftrk_00 2510 -#define SFXrui_x_halftrk_lp_00 2511 -#define SFXsfx09D0 2512 -#define SFXsfx09D1 2513 -#define SFXsfx09D2 2514 -#define SFXsfx09D3 2515 -#define SFXdob_x_moveup_lp_00 2516 -#define SFXsfx09D5 2517 -#define SFXsfx09D6 2518 -#define SFXsfx09D7 2519 -#define SFXsfx09D8 2520 -#define SFXsfx09D9 2521 -#define SFXsfx09DA 2522 -#define SFXsfx09DB 2523 -#define SFXsfx09DC 2524 -#define SFXsfx09DD 2525 -#define SFXsfx09DE 2526 -#define SFXsfx09DF 2527 diff --git a/DataSpec/DNAMP1/SFX/SFX.h b/DataSpec/DNAMP1/SFX/SFX.h deleted file mode 100644 index 4bf0e640b..000000000 --- a/DataSpec/DNAMP1/SFX/SFX.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef DNAMP1_SFX_H -#define DNAMP1_SFX_H - -#include "Atomic.h" -#include "BetaBeetle.h" -#include "Bird.h" -#include "BloodFlower.h" -#include "Burrower.h" -#include "ChozoGhost.h" -#include "ChubbWeed.h" -#include "CineBoots.h" -#include "CineGeneral.h" -#include "CineGun.h" -#include "CineMorphball.h" -#include "CineSuit.h" -#include "CineVisor.h" -#include "Crater.h" -#include "Crystallite.h" -#include "Drones.h" -#include "EliteSpacePirate.h" -#include "FireFlea.h" -#include "Flaaghra.h" -#include "FlickerBat.h" -#include "FlyingPirate.h" -#include "FrontEnd.h" -#include "GagantuanBeatle.h" -#include "Gnats.h" -#include "Gryzbee.h" -#include "IceCrack.h" -#include "IceWorld.h" -#include "InjuredPirates.h" -#include "IntroBoss.h" -#include "IntroWorld.h" -#include "JellyZap.h" -#include "LavaWorld.h" -#include "Magdolite.h" -#include "Metaree.h" -#include "MetroidPrime.h" -#include "Metroid.h" -#include "MinesWorld.h" -#include "MiscSamus.h" -#include "Misc.h" -#include "OmegaPirate.h" -#include "OverWorld.h" -#include "Parasite.h" -#include "PhazonGun.h" -#include "Phazon.h" -#include "PuddleSpore.h" -#include "PuddleToad.h" -#include "Puffer.h" -#include "ReactorDoor.h" -#include "Ridley.h" -#include "Ripper.h" -#include "RuinsWorld.h" -#include "SFX.h" -#include "SamusShip.h" -#include "Scarab.h" -#include "Seedling.h" -#include "SheeGoth.h" -#include "SnakeWeed.h" -#include "Sova.h" -#include "SpacePirate.h" -#include "SpankWeed.h" -#include "Thardus.h" -#include "TheEnd.h" -#include "Torobyte.h" -#include "Triclops.h" -#include "Turret.h" -#include "UI.h" -#include "WarWasp.h" -#include "Weapons.h" -#include "ZZZ.h" -#include "Zoomer.h" -#include "lumigek.h" -#include "test.h" - -#endif // DNAMP1_SFX_H diff --git a/DataSpec/DNAMP1/SFX/SamusShip.h b/DataSpec/DNAMP1/SFX/SamusShip.h deleted file mode 100644 index a726becf4..000000000 --- a/DataSpec/DNAMP1/SFX/SamusShip.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: SamusShip - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPSamusShip 42 - -#define SFXsas_x_dooropen_00 1724 -#define SFXsas_x_dooropen_01 1725 -#define SFXsas_x_dooropen_02 1726 -#define SFXsas_x_dooropen_03 1727 -#define SFXsas_x_dooropen_04 1728 -#define SFXsas_x_dooropen_05 1729 -#define SFXsfx06C2 1730 -#define SFXsas_x_platrise_lp_01 1731 -#define SFXsas_x_thrusmov_00 1732 -#define SFXsfx06C5 1733 -#define SFXsas_x_thrusmov_02 1734 -#define SFXsas_x_thrusmov_03 1735 -#define SFXsas_x_hover_lp_00 1736 -#define SFXsas_x_thrusfir_lp_01 1737 -#define SFXsas_x_hover_lp_01 1738 -#define SFXsfx06CB 1739 -#define SFXsas_x_thrusfir_lp_04 1740 -#define SFXsfx06CD 1741 -#define SFXsfx06CE 1742 -#define SFXsfx06CF 1743 -#define SFXsfx06D0 1744 -#define SFXsfx06D1 1745 -#define SFXsfx06D2 1746 -#define SFXsfx06D3 1747 -#define SFXsfx06D4 1748 -#define SFXsfx06D5 1749 -#define SFXsfx06D6 1750 -#define SFXsfx06D7 1751 -#define SFXsfx06D8 1752 -#define SFXsfx06D9 1753 -#define SFXsfx06DA 1754 -#define SFXsfx06DB 1755 diff --git a/DataSpec/DNAMP1/SFX/Scarab.h b/DataSpec/DNAMP1/SFX/Scarab.h deleted file mode 100644 index 414bc5194..000000000 --- a/DataSpec/DNAMP1/SFX/Scarab.h +++ /dev/null @@ -1,17 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Scarab - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPScarab 27 - -#define SFXsfx02D1 721 -#define SFXsfx02D2 722 -#define SFXsfx02D3 723 -#define SFXsfx02D4 724 -#define SFXsfx02D5 725 -#define SFXsfx02D6 726 -#define SFXsfx02D7 727 -#define SFXsfx02D8 728 diff --git a/DataSpec/DNAMP1/SFX/Seedling.h b/DataSpec/DNAMP1/SFX/Seedling.h deleted file mode 100644 index 6ce1a1f34..000000000 --- a/DataSpec/DNAMP1/SFX/Seedling.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Seedling - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPSeedling 28 - -#define SFXsed_a_spine_00 729 -#define SFXsed_b_idle_lp_00 730 -#define SFXsfx02DB 731 -#define SFXsfx02DC 732 -#define SFXsed_b_alert_00 733 -#define SFXsfx02DE 734 -#define SFXsfx02DF 735 -#define SFXsfx02E0 736 -#define SFXsfx02E1 737 -#define SFXsfx02E2 738 -#define SFXsfx02E3 739 -#define SFXsfx02E4 740 -#define SFXsfx02E5 741 -#define SFXsfx02E6 742 -#define SFXsfx02E7 743 -#define SFXsfx02E8 744 -#define SFXsfx02E9 745 -#define SFXsfx02EA 746 -#define SFXsfx02EB 747 -#define SFXsfx02EC 748 diff --git a/DataSpec/DNAMP1/SFX/SheeGoth.h b/DataSpec/DNAMP1/SFX/SheeGoth.h deleted file mode 100644 index 0445d9ed5..000000000 --- a/DataSpec/DNAMP1/SFX/SheeGoth.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: SheeGoth - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPSheeGoth 29 - -#define SFXshe_a_fireball_00 749 -#define SFXshe_b_shake_lp_00 750 -#define SFXsfx02EF 751 -#define SFXshe_a_flame_lp_00 752 -#define SFXshe_a_snap_00 753 -#define SFXshe_a_snap_01 754 -#define SFXshe_a_stomp_00 755 -#define SFXshe_a_stomp_01 756 -#define SFXshe_a_voxangry_00 757 -#define SFXshe_a_voxangry_01 758 -#define SFXshe_a_voxangry_03 759 -#define SFXshe_a_voxangry_04 760 -#define SFXsh2_a_voxangry_00 761 -#define SFXsfx02FA 762 -#define SFXsfx02FB 763 -#define SFXshe_b_idle_02 764 -#define SFXsh2_a_voxangry_01 765 -#define SFXshe_b_land_00 766 -#define SFXsh2_a_flame_lp_00 767 -#define SFXshe_b_roar_00 768 -#define SFXsh2_a_snap_00 769 -#define SFXsh2_a_voxangry_03 770 -#define SFXsh2_a_snap_01 771 -#define SFXshe_b_walk_00 772 -#define SFXshe_b_walk_01 773 -#define SFXshe_r_death_00 774 -#define SFXshe_r_death_01 775 -#define SFXshe_r_pain_00 776 -#define SFXsfx0309 777 -#define SFXsh2_a_voxangry_04 778 -#define SFXsfx030B 779 -#define SFXsfx030C 780 -#define SFXsh2_b_idle_02 781 -#define SFXsh2_b_land_00 782 -#define SFXsh2_b_roar_00 783 -#define SFXsh2_b_shake_lp_00 784 -#define SFXsh2_b_walk_00 785 -#define SFXsh2_b_walk_01 786 -#define SFXsh2_r_death_00 787 -#define SFXsh2_r_death_01 788 -#define SFXsh2_r_pain_00 789 -#define SFXsfx0316 790 -#define SFXsfx0317 791 -#define SFXsh2_b_run_00 792 -#define SFXsh2_b_run_01 793 -#define SFXsfx031A 794 -#define SFXsfx031B 795 -#define SFXsfx031C 796 -#define SFXsfx031D 797 -#define SFXsfx031E 798 -#define SFXsfx031F 799 -#define SFXsfx0320 800 -#define SFXsfx0321 801 -#define SFXsfx0322 802 -#define SFXsfx0323 803 -#define SFXsfx0324 804 -#define SFXsfx0325 805 diff --git a/DataSpec/DNAMP1/SFX/SnakeWeed.h b/DataSpec/DNAMP1/SFX/SnakeWeed.h deleted file mode 100644 index 091564e47..000000000 --- a/DataSpec/DNAMP1/SFX/SnakeWeed.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: SnakeWeed - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPSnakeWeed 30 - -#define SFXsfx0326 806 -#define SFXsnk_b_in_00 807 -#define SFXsnk_b_out_00 808 -#define SFXsfx0329 809 -#define SFXsfx032A 810 -#define SFXsfx032B 811 diff --git a/DataSpec/DNAMP1/SFX/Sova.h b/DataSpec/DNAMP1/SFX/Sova.h deleted file mode 100644 index d293ff7f7..000000000 --- a/DataSpec/DNAMP1/SFX/Sova.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Sova - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPSova 31 - -#define SFXfpr_b_walk_00 812 -#define SFXfpr_b_walk_01 813 -#define SFXspr_a_gun_00 814 -#define SFXsfx032F 815 -#define SFXsfx0330 816 -#define SFXspr_b_walk_00 817 -#define SFXspr_b_walk_01 818 -#define SFXspr_b_walk_02 819 -#define SFXspr_b_walk_03 820 -#define SFXsfx0335 821 -#define SFXsfx0336 822 -#define SFXsfx0337 823 -#define SFXsfx0338 824 -#define SFXsfx0339 825 -#define SFXsfx033A 826 -#define SFXsfx033B 827 -#define SFXsfx033C 828 -#define SFXsfx033D 829 -#define SFXsfx033E 830 diff --git a/DataSpec/DNAMP1/SFX/SpacePirate.h b/DataSpec/DNAMP1/SFX/SpacePirate.h deleted file mode 100644 index d63dc5f22..000000000 --- a/DataSpec/DNAMP1/SFX/SpacePirate.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: SpacePirate - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPSpacePirate 32 - -#define SFXsfx033F 831 -#define SFXepr_b_swordin_00 832 -#define SFXepr_b_swordout_00 833 -#define SFXopr_c_movement_00 834 -#define SFXsfx0343 835 -#define SFXsfx0344 836 -#define SFXsfx0345 837 -#define SFXsfx0346 838 -#define SFXsfx0347 839 -#define SFXspr_b_movement_00 840 -#define SFXspr_b_movement_01 841 -#define SFXsfx034A 842 -#define SFXsfx034B 843 -#define SFXsfx034C 844 -#define SFXsfx034D 845 -#define SFXspr_b_voxalert_01 846 -#define SFXsfx034F 847 -#define SFXsfx0350 848 -#define SFXsfx0351 849 -#define SFXsfx0352 850 -#define SFXsfx0353 851 -#define SFXsfx0354 852 -#define SFXsfx0355 853 -#define SFXsfx0356 854 -#define SFXspr_r_impact_02 855 -#define SFXopr_b_swordin_00 856 -#define SFXsfx0359 857 -#define SFXsfx035A 858 -#define SFXsfx035B 859 -#define SFXspr_b_idle_02 860 -#define SFXspr_b_intruder_00 861 -#define SFXsfx035E 862 -#define SFXsfx035F 863 -#define SFXsfx0360 864 -#define SFXsfx0361 865 -#define SFXopr_b_swordout_00 866 -#define SFXspr_r_himpact_00 867 -#define SFXsfx0364 868 -#define SFXspr_b_jump_00 869 -#define SFXsfx0366 870 -#define SFXsfx0367 871 -#define SFXsfx0368 872 -#define SFXspr_b_voxangry_02 873 -#define SFXsfx036A 874 -#define SFXsfx036B 875 -#define SFXsfx036C 876 -#define SFXsfx036D 877 -#define SFXsfx036E 878 -#define SFXsfx036F 879 -#define SFXsfx0370 880 -#define SFXsfx0371 881 -#define SFXsfx0372 882 -#define SFXsfx0373 883 -#define SFXepr_b_movement_00 884 -#define SFXepr_b_movement_01 885 -#define SFXsfx0376 886 -#define SFXsfx0377 887 -#define SFXsfx0378 888 -#define SFXsfx0379 889 -#define SFXsfx037A 890 -#define SFXsfx037B 891 -#define SFXepr_r_die_00 892 -#define SFXsfx037D 893 -#define SFXepr_r_pain_00 894 -#define SFXsfx037F 895 -#define SFXsfx0380 896 -#define SFXsfx0381 897 -#define SFXsfx0382 898 -#define SFXsfx0383 899 -#define SFXsfx0384 900 -#define SFXsfx0385 901 -#define SFXsfx0386 902 -#define SFXsfx0387 903 -#define SFXsfx0388 904 -#define SFXsfx0389 905 -#define SFXsfx038A 906 -#define SFXsfx038B 907 -#define SFXsfx038C 908 -#define SFXsfx038D 909 -#define SFXsfx038E 910 -#define SFXsfx038F 911 -#define SFXsfx0390 912 -#define SFXsfx0391 913 -#define SFXsfx0392 914 diff --git a/DataSpec/DNAMP1/SFX/SpankWeed.h b/DataSpec/DNAMP1/SFX/SpankWeed.h deleted file mode 100644 index d48e60e36..000000000 --- a/DataSpec/DNAMP1/SFX/SpankWeed.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: SpankWeed - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPSpankWeed 33 - -#define SFXspw_a_spank_00 915 -#define SFXsfx0394 916 -#define SFXspw_b_out_00 917 -#define SFXspw_b_swish_02 918 -#define SFXspw_b_swoosh_00 919 -#define SFXsfx0398 920 -#define SFXspw_r_impact_00 921 -#define SFXsfx039A 922 -#define SFXfla_a_tentatak_00 923 -#define SFXsfx039C 924 -#define SFXsfx039D 925 -#define SFXsfx039E 926 -#define SFXsfx039F 927 -#define SFXsfx03A0 928 -#define SFXsfx03A1 929 -#define SFXsfx03A2 930 -#define SFXfla_b_tentmove_01 931 -#define SFXfla_b_tentslid_00 932 -#define SFXfla_b_tentslid_01 933 -#define SFXsfx03A6 934 -#define SFXsfx03A7 935 -#define SFXsfx03A8 936 -#define SFXsfx03A9 937 -#define SFXsfx03AA 938 -#define SFXsfx03AB 939 -#define SFXsfx03AC 940 -#define SFXsfx03AD 941 -#define SFXsfx03AE 942 -#define SFXsfx03AF 943 -#define SFXsfx03B0 944 -#define SFXsfx03B1 945 -#define SFXsfx03B2 946 -#define SFXsfx03B3 947 -#define SFXsfx03B4 948 -#define SFXsfx03B5 949 -#define SFXsfx03B6 950 -#define SFXsfx03B7 951 -#define SFXsfx03B8 952 -#define SFXsfx03B9 953 -#define SFXsfx03BA 954 -#define SFXsfx03BB 955 -#define SFXsfx03BC 956 -#define SFXsfx03BD 957 -#define SFXsfx03BE 958 -#define SFXsfx03BF 959 diff --git a/DataSpec/DNAMP1/SFX/Thardus.h b/DataSpec/DNAMP1/SFX/Thardus.h deleted file mode 100644 index 781b57ef6..000000000 --- a/DataSpec/DNAMP1/SFX/Thardus.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Thardus - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPThardus 55 - -#define SFXtha_b_voxangry_02 2703 -#define SFXtha_b_move_00 2704 -#define SFXsfx0A91 2705 -#define SFXtha_b_rocks_00 2706 -#define SFXtha_a_stoneup_lp_00 2707 -#define SFXtha_a_swoosh_00 2708 -#define SFXsfx0A95 2709 -#define SFXtha_a_voxattak_00 2710 -#define SFXtha_a_voxattak_01 2711 -#define SFXtha_b_henshin_lp_00 2712 -#define SFXtha_b_hitgrnd_00 2713 -#define SFXtha_b_hitgrnd_01 2714 -#define SFXtha_b_hitgrnd_02 2715 -#define SFXtha_b_charge_00 2716 -#define SFXtha_a_thunder_00 2717 -#define SFXtha_b_rocks_lp_00 2718 -#define SFXsfx0A9F 2719 -#define SFXtha_b_roll_lp_00 2720 -#define SFXsfx0AA1 2721 -#define SFXtha_b_voxangry_00 2722 -#define SFXtha_b_voxangry_01 2723 -#define SFXtha_b_walk_00 2724 -#define SFXtha_b_walk_01 2725 -#define SFXsfx0AA6 2726 -#define SFXtha_r_pain_00 2727 -#define SFXtha_b_boulder_00 2728 -#define SFXtha_b_boulder_01 2729 -#define SFXsfx0AAA 2730 -#define SFXtha_b_henshin_00 2731 -#define SFXtha_b_henshin_01 2732 -#define SFXsfx0AAD 2733 -#define SFXtha_a_icewave_lp_00 2734 -#define SFXtha_b_chant_00 2735 -#define SFXtha_b_enraged_00 2736 -#define SFXtha_b_charge_01 2737 -#define SFXtha_b_charge_02 2738 -#define SFXtha_b_walk_02 2739 -#define SFXtha_b_walk_03 2740 -#define SFXtha_a_thunder_01 2741 -#define SFXsfx0AB6 2742 -#define SFXsfx0AB7 2743 -#define SFXsfx0AB8 2744 -#define SFXtha_a_icestorm_lp_02 2745 -#define SFXsfx0ABA 2746 -#define SFXsfx0ABB 2747 -#define SFXsfx0ABC 2748 -#define SFXtha_b_idle_00 2749 -#define SFXsfx0ABE 2750 -#define SFXsfx0ABF 2751 -#define SFXsfx0AC0 2752 -#define SFXtha_b_charge_03 2753 -#define SFXtha_r_smpain_00 2754 -#define SFXsfx0AC3 2755 -#define SFXtha_r_pissed_00 2756 -#define SFXsfx0AC5 2757 -#define SFXsfx0AC6 2758 -#define SFXsfx0AC7 2759 -#define SFXsfx0AC8 2760 -#define SFXsfx0AC9 2761 -#define SFXsfx0ACA 2762 -#define SFXsfx0ACB 2763 -#define SFXsfx0ACC 2764 -#define SFXsfx0ACD 2765 -#define SFXsfx0ACE 2766 -#define SFXsfx0ACF 2767 -#define SFXsfx0AD0 2768 -#define SFXsfx0AD1 2769 -#define SFXsfx0AD2 2770 diff --git a/DataSpec/DNAMP1/SFX/TheEnd.h b/DataSpec/DNAMP1/SFX/TheEnd.h deleted file mode 100644 index 3df4c24ae..000000000 --- a/DataSpec/DNAMP1/SFX/TheEnd.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: TheEnd - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPTheEnd 70 - -#define SFXsfx0C4D 3149 -#define SFXsh2_a_fireball_lp_00 3150 -#define SFXshe_a_fireball_lp_00 3151 -#define SFXend_c_shipthst_00 3152 -#define SFXsfx0C51 3153 -#define SFXsfx0C52 3154 -#define SFXsfx0C53 3155 -#define SFXsfx0C54 3156 -#define SFXsfx0C55 3157 -#define SFXsfx0C56 3158 -#define SFXsfx0C57 3159 -#define SFXsfx0C58 3160 -#define SFXsfx0C59 3161 -#define SFXsfx0C5A 3162 -#define SFXsfx0C5B 3163 -#define SFXsfx0C5C 3164 -#define SFXsfx0C5D 3165 -#define SFXsfx0C5E 3166 diff --git a/DataSpec/DNAMP1/SFX/Torobyte.h b/DataSpec/DNAMP1/SFX/Torobyte.h deleted file mode 100644 index cea96f914..000000000 --- a/DataSpec/DNAMP1/SFX/Torobyte.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Torobyte - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPToroByte 35 - -#define SFXocu_b_idle_00 981 -#define SFXsfx03D6 982 -#define SFXocu_b_blink_00 983 -#define SFXsfx03D8 984 -#define SFXbat_r_voxdeath_00 985 -#define SFXsfx03DA 986 -#define SFXsfx03DB 987 -#define SFXsfx03DC 988 -#define SFXsfx03DD 989 -#define SFXsfx03DE 990 -#define SFXsfx03DF 991 -#define SFXsfx03E0 992 -#define SFXsfx03E1 993 -#define SFXsfx03E2 994 -#define SFXsfx03E3 995 -#define SFXsfx03E4 996 -#define SFXsfx03E5 997 -#define SFXsfx03E6 998 -#define SFXsfx03E7 999 diff --git a/DataSpec/DNAMP1/SFX/Triclops.h b/DataSpec/DNAMP1/SFX/Triclops.h deleted file mode 100644 index c36824ccc..000000000 --- a/DataSpec/DNAMP1/SFX/Triclops.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Triclops - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPTriclops 34 - -#define SFXtri_a_attack_00 960 -#define SFXtri_a_attract_00 961 -#define SFXtri_b_idle_00 962 -#define SFXsfx03C3 963 -#define SFXtri_b_walk_00 964 -#define SFXsfx03C5 965 -#define SFXsfx03C6 966 -#define SFXtri_r_impact_00 967 -#define SFXtri_r_impact_01 968 -#define SFXtri_b_run_00 969 -#define SFXsfx03CA 970 -#define SFXsfx03CB 971 -#define SFXsfx03CC 972 -#define SFXsfx03CD 973 -#define SFXsfx03CE 974 -#define SFXsfx03CF 975 -#define SFXsfx03D0 976 -#define SFXsfx03D1 977 -#define SFXsfx03D2 978 -#define SFXsfx03D3 979 -#define SFXsfx03D4 980 diff --git a/DataSpec/DNAMP1/SFX/Turret.h b/DataSpec/DNAMP1/SFX/Turret.h deleted file mode 100644 index d0fedfb4f..000000000 --- a/DataSpec/DNAMP1/SFX/Turret.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Turret - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPTurret 36 - -#define SFXsfx03E8 1000 -#define SFXtur_a_laser_00 1001 -#define SFXsfx03EA 1002 -#define SFXsfx03EB 1003 -#define SFXsfx03EC 1004 -#define SFXsfx03ED 1005 -#define SFXsfx03EE 1006 -#define SFXsfx03EF 1007 -#define SFXtur_b_lower_00 1008 -#define SFXsfx03F1 1009 -#define SFXsfx03F2 1010 -#define SFXtur_b_raise_lp_00 1011 -#define SFXtur_b_stop_00 1012 -#define SFXsfx03F5 1013 -#define SFXtur_b_sweep_lp_00 1014 -#define SFXsfx03F7 1015 -#define SFXsfx03F8 1016 -#define SFXsfx03F9 1017 -#define SFXsfx03FA 1018 -#define SFXtur_r_powrdown_lp_00 1019 -#define SFXsfx03FC 1020 -#define SFXsfx03FD 1021 -#define SFXsfx03FE 1022 -#define SFXsfx03FF 1023 -#define SFXsfx0400 1024 -#define SFXsfx0401 1025 -#define SFXsfx0402 1026 diff --git a/DataSpec/DNAMP1/SFX/UI.h b/DataSpec/DNAMP1/SFX/UI.h deleted file mode 100644 index a2a680eb2..000000000 --- a/DataSpec/DNAMP1/SFX/UI.h +++ /dev/null @@ -1,99 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: UI - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPUI 40 - -#define SFXui_map_rotate 1375 -#define SFXui_map_zoom 1376 -#define SFXui_lockon_poi 1377 -#define SFXui_into_map_screen 1378 -#define SFXsfx0563 1379 -#define SFXui_outof_map_screen 1380 -#define SFXsfx0565 1381 -#define SFXui_outof_visor 1382 -#define SFXui_into_visor 1383 -#define SFXui_visor_xray_lp 1384 -#define SFXui_damage_lp 1385 -#define SFXui_show_local_beacon 1386 -#define SFXui_show_remote_beacon 1387 -#define SFXui_visor_thermal_lp 1388 -#define SFXsfx056D 1389 -#define SFXui_outof_freelook 1390 -#define SFXsfx056F 1391 -#define SFXui_into_freelook 1392 -#define SFXui_lockon_grapple 1393 -#define SFXui_freelook_move_lp 1394 -#define SFXui_select_visor 1395 -#define SFXui_threat_warning 1396 -#define SFXui_missile_warning 1397 -#define SFXui_select_beam 1398 -#define SFXui_threat_damage 1399 -#define SFXui_hud_shutdown 1400 -#define SFXui_hud_reboot 1401 -#define SFXui_static_hi 1402 -#define SFXui_static_lo 1403 -#define SFXui_visor_scan_lp 1404 -#define SFXui_energy_low 1405 -#define SFXui_map_pan 1406 -#define SFXui_scanning_lp 1407 -#define SFXsfx0580 1408 -#define SFXui_outof_scan_window 1409 -#define SFXsfx0582 1410 -#define SFXui_into_scan_window 1411 -#define SFXsfx0584 1412 -#define SFXsfx0585 1413 -#define SFXui_scan_pane_reveal 1414 -#define SFXui_into_hud_message 1415 -#define SFXui_outof_hud_message 1416 -#define SFXui_scan_complete 1417 -#define SFXui_hud_memo_type 1418 -#define SFXsfx058B 1419 -#define SFXsfx058C 1420 -#define SFXui_message_screen_key 1421 -#define SFXui_options_quit_accept 1422 -#define SFXui_options_quit_reject 1423 -#define SFXui_quit_change 1424 -#define SFXui_new_scan_complete 1425 -#define SFXui_map_to_universe 1426 -#define SFXui_map_from_universe 1427 -#define SFXsfx0594 1428 -#define SFXsfx0595 1429 -#define SFXsfx0596 1430 -#define SFXui_table_change_mode 1431 -#define SFXui_advance 1432 -#define SFXui_pause_screen_change 1433 -#define SFXui_pause_screen_exit 1434 -#define SFXui_pause_screen_enter 1435 -#define SFXui_table_selection_change 1436 -#define SFXui_option_enum_change 1437 -#define SFXsfx059E 1438 -#define SFXui_scan_next_page 1439 -#define SFXui_samus_doll_enter 1440 -#define SFXui_samus_doll_exit 1441 -#define SFXui_hud_memo_a_pulse 1442 -#define SFXui_show_hint_memo 1443 -#define SFXui_pause_screen_next_page 1444 -#define SFXsfx05A5 1445 -#define SFXui_map_screen_key2 1446 -#define SFXsfx05A7 1447 -#define SFXsfx05A8 1448 -#define SFXui_hide_hint_memo 1449 -#define SFXsfx05AA 1450 -#define SFXui_options_slider_change_lp 1451 -#define SFXui_map_screen_key1 1452 -#define SFXui_map_screen_key0 1453 -#define SFXsfx05AE 1454 -#define SFXsfx05AF 1455 -#define SFXsfx05B0 1456 -#define SFXsfx05B1 1457 -#define SFXui_frontend_options_slider_change_lp 1458 -#define SFXui_frontend_save_back 1459 -#define SFXui_frontend_save_confirm 1460 -#define SFXui_frontend_save_move 1461 -#define SFXsfx05B6 1462 -#define SFXsfx05B7 1463 -#define SFXsfx05B8 1464 diff --git a/DataSpec/DNAMP1/SFX/WarWasp.h b/DataSpec/DNAMP1/SFX/WarWasp.h deleted file mode 100644 index 138619f46..000000000 --- a/DataSpec/DNAMP1/SFX/WarWasp.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: WarWasp - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPWarWasp 37 - -#define SFXwar_b_idle_lp_00 1027 -#define SFXwa2_a_stinger_00 1028 -#define SFXwa2_b_idle_lp_00 1029 -#define SFXwa2_r_diescream_00 1030 -#define SFXwa2_r_hitlight_00 1031 -#define SFXwa2_r_wingbuzz_00 1032 -#define SFXwar_r_diescream_00 1033 -#define SFXwar_r_diescream_01 1034 -#define SFXwar_r_diescream_02 1035 -#define SFXwar_r_diescream_03 1036 -#define SFXwar_r_hitdirt_00 1037 -#define SFXwar_r_hitdirt_01 1038 -#define SFXwar_r_hitlight_00 1039 -#define SFXwar_r_hitlight_01 1040 -#define SFXwar_r_wingbuzz_00 1041 -#define SFXwar_r_wingbuzz_01 1042 -#define SFXwar_r_wingbuzz_02 1043 -#define SFXwar_r_wingbuzz_03 1044 -#define SFXsfx0415 1045 -#define SFXwa2_r_wingbuzz_01 1046 -#define SFXwar_a_stab_00 1047 -#define SFXwar_b_noise_00 1048 -#define SFXwar_b_noise_01 1049 -#define SFXwa3_a_stab_00 1050 -#define SFXwa3_a_stab_01 1051 -#define SFXwa2_b_noise_00 1052 -#define SFXwa2_b_noise_01 1053 -#define SFXwar_a_stab_01 1054 -#define SFXwar_a_stinger_00 1055 -#define SFXwar_r_wingbuzz_04 1056 -#define SFXsfx0421 1057 -#define SFXsfx0422 1058 -#define SFXwa2_b_agitated_lp_00 1059 -#define SFXsfx0424 1060 -#define SFXwa2_b_noise_02 1061 -#define SFXwar_b_agitated_lp_00 1062 -#define SFXwa3_a_voxattak_00 1063 -#define SFXwar_b_noise_02 1064 -#define SFXwa3_b_agitated_lp_00 1065 -#define SFXwa3_b_idle_lp_00 1066 -#define SFXsfx042B 1067 -#define SFXwa3_b_noise_00 1068 -#define SFXsfx042D 1069 -#define SFXwa3_b_noise_02 1070 -#define SFXwa3_r_hitlight_00 1071 -#define SFXwa3_r_wingbuzz_00 1072 -#define SFXglo_b_fly_lp_00 1073 -#define SFXwa3_r_wingbuzz_02 1074 -#define SFXsfx0433 1075 -#define SFXsfx0434 1076 -#define SFXsfx0435 1077 -#define SFXsfx0436 1078 -#define SFXsfx0437 1079 -#define SFXsfx0438 1080 -#define SFXsfx0439 1081 -#define SFXsfx043A 1082 -#define SFXsfx043B 1083 -#define SFXsfx043C 1084 -#define SFXsfx043D 1085 -#define SFXsfx043E 1086 -#define SFXsfx043F 1087 -#define SFXsfx0440 1088 -#define SFXsfx0441 1089 diff --git a/DataSpec/DNAMP1/SFX/Weapons.h b/DataSpec/DNAMP1/SFX/Weapons.h deleted file mode 100644 index bd30784e0..000000000 --- a/DataSpec/DNAMP1/SFX/Weapons.h +++ /dev/null @@ -1,145 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Weapons - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPWeapons 43 - -#define SFXwpn_bomb_drop 1756 -#define SFXsfx06DD 1757 -#define SFXwpn_bomb_explo 1758 -#define SFXwpn_chargeup_ice 1759 -#define SFXsfx06E0 1760 -#define SFXsfx06E1 1761 -#define SFXwpn_combo_xfer 1762 -#define SFXwpn_empty_action 1763 -#define SFXsfx06E4 1764 -#define SFXsfx06E5 1765 -#define SFXwpn_chargeup_power 1766 -#define SFXwpn_fire_power_charged 1767 -#define SFXwpn_fire_missile 1768 -#define SFXwpn_reload_missile 1769 -#define SFXwpn_fire_power_normal 1770 -#define SFXsfx06EB 1771 -#define SFXsfx06EC 1772 -#define SFXsfx06ED 1773 -#define SFXwpn_morph_out_wipe 1774 -#define SFXwpn_morph_in_wipe_done 1775 -#define SFXwpn_fire_ice_charged 1776 -#define SFXsfx06F1 1777 -#define SFXsfx06F2 1778 -#define SFXsfx06F3 1779 -#define SFXsfx06F4 1780 -#define SFXwpn_invalid_action 1781 -#define SFXsfx06F6 1782 -#define SFXsfx06F7 1783 -#define SFXsfx06F8 1784 -#define SFXsfx06F9 1785 -#define SFXsfx06FA 1786 -#define SFXsfx06FB 1787 -#define SFXsfx06FC 1788 -#define SFXsfx06FD 1789 -#define SFXsfx06FE 1790 -#define SFXsfx06FF 1791 -#define SFXsfx0700 1792 -#define SFXsfx0701 1793 -#define SFXsfx0702 1794 -#define SFXsfx0703 1795 -#define SFXsfx0704 1796 -#define SFXwpn_fire_ice_normal 1797 -#define SFXsfx0706 1798 -#define SFXsfx0707 1799 -#define SFXsfx0708 1800 -#define SFXwpn_fire_wave_normal 1801 -#define SFXsfx070A 1802 -#define SFXwpn_fire_plasma_normal 1803 -#define SFXsfx070C 1804 -#define SFXwpn_fire_phazon_normal 1805 -#define SFXsfx070E 1806 -#define SFXsfx070F 1807 -#define SFXsfx0710 1808 -#define SFXsfx0711 1809 -#define SFXsfx0712 1810 -#define SFXsfx0713 1811 -#define SFXsfx0714 1812 -#define SFXsfx0715 1813 -#define SFXsfx0716 1814 -#define SFXsfx0717 1815 -#define SFXsfx0718 1816 -#define SFXsfx0719 1817 -#define SFXsfx071A 1818 -#define SFXsfx071B 1819 -#define SFXsfx071C 1820 -#define SFXwpn_into_beam_ice 1821 -#define SFXwpn_from_beam_ice 1822 -#define SFXwpn_to_missile_power 1823 -#define SFXwpn_from_missile_power 1824 -#define SFXwpn_into_beam_plasma 1825 -#define SFXwpn_from_beam_plasma 1826 -#define SFXwpn_into_beam_wave 1827 -#define SFXwpn_from_beam_wave 1828 -#define SFXwpn_to_missile_ice 1829 -#define SFXsfx0726 1830 -#define SFXsfx0727 1831 -#define SFXsfx0728 1832 -#define SFXsfx0729 1833 -#define SFXsfx072A 1834 -#define SFXsfx072B 1835 -#define SFXsfx072C 1836 -#define SFXsfx072D 1837 -#define SFXsfx072E 1838 -#define SFXwpn_chargeup_plasma 1839 -#define SFXwpn_fire_plasma_charged 1840 -#define SFXsfx0731 1841 -#define SFXwpn_combo_flamethrower 1842 -#define SFXsfx0733 1843 -#define SFXwpn_chargeup_wave 1844 -#define SFXwpn_fire_wave_charged 1845 -#define SFXsfx0736 1846 -#define SFXwpn_combo_wavebuster 1847 -#define SFXsfx0738 1848 -#define SFXwpn_from_missile_ice 1849 -#define SFXwpn_to_missile_wave 1850 -#define SFXwpn_from_missile_wave 1851 -#define SFXwpn_to_missile_plasma 1852 -#define SFXwpn_from_missile_plasma 1853 -#define SFXsfx073E 1854 -#define SFXsfx073F 1855 -#define SFXsfx0740 1856 -#define SFXsfx0741 1857 -#define SFXsfx0742 1858 -#define SFXsfx0743 1859 -#define SFXsfx0744 1860 -#define SFXsfx0745 1861 -#define SFXsfx0746 1862 -#define SFXsfx0747 1863 -#define SFXsfx0748 1864 -#define SFXsfx0749 1865 -#define SFXsfx074A 1866 -#define SFXsfx074B 1867 -#define SFXsfx074C 1868 -#define SFXsfx074D 1869 -#define SFXsfx074E 1870 -#define SFXsfx074F 1871 -#define SFXsfx0750 1872 -#define SFXsfx0751 1873 -#define SFXsfx0752 1874 -#define SFXsfx0753 1875 -#define SFXsfx0754 1876 -#define SFXsfx0755 1877 -#define SFXsfx0756 1878 -#define SFXsfx0757 1879 -#define SFXsfx0758 1880 -#define SFXsfx0759 1881 -#define SFXsfx075A 1882 -#define SFXsfx075B 1883 -#define SFXsfx075C 1884 -#define SFXsfx075D 1885 -#define SFXsfx075E 1886 -#define SFXsfx075F 1887 -#define SFXsfx0760 1888 -#define SFXsfx0761 1889 -#define SFXsfx0762 1890 -#define SFXsfx0763 1891 diff --git a/DataSpec/DNAMP1/SFX/ZZZ.h b/DataSpec/DNAMP1/SFX/ZZZ.h deleted file mode 100644 index 1b7c2b7fa..000000000 --- a/DataSpec/DNAMP1/SFX/ZZZ.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: ZZZ - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPZZZ 65 - -#define SFXsfx0C16 3094 -#define SFXsfx0C17 3095 -#define SFXsfx0C18 3096 -#define SFXsfx0C19 3097 -#define SFXsfx0C1A 3098 -#define SFXsfx0C1B 3099 -#define SFXsfx0C1C 3100 -#define SFXsfx0C1D 3101 -#define SFXsfx0C1E 3102 -#define SFXsfx0C1F 3103 -#define SFXsfx0C20 3104 -#define SFXsfx0C21 3105 -#define SFXsfx0C22 3106 -#define SFXsfx0C23 3107 -#define SFXsfx0C24 3108 -#define SFXsfx0C25 3109 -#define SFXsfx0C26 3110 -#define SFXsfx0C27 3111 -#define SFXsfx0C28 3112 -#define SFXsfx0C29 3113 diff --git a/DataSpec/DNAMP1/SFX/Zoomer.h b/DataSpec/DNAMP1/SFX/Zoomer.h deleted file mode 100644 index 99269f336..000000000 --- a/DataSpec/DNAMP1/SFX/Zoomer.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: Zoomer - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPZoomer 54 - -#define SFXzom_b_idle_00 2681 -#define SFXsfx0A7A 2682 -#define SFXsfx0A7B 2683 -#define SFXsfx0A7C 2684 -#define SFXsfx0A7D 2685 -#define SFXgem_b_idle_00 2686 -#define SFXsfx0A7F 2687 -#define SFXsfx0A80 2688 -#define SFXsfx0A81 2689 -#define SFXsfx0A82 2690 -#define SFXsfx0A83 2691 -#define SFXsfx0A84 2692 -#define SFXsfx0A85 2693 -#define SFXsfx0A86 2694 -#define SFXsfx0A87 2695 -#define SFXsfx0A88 2696 -#define SFXsfx0A89 2697 -#define SFXsfx0A8A 2698 -#define SFXsfx0A8B 2699 -#define SFXsfx0A8C 2700 -#define SFXsfx0A8D 2701 -#define SFXsfx0A8E 2702 diff --git a/DataSpec/DNAMP1/SFX/lumigek.h b/DataSpec/DNAMP1/SFX/lumigek.h deleted file mode 100644 index 86dc69a74..000000000 --- a/DataSpec/DNAMP1/SFX/lumigek.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: lumigek - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPLumigek 69 - -#define SFXlum_b_idle_00 3143 -#define SFXsfx0C48 3144 -#define SFXsfx0C49 3145 -#define SFXsfx0C4A 3146 -#define SFXsfx0C4B 3147 -#define SFXsfx0C4C 3148 diff --git a/DataSpec/DNAMP1/SFX/test.h b/DataSpec/DNAMP1/SFX/test.h deleted file mode 100644 index 0028de793..000000000 --- a/DataSpec/DNAMP1/SFX/test.h +++ /dev/null @@ -1,13 +0,0 @@ -/* Auto-generated Amuse Defines - * - * Project: Audio - * Subproject: test - * Date: Sat Sep 1 12:32:04 2018 - */ - -#define GRPtest 53 - -#define SNGIntro_Cinema 0 -#define SNGMain_Plaza 1 -#define SNGIntro_Exit 2 -#define SNGEndGame 3 diff --git a/DataSpec/DNAMP1/STRG.cpp b/DataSpec/DNAMP1/STRG.cpp deleted file mode 100644 index e866b1a67..000000000 --- a/DataSpec/DNAMP1/STRG.cpp +++ /dev/null @@ -1,465 +0,0 @@ -#include "STRG.hpp" - -#include - -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -constexpr std::array skLanguages{ - FOURCC('ENGL'), FOURCC('FREN'), FOURCC('GERM'), FOURCC('SPAN'), FOURCC('ITAL'), FOURCC('DUTC'), FOURCC('JAPN'), -}; - -static uint32_t ParseTag(const char16_t* str) { - char parseStr[9]; - int i; - for (i = 0; i < 8 && str[i]; ++i) - parseStr[i] = str[i]; - parseStr[i] = '\0'; - return strtoul(parseStr, nullptr, 16); -} - -static std::u16string_view::const_iterator SkipCommas(std::u16string& ret, std::u16string_view str, - std::u16string_view::const_iterator it, size_t count) { - for (size_t i = 0; i < count; ++i) { - auto cpos = str.find(u',', it - str.begin()); - if (cpos == std::u16string::npos) - return str.end(); - auto end = str.begin() + cpos + 1; - ret.insert(ret.end(), it, end); - it = end; - } - return it; -} - -static std::u16string_view::const_iterator UncookTextureList(std::u16string& ret, std::u16string_view str, - std::u16string_view::const_iterator it) { - while (true) { - UniqueID32 id = ParseTag(&*it); - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id); - ret.append(hecl::UTF8ToChar16(path ? path.getRelativePath() : id.toString())); - it += 8; - if (*it == u';') { - ret.push_back(u';'); - return it + 1; - } else if (*it == u',') { - ret.push_back(u','); - ++it; - } else { - break; - } - } - - /* Failsafe */ - auto scpos = str.find(u';', it - str.begin()); - if (scpos == std::u16string::npos) - return str.end(); - return str.begin() + scpos + 1; -} - -static std::u16string_view::const_iterator CookTextureList(std::u16string& ret, std::u16string_view str, - std::u16string_view::const_iterator it) { - while (true) { - auto end = str.find_first_of(u",;", it - str.begin()); - if (end == std::u16string::npos) - Log.report(logvisor::Fatal, FMT_STRING("Missing comma/semicolon token while pasing font tag")); - auto endIt = str.begin() + end; - hecl::ProjectPath path = - UniqueIDBridge::MakePathFromString(hecl::Char16ToUTF8(std::u16string(it, endIt))); - ret.append(hecl::UTF8ToChar16(UniqueID32(path).toString())); - it = endIt; - if (*it == u';') { - ret.push_back(u';'); - return it + 1; - } else if (*it == u',') { - ret.push_back(u','); - ++it; - } else { - break; - } - } - - /* Failsafe */ - auto scpos = str.find(u';', it - str.begin()); - if (scpos == std::u16string::npos) - return str.end(); - return str.begin() + scpos + 1; -} - -static std::u16string_view::const_iterator GatherTextureList(std::vector& pathsOut, - std::u16string_view str, - std::u16string_view::const_iterator it) { - while (true) { - auto end = str.find_first_of(u",;", it - str.begin()); - if (end == std::u16string::npos) - Log.report(logvisor::Fatal, FMT_STRING("Missing comma/semicolon token while pasing font tag")); - auto endIt = str.begin() + end; - hecl::ProjectPath path = - UniqueIDBridge::MakePathFromString(hecl::Char16ToUTF8(std::u16string(it, endIt))); - if (path) - pathsOut.push_back(path); - - it = endIt; - if (*it == u';') { - return it + 1; - } else if (*it == u',') { - ++it; - } else { - break; - } - } - - /* Failsafe */ - auto scpos = str.find(u';', it - str.begin()); - if (scpos == std::u16string::npos) - return str.end(); - return str.begin() + scpos + 1; -} - -static std::u16string UncookString(std::u16string_view str) { - std::u16string ret; - ret.reserve(str.size()); - for (auto it = str.begin(); it != str.end();) { - if (*it == u'&') { - ret.push_back(u'&'); - ++it; - if (!str.compare(it - str.begin(), 5, u"image")) { - ret.append(u"image="); - it += 6; - if (!str.compare(it - str.begin(), 1, u"A")) { - it = SkipCommas(ret, str, it, 2); - it = UncookTextureList(ret, str, it); - continue; - } else if (!str.compare(it - str.begin(), 2, u"SA")) { - it = SkipCommas(ret, str, it, 4); - it = UncookTextureList(ret, str, it); - continue; - } else if (!str.compare(it - str.begin(), 2, u"SI")) { - it = SkipCommas(ret, str, it, 3); - it = UncookTextureList(ret, str, it); - continue; - } - } else if (!str.compare(it - str.begin(), 4, u"font")) { - ret.append(u"font="); - it += 5; - UniqueID32 id = ParseTag(&*it); - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id, true); - ret.append(hecl::UTF8ToChar16(path ? path.getRelativePath() : id.toString())); - - ret.push_back(u';'); - auto scpos = str.find(u';', it - str.begin()); - if (scpos == std::u16string::npos) - it = str.end(); - else - it = str.begin() + scpos + 1; - } else { - auto scpos = str.find(u';', it - str.begin()); - if (scpos == std::u16string::npos) { - it = str.end(); - } else { - auto end = str.begin() + scpos + 1; - ret.insert(ret.end(), it, end); - it = end; - } - } - } else { - ret.push_back(*it); - ++it; - } - } - return ret; -} - -static std::u16string CookString(std::u16string_view str) { - std::u16string ret; - ret.reserve(str.size()); - for (auto it = str.begin(); it != str.end();) { - if (*it == u'&') { - ret.push_back(u'&'); - ++it; - if (!str.compare(it - str.begin(), 5, u"image")) { - ret.append(u"image="); - it += 6; - if (!str.compare(it - str.begin(), 1, u"A")) { - it = SkipCommas(ret, str, it, 2); - it = CookTextureList(ret, str, it); - continue; - } else if (!str.compare(it - str.begin(), 2, u"SA")) { - it = SkipCommas(ret, str, it, 4); - it = CookTextureList(ret, str, it); - continue; - } else if (!str.compare(it - str.begin(), 2, u"SI")) { - it = SkipCommas(ret, str, it, 3); - it = CookTextureList(ret, str, it); - continue; - } - } else if (!str.compare(it - str.begin(), 4, u"font")) { - ret.append(u"font="); - it += 5; - auto scpos = str.find(u';', it - str.begin()); - if (scpos == std::u16string::npos) - Log.report(logvisor::Fatal, FMT_STRING("Missing semicolon token while pasing font tag")); - hecl::ProjectPath path = - UniqueIDBridge::MakePathFromString(hecl::Char16ToUTF8(std::u16string(it, str.begin() + scpos))); - ret.append(hecl::UTF8ToChar16(UniqueID32(path).toString())); - ret.push_back(u';'); - it = str.begin() + scpos + 1; - } else { - auto scpos = str.find(u';', it - str.begin()); - if (scpos == std::u16string::npos) { - it = str.end(); - } else { - auto end = str.begin() + scpos + 1; - ret.insert(ret.end(), it, end); - it = end; - } - } - } else { - ret.push_back(*it); - ++it; - } - } - return ret; -} - -void STRG::gatherDependencies(std::vector& pathsOut) const { - std::u16string skip; - for (const auto& lang : langs) { - for (const std::u16string& str : lang.second) { - std::u16string_view strView(str); - for (auto it = strView.begin(); it != strView.end();) { - if (*it == u'&') { - ++it; - if (!str.compare(it - strView.begin(), 5, u"image")) { - it += 6; - if (!str.compare(it - strView.begin(), 1, u"A")) { - it = SkipCommas(skip, str, it, 2); - it = GatherTextureList(pathsOut, str, it); - continue; - } else if (!str.compare(it - strView.begin(), 2, u"SA")) { - it = SkipCommas(skip, str, it, 4); - it = GatherTextureList(pathsOut, str, it); - continue; - } else if (!str.compare(it - strView.begin(), 2, u"SI")) { - it = SkipCommas(skip, str, it, 3); - it = GatherTextureList(pathsOut, str, it); - continue; - } - } else if (!str.compare(it - strView.begin(), 4, u"font")) { - it += 5; - auto scpos = str.find(u';', it - strView.begin()); - if (scpos == std::u16string::npos) - Log.report(logvisor::Fatal, FMT_STRING("Missing semicolon token while pasing font tag")); - hecl::ProjectPath path = UniqueIDBridge::MakePathFromString( - hecl::Char16ToUTF8(std::u16string(it, strView.begin() + scpos))); - if (path) - pathsOut.push_back(path); - it = strView.begin() + scpos + 1; - } else { - auto scpos = str.find(u';', it - strView.begin()); - if (scpos == std::u16string::npos) - it = strView.end(); - else - it = strView.begin() + scpos + 1; - } - } else - ++it; - } - } - } -} - -void STRG::_read(athena::io::IStreamReader& reader) { - atUint32 langCount = reader.readUint32Big(); - atUint32 strCount = reader.readUint32Big(); - - std::vector> readLangs; - - readLangs.reserve(langCount); - for (atUint32 l = 0; l < langCount; ++l) { - DNAFourCC lang; - lang.read(reader); - atUint32 off = reader.readUint32Big(); - readLangs.emplace_back(lang, off); - } - - atUint32 tablesStart = reader.position(); - langs.clear(); - langs.reserve(skLanguages.size()); - for (const std::pair& lang : readLangs) { - std::vector strs; - reader.seek(tablesStart + lang.second, athena::SeekOrigin::Begin); - reader.readUint32Big(); // table size - atUint32 langStart = reader.position(); - for (atUint32 s = 0; s < strCount; ++s) { - atUint32 strOffset = reader.readUint32Big(); - atUint32 tmpOffset = reader.position(); - reader.seek(langStart + strOffset, athena::SeekOrigin::Begin); - strs.emplace_back(UncookString(reader.readU16StringBig())); - reader.seek(tmpOffset, athena::SeekOrigin::Begin); - } - langs.emplace_back(lang.first, strs); - } - - langMap.clear(); - langMap.reserve(langCount); - for (std::pair>& item : langs) - langMap.emplace(item.first, &item.second); -} - -template <> -void STRG::Enumerate(typename Read::StreamT& reader) { - atUint32 magic = reader.readUint32Big(); - if (magic != 0x87654321) - Log.report(logvisor::Error, FMT_STRING("invalid STRG magic")); - - atUint32 version = reader.readUint32Big(); - if (version != 0) - Log.report(logvisor::Error, FMT_STRING("invalid STRG version")); - - _read(reader); -} - -template <> -void STRG::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(0x87654321); - writer.writeUint32Big(0); - writer.writeUint32Big(langs.size()); - atUint32 strCount = STRG::count(); - writer.writeUint32Big(strCount); - - std::vector strings; - strings.reserve(strCount * langs.size()); - - atUint32 offset = 0; - for (const std::pair>& lang : langs) { - DNAFourCC(lang.first).write(writer); - writer.writeUint32Big(offset); - offset += strCount * 4 + 4; - atUint32 langStrCount = lang.second.size(); - for (atUint32 s = 0; s < strCount; ++s) { - std::u16string str = CookString(lang.second[s]); - atUint32 chCount = str.size(); - if (s < langStrCount) - offset += (chCount + 1) * 2; - else - offset += 1; - strings.push_back(std::move(str)); - } - } - - auto langIt = strings.cbegin(); - for (const std::pair>& lang : langs) { - atUint32 langStrCount = lang.second.size(); - atUint32 tableSz = strCount * 4; - auto strIt = langIt; - for (atUint32 s = 0; s < strCount; ++s) { - if (s < langStrCount) - tableSz += ((strIt++)->size() + 1) * 2; - else - tableSz += 1; - } - writer.writeUint32Big(tableSz); - - offset = strCount * 4; - strIt = langIt; - for (atUint32 s = 0; s < strCount; ++s) { - writer.writeUint32Big(offset); - if (s < langStrCount) - offset += ((strIt++)->size() + 1) * 2; - else - offset += 1; - } - - strIt = langIt; - for (atUint32 s = 0; s < strCount; ++s) { - if (s < langStrCount) - writer.writeU16StringBig(*strIt++); - else - writer.writeUByte(0); - } - - langIt = strIt; - } -} - -template <> -void STRG::Enumerate(typename BinarySize::StreamT& _s) { - _s += 16; - _s += langs.size() * 12; - - size_t strCount = STRG::count(); - _s += langs.size() * strCount * 4; - for (const std::pair>& lang : langs) { - atUint32 langStrCount = lang.second.size(); - for (atUint32 s = 0; s < strCount; ++s) { - if (s < langStrCount) - _s += (CookString(lang.second[s]).size() + 1) * 2; - else - _s += 1; - } - } -} - -template <> -void STRG::Enumerate(typename ReadYaml::StreamT& reader) { - const athena::io::YAMLNode* root = reader.getRootNode(); - - /* Validate Pass */ - if (root->m_type == YAML_MAPPING_NODE) { - for (const auto& lang : root->m_mapChildren) { - if (lang.first == "DNAType") - continue; - - if (lang.first.size() != 4) { - Log.report(logvisor::Warning, FMT_STRING("STRG language string '{}' must be exactly 4 characters; skipping"), - lang.first); - return; - } - if (lang.second->m_type != YAML_SEQUENCE_NODE) { - Log.report(logvisor::Warning, FMT_STRING("STRG language string '{}' must contain a sequence; skipping"), - lang.first); - return; - } - for (const auto& str : lang.second->m_seqChildren) { - if (str->m_type != YAML_SCALAR_NODE) { - Log.report(logvisor::Warning, FMT_STRING("STRG language '{}' must contain all scalars; skipping"), - lang.first); - return; - } - } - } - } else { - Log.report(logvisor::Warning, FMT_STRING("STRG must have a mapping root node; skipping")); - return; - } - - /* Read Pass */ - langs.clear(); - for (const auto& lang : root->m_mapChildren) { - if (lang.first == "DNAType") - continue; - - std::vector strs; - for (const auto& str : lang.second->m_seqChildren) - strs.emplace_back(hecl::UTF8ToChar16(str->m_scalarString)); - langs.emplace_back(FourCC(lang.first.c_str()), strs); - } - - langMap.clear(); - langMap.reserve(langs.size()); - for (auto& item : langs) - langMap.emplace(item.first, &item.second); -} - -template <> -void STRG::Enumerate(typename WriteYaml::StreamT& writer) { - for (const auto& lang : langs) { - if (auto v = writer.enterSubVector(lang.first.toString())) - for (const std::u16string& str : lang.second) - writer.writeU16String(str); - } -} - -std::string_view STRG::DNAType() { return "DNAMP1::STRG"sv; } -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/STRG.hpp b/DataSpec/DNAMP1/STRG.hpp deleted file mode 100644 index 9cc4f2285..000000000 --- a/DataSpec/DNAMP1/STRG.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/STRG.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -struct STRG : ISTRG { - AT_DECL_EXPLICIT_DNA_YAMLV - void _read(athena::io::IStreamReader& reader); - std::vector>> langs; - std::unordered_map*> langMap; - - int32_t lookupIdx(std::string_view name) const override { return -1; } - - size_t count() const override { - size_t retval = 0; - for (const auto& item : langs) { - size_t sz = item.second.size(); - if (sz > retval) - retval = sz; - } - return retval; - } - std::string getUTF8(const FourCC& lang, size_t idx) const override { - auto search = langMap.find(lang); - if (search != langMap.end()) - return hecl::Char16ToUTF8(search->second->at(idx)); - return std::string(); - } - std::u16string getUTF16(const FourCC& lang, size_t idx) const override { - auto search = langMap.find(lang); - if (search != langMap.end()) - return search->second->at(idx); - return std::u16string(); - } - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - STRG strg; - strg.read(rs); - athena::io::TransactionalFileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(strg, writer); - return true; - } - - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - STRG strg; - athena::io::FileReader reader(inPath.getAbsolutePath()); - athena::io::FromYAMLStream(strg, reader); - athena::io::TransactionalFileWriter ws(outPath.getAbsolutePath()); - strg.write(ws); - return true; - } - - static bool Cook(const STRG& strg, const hecl::ProjectPath& outPath) { - athena::io::TransactionalFileWriter ws(outPath.getAbsolutePath()); - strg.write(ws); - return true; - } - - void gatherDependencies(std::vector& pathsOut) const override; -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/AIJumpPoint.hpp b/DataSpec/DNAMP1/ScriptObjects/AIJumpPoint.hpp deleted file mode 100644 index 2595fc26c..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/AIJumpPoint.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct AIJumpPoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value apex; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/AIKeyframe.hpp b/DataSpec/DNAMP1/ScriptObjects/AIKeyframe.hpp deleted file mode 100644 index 9d05a3c36..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/AIKeyframe.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { - -struct AIKeyframe : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value animationId; - Value looping; - Value lifetime; - Value active; - Value fadeOut; - Value totalPlayback; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Actor.cpp b/DataSpec/DNAMP1/ScriptObjects/Actor.cpp deleted file mode 100644 index da056382e..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Actor.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "Actor.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -zeus::CAABox Actor::getVISIAABB(hecl::blender::Token& btok) const { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - zeus::CAABox aabbOut; - - if (model.isValid()) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(model); - conn.openBlend(path); - hecl::blender::DataStream ds = conn.beginData(); - auto aabb = ds.getMeshAABB(); - aabbOut = zeus::CAABox(aabb.first, aabb.second); - } else if (animationParameters.animationCharacterSet.isValid()) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(animationParameters.animationCharacterSet); - conn.openBlend(path.getWithExtension(".blend", true)); - hecl::blender::DataStream ds = conn.beginData(); - auto aabb = ds.getMeshAABB(); - aabbOut = zeus::CAABox(aabb.first, aabb.second); - } - - if (aabbOut.min.x() > aabbOut.max.x()) - return {}; - - zeus::CTransform xf = ConvertEditorEulerToTransform4f(scale, orientation, location); - return aabbOut.getTransformedAABox(xf); -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Actor.hpp b/DataSpec/DNAMP1/ScriptObjects/Actor.hpp deleted file mode 100644 index 9b094f042..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Actor.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Actor : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value collisionExtent; - Value collisionOffset; - Value mass; - Value zMomentum; - HealthInfo healthInfo; - DamageVulnerability damageVulnerability; - UniqueID32 model; - AnimationParameters animationParameters; - ActorParameters actorParameters; - Value looping; - Value immovable; - Value solid; - Value cameraPassthrough; - Value active; - Value shaderIdx; - Value xrayAlpha; - Value noThermalHotZ; - Value castsShadow; - Value scaleAdvancementDelta; - Value materialFlag54; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(model, pathsOut); - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } - - zeus::CAABox getVISIAABB(hecl::blender::Token& btok) const override; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ActorContraption.hpp b/DataSpec/DNAMP1/ScriptObjects/ActorContraption.hpp deleted file mode 100644 index b367b9ca2..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ActorContraption.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ActorContraption : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value collisionExtent; - Value collisionOrigin; - Value mass; - Value zMomentum; - HealthInfo healthInfo; - DamageVulnerability damageVulnerability; - AnimationParameters animationParameters; - ActorParameters actorParameters; - UniqueID32 particle; - DamageInfo damageInfo; - Value active; // needs verification - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle, pathsOut); - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ActorKeyframe.hpp b/DataSpec/DNAMP1/ScriptObjects/ActorKeyframe.hpp deleted file mode 100644 index 4fb752caa..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ActorKeyframe.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ActorKeyframe : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value animationId; - Value looping; - Value lifetime; - Value active; - Value fadeOut; - Value totalPlayback; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ActorRotate.hpp b/DataSpec/DNAMP1/ScriptObjects/ActorRotate.hpp deleted file mode 100644 index 41f2a4c1f..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ActorRotate.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ActorRotate : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value rotationOffset; - Value timeScale; - Value updateActors; - Value updateOnCreation; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/AmbientAI.hpp b/DataSpec/DNAMP1/ScriptObjects/AmbientAI.hpp deleted file mode 100644 index 92eeaf626..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/AmbientAI.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct AmbientAI : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value collisionExtent; - Value collisionOffset; - Value mass; - HealthInfo healthInfo; - DamageVulnerability damageVulnerability; - AnimationParameters animationParameters; - ActorParameters actorParameters; - Value alertRange; - Value impactRange; - Value alertAnim; - Value impactAnim; - Value active; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/AreaAttributes.hpp b/DataSpec/DNAMP1/ScriptObjects/AreaAttributes.hpp deleted file mode 100644 index 5ee96ae11..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/AreaAttributes.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct AreaAttributes : IScriptObject { - AT_DECL_DNA_YAMLV - enum class EWeatherType : atUint32 { None, Snow, Rain }; - - Value load; /* 0 causes the loader to bail and return null */ - Value skyboxEnabled; - Value weather; - Value envFxDensity; - Value thermalHeat; - Value xrayFogDistance; - Value worldLightingLevel; - UniqueID32 skybox; - Value phazonType; - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(skybox, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/AtomicAlpha.hpp b/DataSpec/DNAMP1/ScriptObjects/AtomicAlpha.hpp deleted file mode 100644 index 5ea14c195..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/AtomicAlpha.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct AtomicAlpha : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - UniqueID32 wpsc; - UniqueID32 model; - DamageInfo damageInfo; - Value bombDropDelay; - Value bombReappearDelay; - Value bombReappearTime; - Value invisible; - Value applyBeamAttraction; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); - ent->name = name + "_wpsc"; - } - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc, pathsOut); - g_curSpec->flattenDependencies(model, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/AtomicBeta.hpp b/DataSpec/DNAMP1/ScriptObjects/AtomicBeta.hpp deleted file mode 100644 index e367f683e..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/AtomicBeta.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct AtomicBeta : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - UniqueID32 elsc; - UniqueID32 wpsc; - DamageInfo damageInfo; - UniqueID32 part; - Value unknown1; - Value unknown2; - Value unknown3; - DamageVulnerability damageVulnerabilty; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - if (wpsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); - ent->name = name + "_wpsc"; - } - if (part.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part); - ent->name = name + "_part"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(elsc, pathsOut); - g_curSpec->flattenDependencies(wpsc, pathsOut); - g_curSpec->flattenDependencies(part, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Babygoth.hpp b/DataSpec/DNAMP1/ScriptObjects/Babygoth.hpp deleted file mode 100644 index 37c3c7607..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Babygoth.hpp +++ /dev/null @@ -1,125 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Babygoth : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value fireballAttackTime; - Value fireballAttackTimeVariance; - UniqueID32 fireballWeapon; - DamageInfo fireballDamage; - DamageInfo attackContactDamage; - UniqueID32 fireBreathWeapon; - UniqueID32 fireBreathRes; - DamageInfo fireBreathDamage; - DamageVulnerability mouthVulnerabilities; - DamageVulnerability shellVulnerabilities; - UniqueID32 noShellModel; - UniqueID32 noShellSkin; - Value shellHitPoints; - Value shellCrackSfx; - UniqueID32 intermediateCrackParticle; - UniqueID32 crackOneParticle; - UniqueID32 crackTwoParticle; - UniqueID32 destroyShellParticle; - Value crackOneSfx; - Value crackTwoSfx; - Value destroyShellSfx; - Value timeUntilAttack; - Value attackCooldownTime; - Value interestTime; - UniqueID32 flamePlayerSteamTxtr; - Value flamePlayerHitSfx; - UniqueID32 flamePlayerIceTxtr; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - UniqueID32 cinf = patternedInfo.animationParameters.getCINF(pakRouter); - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - - if (noShellModel.isValid() && noShellSkin.isValid()) { - charAssoc.m_cmdlRigs[noShellModel] = {noShellSkin, cinf}; - charAssoc.m_cskrToCharacter[noShellSkin] = - std::make_pair(patternedInfo.animationParameters.animationCharacterSet, - fmt::format(FMT_STRING("ATTACH.SHELLESS_{}.CSKR"), noShellSkin)); - charAssoc.addAttachmentRig(patternedInfo.animationParameters.animationCharacterSet, {}, noShellModel, "SHELLESS"); - } - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (fireballWeapon.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(fireballWeapon); - ent->name = name + "_wpsc1"; - } - if (fireBreathWeapon.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(fireBreathWeapon); - ent->name = name + "_wpsc2"; - } - if (fireBreathRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(fireBreathRes); - ent->name = name + "_part1"; - } - if (noShellModel.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(noShellModel); - ent->name = name + "_emodel"; - } - if (noShellSkin.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(noShellSkin); - ent->name = name + "_eskin"; - } - if (intermediateCrackParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(intermediateCrackParticle); - ent->name = name + "_part2"; - } - if (crackOneParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(crackOneParticle); - ent->name = name + "_part3"; - } - if (crackTwoParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(crackTwoParticle); - ent->name = name + "_part4"; - } - if (destroyShellParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(destroyShellParticle); - ent->name = name + "_part5"; - } - if (flamePlayerSteamTxtr.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(flamePlayerSteamTxtr); - ent->name = name + "_tex"; - } - if (flamePlayerIceTxtr.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(flamePlayerIceTxtr); - ent->name = name + "_part6"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(fireballWeapon, pathsOut); - g_curSpec->flattenDependencies(fireBreathWeapon, pathsOut); - g_curSpec->flattenDependencies(fireBreathRes, pathsOut); - g_curSpec->flattenDependencies(noShellModel, pathsOut); - g_curSpec->flattenDependencies(noShellSkin, pathsOut); - g_curSpec->flattenDependencies(intermediateCrackParticle, pathsOut); - g_curSpec->flattenDependencies(crackOneParticle, pathsOut); - g_curSpec->flattenDependencies(crackTwoParticle, pathsOut); - g_curSpec->flattenDependencies(destroyShellParticle, pathsOut); - g_curSpec->flattenDependencies(flamePlayerSteamTxtr, pathsOut); - g_curSpec->flattenDependencies(flamePlayerIceTxtr, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/BallTrigger.hpp b/DataSpec/DNAMP1/ScriptObjects/BallTrigger.hpp deleted file mode 100644 index b09627694..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/BallTrigger.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct BallTrigger : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value volume; - Value active; - Value force; - Value minAngle; - Value maxDistance; - Value forceAngle; - Value stopPlayer; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Beetle.hpp b/DataSpec/DNAMP1/ScriptObjects/Beetle.hpp deleted file mode 100644 index 2c6c39445..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Beetle.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Beetle : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value flavor; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - DamageInfo touchDamage; - Value tailAimReference; - Value unused; - DamageVulnerability tailVuln; - DamageVulnerability platingVuln; - UniqueID32 tailModel; - Value entranceType; - Value initialAttackDelay; - Value retreatTime; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (tailModel.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(tailModel); - ent->name = name + "_tailModel"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(tailModel, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/BloodFlower.hpp b/DataSpec/DNAMP1/ScriptObjects/BloodFlower.hpp deleted file mode 100644 index 69e4d1209..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/BloodFlower.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct BloodFlower : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - UniqueID32 particle1; - UniqueID32 wpsc1; - UniqueID32 wpsc2; - DamageInfo damageInfo1; - DamageInfo damageInfo2; - DamageInfo damageInfo3; - UniqueID32 particle2; - UniqueID32 particle3; - UniqueID32 particle4; - Value unknown1; - UniqueID32 particle5; - Value unknown2; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); - ent->name = name + "_wpsc1"; - } - if (wpsc2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); - ent->name = name + "_wpsc2"; - } - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - if (particle5.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle5); - ent->name = name + "_part5"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc1, pathsOut); - g_curSpec->flattenDependencies(wpsc2, pathsOut); - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - g_curSpec->flattenDependencies(particle5, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Burrower.hpp b/DataSpec/DNAMP1/ScriptObjects/Burrower.hpp deleted file mode 100644 index 38ca9adde..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Burrower.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Burrower : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - UniqueID32 particle1; - UniqueID32 particle2; - UniqueID32 wpsc; - DamageInfo damageInfo; - UniqueID32 particle3; - Value unknown; // always FF - UniqueID32 particle4; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); - ent->name = name + "_wpsc"; - } - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc, pathsOut); - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CMakeLists.txt b/DataSpec/DNAMP1/ScriptObjects/CMakeLists.txt deleted file mode 100644 index 53cb30a51..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CMakeLists.txt +++ /dev/null @@ -1,143 +0,0 @@ -make_dnalist( - IScriptObject - Parameters - Actor - ActorContraption - ActorKeyframe - ActorRotate - AIJumpPoint - AIKeyframe - AmbientAI - AreaAttributes - AtomicAlpha - AtomicBeta - Babygoth - BallTrigger - Beetle - BloodFlower - Burrower - Camera - CameraBlurKeyframe - CameraFilterKeyframe - CameraHint - CameraHintTrigger - CameraPitchVolume - CameraShaker - CameraWaypoint - ChozoGhost - ColorModulate - ControllerAction - Counter - CoverPoint - DamageableTrigger - Debris - DebrisExtended - DebugCameraWaypoint - DistanceFog - Dock - DockAreaChange - DoorArea - Drone - Effect - ElectroMagneticPulse - ElitePirate - EnergyBall - EnvFxDensityController - Eyeball - FireFlea - FishCloud - FishCloudModifier - Flaahgra - FlaahgraTentacle - FlickerBat - FlyingPirate - FogVolume - Geemer - Generator - GrapplePoint - GunTurret - HUDMemo - IceSheegoth - IceZoomer - JellyZap - Magdolite - MazeNode - MemoryRelay - MetareeAlpha - MetroidAlpha - MetroidBeta - MetroidPrimeStage1 - MetroidPrimeStage2 - Midi - NewCameraShaker - NewIntroBoss - Oculus - OmegaPirate - Parasite - PathCamera - PhazonHealingNodule - PhazonPool - Pickup - PickupGenerator - Platform - PlayerActor - PlayerHint - PlayerStateChange - PointOfInterest - PuddleSpore - PuddleToadGamma - Puffer - RadialDamage - RandomRelay - Relay - Repulsor - Ridley - Ripper - Ripple - RoomAcoustics - RumbleEffect - ScriptBeam - Seedling - ShadowProjector - SnakeWeedSwarm - Sound - SpacePirate - SpankWeed - SpawnPoint - SpecialFunction - SpiderBallAttractionSurface - SpiderBallWaypoint - SpindleCamera - Steam - StreamedAudio - Switch - TargetingPoint - TeamAIMgr - Thardus - ThardusRockProjectile - ThermalHeatFader - Timer - Trigger - Tryclops - VisorFlare - VisorGoo - WallCrawlerSwarm - Warwasp - Water - Waypoint - WorldLightFader - WorldTeleporter) - -set(ScriptObjectsMP1_SOURCES - ScriptTypes.hpp - IScriptObject.cpp - Parameters.cpp - Actor.cpp - Platform.cpp - DoorArea.cpp - Oculus.cpp - Ridley.cpp - Water.cpp - WorldTeleporter.cpp) - -dataspec_add_list(DNAMP1/ScriptObjects ScriptObjectsMP1_SOURCES) diff --git a/DataSpec/DNAMP1/ScriptObjects/Camera.hpp b/DataSpec/DNAMP1/ScriptObjects/Camera.hpp deleted file mode 100644 index 1eec64c84..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Camera.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Camera : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value shotDuration; - Value lookAtPlayer; - Value outOfPlayerEye; - Value intoPlayerEye; - Value drawPlayer; - Value disableInput; - Value unknown; - Value finishCineSkip; - Value fov; - Value checkFailsafe; - Value disableOutOfInto; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraBlurKeyframe.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraBlurKeyframe.hpp deleted file mode 100644 index 1565bba1d..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CameraBlurKeyframe.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CameraBlurKeyframe : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value btype; - Value amount; - Value unk; - Value timeIn; - Value timeOut; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraFilterKeyframe.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraFilterKeyframe.hpp deleted file mode 100644 index db95965b7..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CameraFilterKeyframe.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CameraFilterKeyframe : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value ftype; - Value shape; - Value filterIdx; - Value unk; - DNAColor color; - Value timeIn; - Value timeOut; - UniqueID32 texture; - - void nameIDs(PAKRouter& pakRouter) const override { - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_texture"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(texture, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraHint.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraHint.hpp deleted file mode 100644 index 31a2e8390..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CameraHint.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CameraHint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value priority; - Value behaviour; - struct CameraHintParameters : BigDNA { - AT_DECL_DNA - Value propertyCount; - Value calculateCamPos; // 0x1 - Value chaseAllowed; // 0x2 - Value boostAllowed; // 0x4 - Value obscureAvoidance; // 0x8 - Value volumeCollider; // 0x10 - Value applyImmediately; // 0x20 - Value lookAtBall; // 0x40 - Value hintDistanceSelection; // 0x80 - Value hintDistanceSelfPos; // 0x100 - Value controlInterpolation; // 0x200 - Value sinusoidalInterpolation; // 0x400 - Value sinusoidalInterpolationHintless; // 0x800 - Value clampVelocity; // 0x1000 - Value skipCinematic; // 0x2000 - Value noElevationInterp; // 0x4000 - Value directElevation; // 0x8000 - Value overrideLookDir; // 0x10000 - Value noElevationVelClamp; // 0x20000 - Value calculateTransformFromPrevCam; // 0x40000 - Value noSpline; // 0x80000 - Value unknown21; // 0x100000 - Value unknown22; // 0x200000 - } cameraHintParameters; - - struct BoolFloat : BigDNA { - AT_DECL_DNA - Value active; - Value value; - } minDist, maxDist, backwardsDist; // 0x400000, 0x800000, 0x1000000 - struct BoolVec3f : BigDNA { - AT_DECL_DNA - Value active; - Value value; - } lookAtOffset, chaseLookAtOffset; // 0x2000000, 0x4000000 - Value ballToCam; - BoolFloat fov, attitudeRange, azimuthRange, anglePerSecond; // 0x8000000, 0x10000000, 0x20000000, 0x40000000 - Value clampVelRange; - Value clampRotRange; - BoolFloat elevation; // 0x80000000 - Value interpolateTime; - Value clampVelTime; - Value controlInterpDur; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraHintTrigger.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraHintTrigger.hpp deleted file mode 100644 index 37287382e..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CameraHintTrigger.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CameraHintTrigger : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value volume; - Value active; - Value deactivateOnEntered; - Value deactivateOnExited; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraPitchVolume.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraPitchVolume.hpp deleted file mode 100644 index 9a8566fb5..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CameraPitchVolume.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CameraPitchVolume : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value volume; - Value active; - Value upPitch; - Value downPitch; - Value scale; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraShaker.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraShaker.hpp deleted file mode 100644 index c953ca45c..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CameraShaker.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CameraShaker : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value xMag; - Value xB; - Value yMag; - Value yB; - Value zMag; - Value zB; - Value duration; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraWaypoint.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraWaypoint.hpp deleted file mode 100644 index 24ddd9604..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CameraWaypoint.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CameraWaypoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value hFov; - Value unknown3; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ChozoGhost.hpp b/DataSpec/DNAMP1/ScriptObjects/ChozoGhost.hpp deleted file mode 100644 index a4bb949e1..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ChozoGhost.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ChozoGhost : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - UniqueID32 wpsc1; - DamageInfo damageInfo1; - UniqueID32 wpsc2; - DamageInfo damageInfo2; - BehaveChance BehaveChance1; - BehaveChance BehaveChance2; - BehaveChance BehaveChance3; - Value sound1; - Value unknown5; - Value sound2; - Value sound3; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - UniqueID32 particle; - Value soundId4; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); - ent->name = name + "_wpsc1"; - } - if (wpsc2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); - ent->name = name + "_wpsc2"; - } - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc1, pathsOut); - g_curSpec->flattenDependencies(wpsc2, pathsOut); - g_curSpec->flattenDependencies(particle, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ColorModulate.hpp b/DataSpec/DNAMP1/ScriptObjects/ColorModulate.hpp deleted file mode 100644 index a1cc80504..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ColorModulate.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ColorModulate : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value colorA; - Value colorB; - Value blendMode; - Value timeA2B; - Value timeB2A; - Value doReverse; - Value resetTargetWhenDone; - Value depthCompare; - Value depthUpdate; - Value depthBackwards; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ControllerAction.hpp b/DataSpec/DNAMP1/ScriptObjects/ControllerAction.hpp deleted file mode 100644 index dff78e217..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ControllerAction.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ControllerAction : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value command; - Value deactivateOnClose; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Counter.hpp b/DataSpec/DNAMP1/ScriptObjects/Counter.hpp deleted file mode 100644 index 460816cae..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Counter.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Counter : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value initial; - Value maxValue; - Value autoReset; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CoverPoint.hpp b/DataSpec/DNAMP1/ScriptObjects/CoverPoint.hpp deleted file mode 100644 index 040ece63d..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CoverPoint.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CoverPoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value flags; - Value crouch; - Value horizontalAngle; - Value verticleAngle; - Value coverTime; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/DamageableTrigger.hpp b/DataSpec/DNAMP1/ScriptObjects/DamageableTrigger.hpp deleted file mode 100644 index ec893629e..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/DamageableTrigger.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct DamageableTrigger : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value volume; - HealthInfo healthInfo; - DamageVulnerability damageVulnerabilty; - Value faceFlag; - UniqueID32 patternTex1; - UniqueID32 patternTex2; - UniqueID32 colorTex; - Value lockOn; - Value active; - VisorParameters visorParameters; - - void nameIDs(PAKRouter& pakRouter) const override { - if (patternTex1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternTex1); - ent->name = name + "_patternTex1"; - } - if (patternTex2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternTex2); - ent->name = name + "_patternTex2"; - } - if (colorTex.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(colorTex); - ent->name = name + "_colorTex"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(patternTex1, pathsOut); - g_curSpec->flattenDependencies(patternTex2, pathsOut); - g_curSpec->flattenDependencies(colorTex, pathsOut); - } - - zeus::CAABox getVISIAABB(hecl::blender::Token& btok) const override { - zeus::CVector3f halfExtent = zeus::CVector3f(volume) / 2.f; - zeus::CVector3f loc(location); - return zeus::CAABox(loc - halfExtent, loc + halfExtent); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Debris.hpp b/DataSpec/DNAMP1/ScriptObjects/Debris.hpp deleted file mode 100644 index 401c0ad7f..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Debris.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Debris : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value zImpulse; - Value velocity; - DNAColor endsColor; - Value mass; - Value restitution; - Value duration; - Value scaleType; - Value randomAngImpulse; - UniqueID32 model; - ActorParameters actorParameters; - UniqueID32 particle; - Value particleScale; - Value b1; - Value active; - - void nameIDs(PAKRouter& pakRouter) const override { - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(model, pathsOut); - g_curSpec->flattenDependencies(particle, pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/DebrisExtended.hpp b/DataSpec/DNAMP1/ScriptObjects/DebrisExtended.hpp deleted file mode 100644 index 002b3d751..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/DebrisExtended.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct DebrisExtended : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value linConeAngle; - Value linMinMag; - Value linMaxMag; - Value angMinMag; - Value angMaxMag; - Value minDuration; - Value maxDuration; - Value colorInT; - Value colorOutT; - DNAColor color; - DNAColor endsColor; - Value scaleOutT; - Value endScale; - Value restitution; - Value downwardSpeed; - Value localOffset; - UniqueID32 model; - ActorParameters actorParameters; - UniqueID32 particle1; - Value particle1Scale; - Value particle1GlobalTranslation; - Value deferDeleteTillParticle1Done; - Value particle1Or; - UniqueID32 particle2; - Value particle2Scale; - Value particle2GlobalTranslation; - Value deferDeleteTillParticle2Done; - Value particle2Or; - UniqueID32 particle3; - Value particle3Scale; - Value particle3Or; - Value solid; - Value dieOnProjectile; - Value noBounce; - Value active; - - void nameIDs(PAKRouter& pakRouter) const override { - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(model, pathsOut); - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/DebugCameraWaypoint.hpp b/DataSpec/DNAMP1/ScriptObjects/DebugCameraWaypoint.hpp deleted file mode 100644 index aad5f0e39..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/DebugCameraWaypoint.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct DebugCameraWaypoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value unknown1; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/DistanceFog.hpp b/DataSpec/DNAMP1/ScriptObjects/DistanceFog.hpp deleted file mode 100644 index 07813fc15..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/DistanceFog.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct DistanceFog : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value fogMode; - Value fogColor; // CColor - Value range; - Value colorDelta; - Value rangeDelta; - Value expl; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Dock.hpp b/DataSpec/DNAMP1/ScriptObjects/Dock.hpp deleted file mode 100644 index 1d24e3cb1..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Dock.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Dock : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value location; - Value volume; - Value dock; - Value room; - Value loadConnected; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/DockAreaChange.hpp b/DataSpec/DNAMP1/ScriptObjects/DockAreaChange.hpp deleted file mode 100644 index 64bb25b9c..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/DockAreaChange.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct DockAreaChange : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value dockReference; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/DoorArea.cpp b/DataSpec/DNAMP1/ScriptObjects/DoorArea.cpp deleted file mode 100644 index 766ff4dff..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/DoorArea.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "DoorArea.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -zeus::CAABox DoorArea::getVISIAABB(hecl::blender::Token& btok) const { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - zeus::CAABox aabbOut; - - if (animationParameters.animationCharacterSet.isValid()) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(animationParameters.animationCharacterSet); - conn.openBlend(path.getWithExtension(".blend", true)); - hecl::blender::DataStream ds = conn.beginData(); - auto aabb = ds.getMeshAABB(); - aabbOut = zeus::CAABox(aabb.first, aabb.second); - } - - if (aabbOut.min.x() > aabbOut.max.x()) - return {}; - - zeus::CTransform xf = ConvertEditorEulerToTransform4f(scale, orientation, location); - return aabbOut.getTransformedAABox(xf); -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/DoorArea.hpp b/DataSpec/DNAMP1/ScriptObjects/DoorArea.hpp deleted file mode 100644 index 8cfaacb6b..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/DoorArea.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct DoorArea : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - AnimationParameters animationParameters; - ActorParameters actorParameters; - Value orbitPos; - Value collisionExtent; - Value collisionOffset; - Value active; - Value open; - Value projectilesCollide; - Value animationLength; - Value isMorphballDoor; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } - - zeus::CAABox getVISIAABB(hecl::blender::Token& btok) const override; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Drone.hpp b/DataSpec/DNAMP1/ScriptObjects/Drone.hpp deleted file mode 100644 index af29fad9d..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Drone.hpp +++ /dev/null @@ -1,90 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Drone : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value unknown1; - Value location; - Value orientation; - Value scale; - Value unknown2; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - DamageInfo damageInfo1; - Value unknown3; - DamageInfo damageInfo2; - UniqueID32 unknown4; - Value unused; - UniqueID32 unknown6; - FlareDefinition flareDefinition1; - FlareDefinition flareDefinition2; - FlareDefinition flareDefinition3; - FlareDefinition flareDefinition4; - FlareDefinition flareDefinition5; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - Value unknown16; - Value unknown17; - Value unknown18; - Value unknown19; - Value unknown20; - Value unknown21; - Value unknown22; - Value unknown23; - Value unknown24; - Value unknown25; - UniqueID32 crsc; - Value unknon26; - Value unknon27; - Value unknon28; - Value unknon29; - Value sound; // verification needed - Value unknown30; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (crsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(crsc); - ent->name = name + "_crsc"; - } - flareDefinition1.nameIDs(pakRouter, name + "_flare1"); - flareDefinition2.nameIDs(pakRouter, name + "_flare2"); - flareDefinition3.nameIDs(pakRouter, name + "_flare3"); - flareDefinition4.nameIDs(pakRouter, name + "_flare4"); - flareDefinition5.nameIDs(pakRouter, name + "_flare5"); - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(unknown4, pathsOut); - g_curSpec->flattenDependencies(unknown6, pathsOut); - g_curSpec->flattenDependencies(crsc, pathsOut); - flareDefinition1.depIDs(pathsOut); - flareDefinition2.depIDs(pathsOut); - flareDefinition3.depIDs(pathsOut); - flareDefinition4.depIDs(pathsOut); - flareDefinition5.depIDs(pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Effect.hpp b/DataSpec/DNAMP1/ScriptObjects/Effect.hpp deleted file mode 100644 index 05ce2153c..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Effect.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Effect : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - UniqueID32 part; - UniqueID32 elsc; - Value hotInThermal; - Value noTimerUnlessAreaOccluded; - Value rebuildSystemsOnActivate; - Value active; - Value useRateInverseCamDist; - Value rateInverseCamDist; - Value rateInverseCamDistRate; - Value duration; - Value durationResetWhileVisible; - Value useRateCamDistRange; - Value rateCamDistRangeMin; - Value rateCamDistRangeMax; - Value rateCamDistRangeFarRate; - Value combatVisorVisible; - Value thermalVisorVisible; - Value xrayVisorVisible; - Value dieWhenSystemsDone; - LightParameters lightParameters; - - void nameIDs(PAKRouter& pakRouter) const override { - if (part.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part); - ent->name = name + "_part"; - } - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(part, pathsOut); - g_curSpec->flattenDependencies(elsc, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ElectroMagneticPulse.hpp b/DataSpec/DNAMP1/ScriptObjects/ElectroMagneticPulse.hpp deleted file mode 100644 index 6a3c92685..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ElectroMagneticPulse.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ElectroMagneticPulse : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value initialRadius; - Value finalRadius; - Value duration; - Value interferenceDur; - Value unknown6; - Value interferenceMag; - Value unknown8; - UniqueID32 particle; - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ElitePirate.hpp b/DataSpec/DNAMP1/ScriptObjects/ElitePirate.hpp deleted file mode 100644 index 1e011506a..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ElitePirate.hpp +++ /dev/null @@ -1,123 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ElitePirate : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters1; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - UniqueID32 particle1; - Value soundID1; - ActorParameters actorParameters2; - AnimationParameters animationParameters; - UniqueID32 particle2; - Value soundID2; - UniqueID32 model; - DamageInfo damageInfo1; - Value unknown9; - UniqueID32 particle3; - UniqueID32 particle4; - UniqueID32 particle5; - UniqueID32 particle6; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - Value unknown16; - Value soundID3; - Value soundID4; - UniqueID32 particle7; - DamageInfo damageInfo2; - UniqueID32 elsc; - Value soundID5; - Value unknown17; - Value unknown18; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters1.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - actorParameters2.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - if (particle5.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle5); - ent->name = name + "_part5"; - } - if (particle6.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle6); - ent->name = name + "_part6"; - } - if (particle7.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle7); - ent->name = name + "_part7"; - } - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters1.nameIDs(pakRouter, name + "_actp1"); - actorParameters2.nameIDs(pakRouter, name + "_actp2"); - animationParameters.nameANCS(pakRouter, name + "_animp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(model, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - g_curSpec->flattenDependencies(particle5, pathsOut); - g_curSpec->flattenDependencies(particle6, pathsOut); - g_curSpec->flattenDependencies(particle7, pathsOut); - g_curSpec->flattenDependencies(elsc, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters1.depIDs(pathsOut, lazyOut); - actorParameters2.depIDs(pathsOut, lazyOut); - animationParameters.depANCS(pathsOut); - } - - void gatherScans(std::vector& scansOut) const override { - actorParameters1.scanIDs(scansOut); - actorParameters2.scanIDs(scansOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/EnergyBall.hpp b/DataSpec/DNAMP1/ScriptObjects/EnergyBall.hpp deleted file mode 100644 index 65856253f..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/EnergyBall.hpp +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct EnergyBall : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - DamageInfo damageInfo1; - Value unknown3; - UniqueID32 texture; - Value soundID1; - UniqueID32 particle1; - UniqueID32 elsc; - Value soundID2; - Value unknown4; - Value unknown5; - UniqueID32 particle2; - DamageInfo damageInfo2; - Value unknown6; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_texture"; - } - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(texture, pathsOut); - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(elsc, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/EnvFxDensityController.hpp b/DataSpec/DNAMP1/ScriptObjects/EnvFxDensityController.hpp deleted file mode 100644 index 19374dfc7..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/EnvFxDensityController.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct EnvFxDensityController : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value density; - Value maxDensityDeltaSpeed; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Eyeball.hpp b/DataSpec/DNAMP1/ScriptObjects/Eyeball.hpp deleted file mode 100644 index aaf296802..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Eyeball.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Eyeball : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value flavor; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value attackDelay; - Value attackStartTime; - UniqueID32 wpsc; - DamageInfo damageInfo; - UniqueID32 beamContactFxId; - UniqueID32 beamPulseFxId; - UniqueID32 beamTextureId; - UniqueID32 beamGlowTextureId; - Value anim0; - Value anim1; // always ff - Value anim2; // always ff - Value anim3; // always ff - Value beamSfx; - Value attackDisabled; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); - ent->name = name + "_wpsc"; - } - if (beamContactFxId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamContactFxId); - ent->name = name + "_part1"; - } - if (beamPulseFxId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamPulseFxId); - ent->name = name + "_part2"; - } - if (beamTextureId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamTextureId); - ent->name = name + "_tex1"; - } - if (beamGlowTextureId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamGlowTextureId); - ent->name = name + "_tex2"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc, pathsOut); - g_curSpec->flattenDependencies(beamContactFxId, pathsOut); - g_curSpec->flattenDependencies(beamPulseFxId, pathsOut); - g_curSpec->flattenDependencies(beamTextureId, pathsOut); - g_curSpec->flattenDependencies(beamGlowTextureId, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/FireFlea.hpp b/DataSpec/DNAMP1/ScriptObjects/FireFlea.hpp deleted file mode 100644 index d80f1ae2a..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/FireFlea.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct FireFlea : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - Value unknown3; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/FishCloud.hpp b/DataSpec/DNAMP1/ScriptObjects/FishCloud.hpp deleted file mode 100644 index c55be52cf..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/FishCloud.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct FishCloud : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value volume; - Value active; - UniqueID32 model; - AnimationParameters animationParameters; - Value numBoids; - Value speed; - Value separationRadius; - Value cohesionMagnitude; - Value alignmentWeight; - Value separationMagnitude; - Value weaponRepelMagnitude; - Value playerRepelMagnitude; - Value containmentMagnitude; - Value scatterVel; - Value maxScatterAngle; - Value weaponRepelDampingSpeed; - Value playerRepelDampingSpeed; - Value containmentRadius; - Value updateShift; - Value color; // CColor - Value killable; - Value weaponKillRadius; - UniqueID32 deathParticle1; - Value deathParticle1Count; - UniqueID32 deathParticle2; - Value deathParticle2Count; - UniqueID32 deathParticle3; - Value deathParticle3Count; - UniqueID32 deathParticle4; - Value deathParticle4Count; - Value deathSFX; - Value repelFromThreats; - Value hotInThermal; - - void nameIDs(PAKRouter& pakRouter) const override { - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - if (deathParticle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(deathParticle1); - ent->name = name + "_deathParticle1"; - } - if (deathParticle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(deathParticle2); - ent->name = name + "_deathParticle2"; - } - if (deathParticle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(deathParticle3); - ent->name = name + "_deathParticle3"; - } - if (deathParticle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(deathParticle4); - ent->name = name + "_deathParticle4"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(model, pathsOut); - animationParameters.depANCS(pathsOut); - g_curSpec->flattenDependencies(deathParticle1, pathsOut); - g_curSpec->flattenDependencies(deathParticle2, pathsOut); - g_curSpec->flattenDependencies(deathParticle3, pathsOut); - g_curSpec->flattenDependencies(deathParticle4, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/FishCloudModifier.hpp b/DataSpec/DNAMP1/ScriptObjects/FishCloudModifier.hpp deleted file mode 100644 index cf691aac0..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/FishCloudModifier.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct FishCloudModifier : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value position; - Value active; - Value repulsor; - Value swirl; - Value radius; - Value priority; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Flaahgra.hpp b/DataSpec/DNAMP1/ScriptObjects/Flaahgra.hpp deleted file mode 100644 index d8208209b..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Flaahgra.hpp +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Flaahgra : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters1; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - DamageVulnerability damageVulnerabilty; - UniqueID32 wpsc1; - DamageInfo damageInfo1; - UniqueID32 wpsc2; - DamageInfo damageInfo2; - UniqueID32 particle; - DamageInfo damageInfo3; - ActorParameters actorParameters2; - Value unknown5; - Value unknown6; - Value unknown7; - AnimationParameters animationParameters; - UniqueID32 dependencyGroup; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters1.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - actorParameters2.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); - ent->name = name + "_wpsc1"; - } - if (wpsc2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); - ent->name = name + "_wpsc2"; - } - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - if (dependencyGroup.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(dependencyGroup); - ent->name = name + "_dgrp"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters1.nameIDs(pakRouter, name + "_actp1"); - actorParameters2.nameIDs(pakRouter, name + "_actp2"); - animationParameters.nameANCS(pakRouter, name + "_animp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc1, pathsOut); - g_curSpec->flattenDependencies(wpsc2, pathsOut); - g_curSpec->flattenDependencies(particle, pathsOut); - g_curSpec->flattenDependencies(dependencyGroup, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters1.depIDs(pathsOut, lazyOut); - actorParameters2.depIDs(pathsOut, lazyOut); - animationParameters.depANCS(pathsOut); - } - - void gatherScans(std::vector& scansOut) const override { - actorParameters1.scanIDs(scansOut); - actorParameters2.scanIDs(scansOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/FlaahgraTentacle.hpp b/DataSpec/DNAMP1/ScriptObjects/FlaahgraTentacle.hpp deleted file mode 100644 index 0922909fe..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/FlaahgraTentacle.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct FlaahgraTentacle : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/FlickerBat.hpp b/DataSpec/DNAMP1/ScriptObjects/FlickerBat.hpp deleted file mode 100644 index ee0d3afcf..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/FlickerBat.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct FlickerBat : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value unknown1; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value collider; - Value startsHidden; - Value enableLineOfSight; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/FlyingPirate.hpp b/DataSpec/DNAMP1/ScriptObjects/FlyingPirate.hpp deleted file mode 100644 index ff0f3d5cd..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/FlyingPirate.hpp +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct FlyingPirate : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - Value unknown3; - UniqueID32 wpsc1; - DamageInfo damageInfo1; - Value unknown4; - UniqueID32 wpsc2; - DamageInfo damageInfo2; - UniqueID32 wpsc3; - Value unknown5; - Value unknown6; - UniqueID32 particle1; - DamageInfo damageInfo3; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - UniqueID32 particle2; - UniqueID32 particle3; - UniqueID32 particle4; - Value unknown16; - Value unknown17; - Value unknown18; - Value unknown19; - Value unknown20; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); - ent->name = name + "_wpsc1"; - } - if (wpsc2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); - ent->name = name + "_wpsc2"; - } - if (wpsc3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc3); - ent->name = name + "_wpsc3"; - } - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc1, pathsOut); - g_curSpec->flattenDependencies(wpsc2, pathsOut); - g_curSpec->flattenDependencies(wpsc3, pathsOut); - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/FogVolume.hpp b/DataSpec/DNAMP1/ScriptObjects/FogVolume.hpp deleted file mode 100644 index 421614c35..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/FogVolume.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct FogVolume : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value volume; - Value flickerSpeed; - Value unknown2; - Value fogColor; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Geemer.hpp b/DataSpec/DNAMP1/ScriptObjects/Geemer.hpp deleted file mode 100644 index f60cf648c..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Geemer.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Geemer : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value advanceWpRadius; - Value unknown2; - Value alignAngVel; - Value unknown4; - Value playerObstructionMinDist; - Value haltDelay; - Value forwardMoveWeight; - Value haltSfx; - Value getUpSfx; - Value crouchSfx; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Generator.hpp b/DataSpec/DNAMP1/ScriptObjects/Generator.hpp deleted file mode 100644 index b8a9f8205..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Generator.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Generator : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value spawnCount; - Value noReuseFollowers; - Value noInheritXf; - Value offset; - Value active; - Value minScale; - Value maxScale; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/GrapplePoint.hpp b/DataSpec/DNAMP1/ScriptObjects/GrapplePoint.hpp deleted file mode 100644 index 7090af783..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/GrapplePoint.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct GrapplePoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - GrappleParameters grappleParameters; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/GunTurret.hpp b/DataSpec/DNAMP1/ScriptObjects/GunTurret.hpp deleted file mode 100644 index 851dfa4fd..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/GunTurret.hpp +++ /dev/null @@ -1,121 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct GunTurret : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value unknown1; - Value location; - Value orientation; - Value scale; - Value collisionExtent; - Value collisionOffset; - AnimationParameters animationParameters; - ActorParameters actorParameters; - HealthInfo healthInfo; - DamageVulnerability damageVulnerabilty; - Value intoDeactivateDelay; - Value reloadTime; - Value reloadTimeVariance; - Value panStartTime; - Value panHoldTime; - Value totalPanSearchTime; - Value leftMaxAngle; - Value rightMaxAngle; - Value downMaxAngle; - Value turnSpeed; - Value detectionRange; - Value detectionZRange; - Value freezeDuration; - Value freezeVariance; - Value freezeTimeout; - UniqueID32 projectileRes; - DamageInfo projectileDamage; - UniqueID32 idleLightRes; - UniqueID32 deactivateLightRes; - UniqueID32 targettingLightRes; - UniqueID32 frozenEffectRes; - UniqueID32 chargingEffectRes; - UniqueID32 panningEffectRes; - UniqueID32 visorEffectRes; - Value trackingSoundId; - Value lockOnSoundId; - Value unfreezeSoundId; - Value stopClankSoundId; - Value chargingSoundId; - Value visorSoundId; - UniqueID32 extensionModelResId; - Value extensionDropDownDist; - Value numInitialShots; - Value initialShotTableIndex; - Value numSubsequentShots; - Value frenzyDuration; - Value scriptedStartOnly; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (projectileRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(projectileRes); - ent->name = name + "_projectileRes"; - } - if (idleLightRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(idleLightRes); - ent->name = name + "_idleLightRes"; - } - if (deactivateLightRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(deactivateLightRes); - ent->name = name + "_deactivateLightRes"; - } - if (targettingLightRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(targettingLightRes); - ent->name = name + "_targettingLightRes"; - } - if (frozenEffectRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(frozenEffectRes); - ent->name = name + "_frozenEffectRes"; - } - if (chargingEffectRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(chargingEffectRes); - ent->name = name + "_chargingEffectRes"; - } - if (panningEffectRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(panningEffectRes); - ent->name = name + "_panningEffectRes"; - } - if (visorEffectRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(visorEffectRes); - ent->name = name + "_visorEffectRes"; - } - if (extensionModelResId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(extensionModelResId); - ent->name = name + "_extensionModelResId"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(projectileRes, pathsOut); - g_curSpec->flattenDependencies(idleLightRes, pathsOut); - g_curSpec->flattenDependencies(deactivateLightRes, pathsOut); - g_curSpec->flattenDependencies(targettingLightRes, pathsOut); - g_curSpec->flattenDependencies(frozenEffectRes, pathsOut); - g_curSpec->flattenDependencies(chargingEffectRes, pathsOut); - g_curSpec->flattenDependencies(panningEffectRes, pathsOut); - g_curSpec->flattenDependencies(visorEffectRes, pathsOut); - g_curSpec->flattenDependencies(extensionModelResId, pathsOut); - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/HUDMemo.hpp b/DataSpec/DNAMP1/ScriptObjects/HUDMemo.hpp deleted file mode 100644 index 52356d9c5..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/HUDMemo.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct HUDMemo : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value firstMessageTimer; - Value unknown1; - Value memoType; - UniqueID32 message; - Value active; - - void nameIDs(PAKRouter& pakRouter) const override { - if (message.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(message); - ent->name = name + "_message"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(message, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/IScriptObject.cpp b/DataSpec/DNAMP1/ScriptObjects/IScriptObject.cpp deleted file mode 100644 index f29c32671..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/IScriptObject.cpp +++ /dev/null @@ -1,425 +0,0 @@ -#include "IScriptObject.hpp" - -#include "Actor.hpp" -#include "ActorContraption.hpp" -#include "ActorKeyframe.hpp" -#include "ActorRotate.hpp" -#include "AIJumpPoint.hpp" -#include "AIKeyframe.hpp" -#include "AmbientAI.hpp" -#include "AreaAttributes.hpp" -#include "AtomicAlpha.hpp" -#include "AtomicBeta.hpp" -#include "Babygoth.hpp" -#include "BallTrigger.hpp" -#include "Beetle.hpp" -#include "BloodFlower.hpp" -#include "Burrower.hpp" -#include "Camera.hpp" -#include "CameraBlurKeyframe.hpp" -#include "CameraFilterKeyframe.hpp" -#include "CameraHint.hpp" -#include "CameraHintTrigger.hpp" -#include "CameraPitchVolume.hpp" -#include "CameraShaker.hpp" -#include "CameraWaypoint.hpp" -#include "ChozoGhost.hpp" -#include "ColorModulate.hpp" -#include "ControllerAction.hpp" -#include "Counter.hpp" -#include "CoverPoint.hpp" -#include "DamageableTrigger.hpp" -#include "Debris.hpp" -#include "DebrisExtended.hpp" -#include "DebugCameraWaypoint.hpp" -#include "DistanceFog.hpp" -#include "Dock.hpp" -#include "DockAreaChange.hpp" -#include "DoorArea.hpp" -#include "Drone.hpp" -#include "Effect.hpp" -#include "ElectroMagneticPulse.hpp" -#include "ElitePirate.hpp" -#include "EnergyBall.hpp" -#include "EnvFxDensityController.hpp" -#include "Eyeball.hpp" -#include "FireFlea.hpp" -#include "FishCloud.hpp" -#include "FishCloudModifier.hpp" -#include "Flaahgra.hpp" -#include "FlaahgraTentacle.hpp" -#include "FlickerBat.hpp" -#include "FlyingPirate.hpp" -#include "FogVolume.hpp" -#include "Geemer.hpp" -#include "Generator.hpp" -#include "GrapplePoint.hpp" -#include "GunTurret.hpp" -#include "HUDMemo.hpp" -#include "IceSheegoth.hpp" -#include "IceZoomer.hpp" -#include "JellyZap.hpp" -#include "Magdolite.hpp" -#include "MazeNode.hpp" -#include "MemoryRelay.hpp" -#include "MetareeAlpha.hpp" -#include "MetroidAlpha.hpp" -#include "MetroidBeta.hpp" -#include "MetroidPrimeStage1.hpp" -#include "MetroidPrimeStage2.hpp" -#include "Midi.hpp" -#include "NewCameraShaker.hpp" -#include "NewIntroBoss.hpp" -#include "Oculus.hpp" -#include "OmegaPirate.hpp" -#include "Parasite.hpp" -#include "PathCamera.hpp" -#include "PhazonHealingNodule.hpp" -#include "PhazonPool.hpp" -#include "Pickup.hpp" -#include "PickupGenerator.hpp" -#include "Platform.hpp" -#include "PlayerActor.hpp" -#include "PlayerHint.hpp" -#include "PlayerStateChange.hpp" -#include "PointOfInterest.hpp" -#include "PuddleSpore.hpp" -#include "PuddleToadGamma.hpp" -#include "Puffer.hpp" -#include "RadialDamage.hpp" -#include "RandomRelay.hpp" -#include "Relay.hpp" -#include "Repulsor.hpp" -#include "Ridley.hpp" -#include "Ripper.hpp" -#include "Ripple.hpp" -#include "RoomAcoustics.hpp" -#include "RumbleEffect.hpp" -#include "ScriptBeam.hpp" -#include "ScriptTypes.hpp" -#include "Seedling.hpp" -#include "ShadowProjector.hpp" -#include "SnakeWeedSwarm.hpp" -#include "Sound.hpp" -#include "SpacePirate.hpp" -#include "SpankWeed.hpp" -#include "SpawnPoint.hpp" -#include "SpecialFunction.hpp" -#include "SpiderBallAttractionSurface.hpp" -#include "SpiderBallWaypoint.hpp" -#include "SpindleCamera.hpp" -#include "Steam.hpp" -#include "StreamedAudio.hpp" -#include "Switch.hpp" -#include "TargetingPoint.hpp" -#include "TeamAIMgr.hpp" -#include "Thardus.hpp" -#include "ThardusRockProjectile.hpp" -#include "ThermalHeatFader.hpp" -#include "Timer.hpp" -#include "Trigger.hpp" -#include "Tryclops.hpp" -#include "VisorFlare.hpp" -#include "VisorGoo.hpp" -#include "WallCrawlerSwarm.hpp" -#include "Warwasp.hpp" -#include "Water.hpp" -#include "Waypoint.hpp" -#include "WorldLightFader.hpp" -#include "WorldTeleporter.hpp" - -namespace DataSpec::DNAMP1 { -namespace priv { -namespace { -constexpr ScriptObjectSpec ActorEnt = {0x00, []() -> IScriptObject* { return new struct Actor(); }}; -constexpr ScriptObjectSpec WaypointEnt = {0x02, []() -> IScriptObject* { return new struct Waypoint(); }}; -constexpr ScriptObjectSpec DoorAreaEnt = {0x03, []() -> IScriptObject* { return new struct DoorArea(); }}; -constexpr ScriptObjectSpec TriggerEnt = {0x04, []() -> IScriptObject* { return new struct Trigger(); }}; -constexpr ScriptObjectSpec TimerEnt = {0x05, []() -> IScriptObject* { return new struct Timer(); }}; -constexpr ScriptObjectSpec CounterEnt = {0x06, []() -> IScriptObject* { return new struct Counter(); }}; -constexpr ScriptObjectSpec EffectEnt = {0x07, []() -> IScriptObject* { return new struct Effect(); }}; -constexpr ScriptObjectSpec PlatformEnt = {0x08, []() -> IScriptObject* { return new struct Platform(); }}; -constexpr ScriptObjectSpec SoundEnt = {0x09, []() -> IScriptObject* { return new struct Sound(); }}; -constexpr ScriptObjectSpec GeneratorEnt = {0x0A, []() -> IScriptObject* { return new struct Generator(); }}; -constexpr ScriptObjectSpec DockEnt = {0x0B, []() -> IScriptObject* { return new struct Dock(); }}; -constexpr ScriptObjectSpec CameraEnt = {0x0C, []() -> IScriptObject* { return new struct Camera(); }}; -constexpr ScriptObjectSpec CameraWaypointEnt = {0x0D, []() -> IScriptObject* { return new struct CameraWaypoint(); }}; -constexpr ScriptObjectSpec NewIntroBossEnt = {0x0E, []() -> IScriptObject* { return new struct NewIntroBoss(); }}; -constexpr ScriptObjectSpec SpawnPointEnt = {0x0F, []() -> IScriptObject* { return new struct SpawnPoint(); }}; -constexpr ScriptObjectSpec CameraHintEnt = {0x10, []() -> IScriptObject* { return new struct CameraHint(); }}; -constexpr ScriptObjectSpec PickupEnt = {0x11, []() -> IScriptObject* { return new struct Pickup(); }}; -constexpr ScriptObjectSpec MemoryRelayEnt = {0x13, []() -> IScriptObject* { return new struct MemoryRelay(); }}; -constexpr ScriptObjectSpec RandomRelayEnt = {0x14, []() -> IScriptObject* { return new struct RandomRelay(); }}; -constexpr ScriptObjectSpec RelayEnt = {0x15, []() -> IScriptObject* { return new struct Relay(); }}; -constexpr ScriptObjectSpec BeetleEnt = {0x16, []() -> IScriptObject* { return new struct Beetle(); }}; -constexpr ScriptObjectSpec HUDMemoEnt = {0x17, []() -> IScriptObject* { return new struct HUDMemo(); }}; -constexpr ScriptObjectSpec CameraFilterKeyframeEnt = { - 0x18, []() -> IScriptObject* { return new struct CameraFilterKeyframe(); }}; -constexpr ScriptObjectSpec CameraBlurKeyframeEnt = {0x19, - []() -> IScriptObject* { return new struct CameraBlurKeyframe(); }}; -constexpr ScriptObjectSpec DamageableTriggerEnt = {0x1A, - []() -> IScriptObject* { return new struct DamageableTrigger(); }}; -constexpr ScriptObjectSpec DebrisEnt = {0x1B, []() -> IScriptObject* { return new struct Debris(); }}; -constexpr ScriptObjectSpec CameraShakerEnt = {0x1C, []() -> IScriptObject* { return new struct CameraShaker(); }}; -constexpr ScriptObjectSpec ActorKeyframeEnt = {0x1D, []() -> IScriptObject* { return new struct ActorKeyframe(); }}; -constexpr ScriptObjectSpec WaterEnt = {0x20, []() -> IScriptObject* { return new struct Water(); }}; -constexpr ScriptObjectSpec WarwaspEnt = {0x21, []() -> IScriptObject* { return new struct Warwasp(); }}; -constexpr ScriptObjectSpec SpacePirateEnt = {0x24, []() -> IScriptObject* { return new struct SpacePirate(); }}; -constexpr ScriptObjectSpec FlyingPirateEnt = {0x25, []() -> IScriptObject* { return new struct FlyingPirate(); }}; -constexpr ScriptObjectSpec ElitePirateEnt = {0x26, []() -> IScriptObject* { return new struct ElitePirate(); }}; -constexpr ScriptObjectSpec MetroidBetaEnt = {0x27, []() -> IScriptObject* { return new struct MetroidBeta(); }}; -constexpr ScriptObjectSpec ChozoGhostEnt = {0x28, []() -> IScriptObject* { return new struct ChozoGhost(); }}; -constexpr ScriptObjectSpec CoverPointEnt = {0x2A, []() -> IScriptObject* { return new struct CoverPoint(); }}; -constexpr ScriptObjectSpec SpiderBallWaypointEnt = {0x2C, - []() -> IScriptObject* { return new struct SpiderBallWaypoint(); }}; -constexpr ScriptObjectSpec BloodFlowerEnt = {0x2D, []() -> IScriptObject* { return new struct BloodFlower(); }}; -constexpr ScriptObjectSpec FlickerBatEnt = {0x2E, []() -> IScriptObject* { return new struct FlickerBat(); }}; -constexpr ScriptObjectSpec PathCameraEnt = {0x2F, []() -> IScriptObject* { return new struct PathCamera(); }}; -constexpr ScriptObjectSpec GrapplePointEnt = {0x30, []() -> IScriptObject* { return new struct GrapplePoint(); }}; -constexpr ScriptObjectSpec PuddleSporeEnt = {0x31, []() -> IScriptObject* { return new struct PuddleSpore(); }}; -constexpr ScriptObjectSpec DebugCameraWaypointEnt = { - 0x32, []() -> IScriptObject* { return new struct DebugCameraWaypoint(); }}; -constexpr ScriptObjectSpec SpiderBallAttractionSurfaceEnt = { - 0x33, []() -> IScriptObject* { return new struct SpiderBallAttractionSurface(); }}; -constexpr ScriptObjectSpec PuddleToadGammaEnt = {0x34, []() -> IScriptObject* { return new struct PuddleToadGamma(); }}; -constexpr ScriptObjectSpec DistanceFogEnt = {0x35, []() -> IScriptObject* { return new struct DistanceFog(); }}; -constexpr ScriptObjectSpec FireFleaEnt = {0x36, []() -> IScriptObject* { return new struct FireFlea(); }}; -constexpr ScriptObjectSpec MetareeAlphaEnt = {0x37, []() -> IScriptObject* { return new struct MetareeAlpha(); }}; -constexpr ScriptObjectSpec DockAreaChangeEnt = {0x38, []() -> IScriptObject* { return new struct DockAreaChange(); }}; -constexpr ScriptObjectSpec ActorRotateEnt = {0x39, []() -> IScriptObject* { return new struct ActorRotate(); }}; -constexpr ScriptObjectSpec SpecialFunctionEnt = {0x3A, []() -> IScriptObject* { return new struct SpecialFunction(); }}; -constexpr ScriptObjectSpec SpankWeedEnt = {0x3B, []() -> IScriptObject* { return new struct SpankWeed(); }}; -constexpr ScriptObjectSpec ParasiteEnt = {0x3D, []() -> IScriptObject* { return new struct Parasite(); }}; -constexpr ScriptObjectSpec PlayerHintEnt = {0x3E, []() -> IScriptObject* { return new struct PlayerHint(); }}; -constexpr ScriptObjectSpec RipperEnt = {0x3F, []() -> IScriptObject* { return new struct Ripper(); }}; -constexpr ScriptObjectSpec PickupGeneratorEnt = {0x40, []() -> IScriptObject* { return new struct PickupGenerator(); }}; -constexpr ScriptObjectSpec AIKeyframeEnt = {0x41, []() -> IScriptObject* { return new struct AIKeyframe(); }}; -constexpr ScriptObjectSpec PointOfInterestEnt = {0x42, []() -> IScriptObject* { return new struct PointOfInterest(); }}; -constexpr ScriptObjectSpec DroneEnt = {0x43, []() -> IScriptObject* { return new struct Drone(); }}; -constexpr ScriptObjectSpec MetroidAlphaEnt = {0x44, []() -> IScriptObject* { return new struct MetroidAlpha(); }}; -constexpr ScriptObjectSpec DebrisExtendedEnt = {0x45, []() -> IScriptObject* { return new struct DebrisExtended(); }}; -constexpr ScriptObjectSpec SteamEnt = {0x46, []() -> IScriptObject* { return new struct Steam(); }}; -constexpr ScriptObjectSpec RippleEnt = {0x47, []() -> IScriptObject* { return new struct Ripple(); }}; -constexpr ScriptObjectSpec BallTriggerEnt = {0x48, []() -> IScriptObject* { return new struct BallTrigger(); }}; -constexpr ScriptObjectSpec TargetingPointEnt = {0x49, []() -> IScriptObject* { return new struct TargetingPoint(); }}; -constexpr ScriptObjectSpec ElectroMagneticPulseEnt = { - 0x4A, []() -> IScriptObject* { return new struct ElectroMagneticPulse(); }}; -constexpr ScriptObjectSpec IceSheegothEnt = {0x4B, []() -> IScriptObject* { return new struct IceSheegoth(); }}; -constexpr ScriptObjectSpec PlayerActorEnt = {0x4C, []() -> IScriptObject* { return new struct PlayerActor(); }}; -constexpr ScriptObjectSpec FlaahgraEnt = {0x4D, []() -> IScriptObject* { return new struct Flaahgra(); }}; -constexpr ScriptObjectSpec AreaAttributesEnt = {0x4E, []() -> IScriptObject* { return new struct AreaAttributes(); }}; -constexpr ScriptObjectSpec FishCloudEnt = {0x4F, []() -> IScriptObject* { return new struct FishCloud(); }}; -constexpr ScriptObjectSpec FishCloudModifierEnt = {0x50, - []() -> IScriptObject* { return new struct FishCloudModifier(); }}; -constexpr ScriptObjectSpec VisorFlareEnt = {0x51, []() -> IScriptObject* { return new struct VisorFlare(); }}; -constexpr ScriptObjectSpec WorldTeleporterx52Ent = {0x52, - []() -> IScriptObject* { return new struct WorldTeleporter(); }}; -constexpr ScriptObjectSpec VisorGooEnt = {0x53, []() -> IScriptObject* { return new struct VisorGoo(); }}; -constexpr ScriptObjectSpec JellyZapEnt = {0x54, []() -> IScriptObject* { return new struct JellyZap(); }}; -constexpr ScriptObjectSpec ControllerActionEnt = {0x55, - []() -> IScriptObject* { return new struct ControllerAction(); }}; -constexpr ScriptObjectSpec SwitchEnt = {0x56, []() -> IScriptObject* { return new struct Switch(); }}; -constexpr ScriptObjectSpec PlayerStateChangeEnt = {0x57, - []() -> IScriptObject* { return new struct PlayerStateChange(); }}; -constexpr ScriptObjectSpec ThardusEnt = {0x58, []() -> IScriptObject* { return new struct Thardus(); }}; -constexpr ScriptObjectSpec WallCrawlerSwarmEnt = {0x5A, - []() -> IScriptObject* { return new struct WallCrawlerSwarm(); }}; -constexpr ScriptObjectSpec AIJumpPointEnt = {0x5B, []() -> IScriptObject* { return new struct AIJumpPoint(); }}; -constexpr ScriptObjectSpec FlaahgraTentacleEnt = {0x5C, - []() -> IScriptObject* { return new struct FlaahgraTentacle(); }}; -constexpr ScriptObjectSpec RoomAcousticsEnt = {0x5D, []() -> IScriptObject* { return new struct RoomAcoustics(); }}; -constexpr ScriptObjectSpec ColorModulateEnt = {0x5E, []() -> IScriptObject* { return new struct ColorModulate(); }}; -constexpr ScriptObjectSpec ThardusRockProjectileEnt = { - 0x5F, []() -> IScriptObject* { return new struct ThardusRockProjectile(); }}; -constexpr ScriptObjectSpec MidiEnt = {0x60, []() -> IScriptObject* { return new struct Midi(); }}; -constexpr ScriptObjectSpec StreamedAudioEnt = {0x61, []() -> IScriptObject* { return new struct StreamedAudio(); }}; -constexpr ScriptObjectSpec WorldTeleporterx62Ent = { - 0x62, []() -> IScriptObject* { return new struct WorldTeleporter(); }}; // o.o, no this is not a trick -constexpr ScriptObjectSpec RepulsorEnt = {0x63, []() -> IScriptObject* { return new struct Repulsor(); }}; -constexpr ScriptObjectSpec GunTurretEnt = {0x64, []() -> IScriptObject* { return new struct GunTurret(); }}; -constexpr ScriptObjectSpec FogVolumeEnt = {0x65, []() -> IScriptObject* { return new struct FogVolume(); }}; -constexpr ScriptObjectSpec BabygothEnt = {0x66, []() -> IScriptObject* { return new struct Babygoth(); }}; -constexpr ScriptObjectSpec EyeballEnt = {0x67, []() -> IScriptObject* { return new struct Eyeball(); }}; -constexpr ScriptObjectSpec RadialDamageEnt = {0x68, []() -> IScriptObject* { return new struct RadialDamage(); }}; -constexpr ScriptObjectSpec CameraPitchVolumeEnt = {0x69, - []() -> IScriptObject* { return new struct CameraPitchVolume(); }}; -constexpr ScriptObjectSpec EnvFxDensityControllerEnt = { - 0x6A, []() -> IScriptObject* { return new struct EnvFxDensityController(); }}; -constexpr ScriptObjectSpec MagdoliteEnt = {0x6B, []() -> IScriptObject* { return new struct Magdolite(); }}; -constexpr ScriptObjectSpec TeamAIMgrEnt = {0x6C, []() -> IScriptObject* { return new struct TeamAIMgr(); }}; -constexpr ScriptObjectSpec SnakeWeedSwarmEnt = {0x6D, []() -> IScriptObject* { return new struct SnakeWeedSwarm(); }}; -constexpr ScriptObjectSpec ActorContraptionEnt = {0x6E, - []() -> IScriptObject* { return new struct ActorContraption(); }}; -constexpr ScriptObjectSpec OculusEnt = {0x6F, []() -> IScriptObject* { return new struct Oculus(); }}; -constexpr ScriptObjectSpec GeemerEnt = {0x70, []() -> IScriptObject* { return new struct Geemer(); }}; -constexpr ScriptObjectSpec SpindleCameraEnt = {0x71, []() -> IScriptObject* { return new struct SpindleCamera(); }}; -constexpr ScriptObjectSpec AtomicAlphaEnt = {0x72, []() -> IScriptObject* { return new struct AtomicAlpha(); }}; -constexpr ScriptObjectSpec CameraHintTriggerEnt = {0x73, - []() -> IScriptObject* { return new struct CameraHintTrigger(); }}; -constexpr ScriptObjectSpec RumbleEffectEnt = {0x74, []() -> IScriptObject* { return new struct RumbleEffect(); }}; -constexpr ScriptObjectSpec AmbientAIEnt = {0x75, []() -> IScriptObject* { return new struct AmbientAI(); }}; -constexpr ScriptObjectSpec AtomicBetaEnt = {0x77, []() -> IScriptObject* { return new struct AtomicBeta(); }}; -constexpr ScriptObjectSpec IceZoomerEnt = {0x78, []() -> IScriptObject* { return new struct IceZoomer(); }}; -constexpr ScriptObjectSpec PufferEnt = {0x79, []() -> IScriptObject* { return new struct Puffer(); }}; -constexpr ScriptObjectSpec TryclopsEnt = {0x7A, []() -> IScriptObject* { return new struct Tryclops(); }}; -constexpr ScriptObjectSpec RidleyEnt = {0x7B, []() -> IScriptObject* { return new struct Ridley(); }}; -constexpr ScriptObjectSpec SeedlingEnt = {0x7C, []() -> IScriptObject* { return new struct Seedling(); }}; -constexpr ScriptObjectSpec ThermalHeatFaderEnt = {0x7D, - []() -> IScriptObject* { return new struct ThermalHeatFader(); }}; -constexpr ScriptObjectSpec BurrowerEnt = {0x7F, []() -> IScriptObject* { return new struct Burrower(); }}; -constexpr ScriptObjectSpec ScriptBeamEnt = {0x81, []() -> IScriptObject* { return new struct ScriptBeam(); }}; -constexpr ScriptObjectSpec WorldLightFaderEnt = {0x82, []() -> IScriptObject* { return new struct WorldLightFader(); }}; -constexpr ScriptObjectSpec MetroidPrimeStage2Ent = {0x83, - []() -> IScriptObject* { return new struct MetroidPrimeStage2(); }}; -constexpr ScriptObjectSpec MetroidPrimeStage1Ent = {0x84, - []() -> IScriptObject* { return new struct MetroidPrimeStage1(); }}; -constexpr ScriptObjectSpec MazeNodeEnt = {0x85, []() -> IScriptObject* { return new struct MazeNode(); }}; -constexpr ScriptObjectSpec OmegaPirateEnt = {0x86, []() -> IScriptObject* { return new struct OmegaPirate(); }}; -constexpr ScriptObjectSpec PhazonPoolEnt = {0x87, []() -> IScriptObject* { return new struct PhazonPool(); }}; -constexpr ScriptObjectSpec PhazonHealingNoduleEnt = { - 0x88, []() -> IScriptObject* { return new struct PhazonHealingNodule(); }}; -constexpr ScriptObjectSpec NewCameraShakerEnt = {0x89, []() -> IScriptObject* { return new struct NewCameraShaker(); }}; -constexpr ScriptObjectSpec ShadowProjectorEnt = {0x8A, []() -> IScriptObject* { return new struct ShadowProjector(); }}; -constexpr ScriptObjectSpec EnergyBallEnt = {0x8B, []() -> IScriptObject* { return new struct EnergyBall(); }}; -} // Anonymous namespace -} // namespace priv - -const ScriptObjectDBArray SCRIPT_OBJECT_DB = { - &priv::AIJumpPointEnt, - &priv::AIKeyframeEnt, - &priv::ActorEnt, - &priv::ActorContraptionEnt, - &priv::ActorKeyframeEnt, - &priv::ActorRotateEnt, - &priv::AmbientAIEnt, - &priv::AreaAttributesEnt, - &priv::AtomicAlphaEnt, - &priv::AtomicBetaEnt, - &priv::BabygothEnt, - &priv::BallTriggerEnt, - &priv::BeetleEnt, - &priv::BloodFlowerEnt, - &priv::BurrowerEnt, - &priv::CameraEnt, - &priv::CameraBlurKeyframeEnt, - &priv::CameraFilterKeyframeEnt, - &priv::CameraHintEnt, - &priv::CameraHintTriggerEnt, - &priv::CameraPitchVolumeEnt, - &priv::CameraShakerEnt, - &priv::CameraWaypointEnt, - &priv::ChozoGhostEnt, - &priv::ColorModulateEnt, - &priv::ControllerActionEnt, - &priv::CounterEnt, - &priv::CoverPointEnt, - &priv::DamageableTriggerEnt, - &priv::DebrisEnt, - &priv::DebrisExtendedEnt, - &priv::DebugCameraWaypointEnt, - &priv::DistanceFogEnt, - &priv::DockEnt, - &priv::DockAreaChangeEnt, - &priv::DoorAreaEnt, - &priv::DroneEnt, - &priv::EffectEnt, - &priv::ElectroMagneticPulseEnt, - &priv::ElitePirateEnt, - &priv::EnergyBallEnt, - &priv::EnvFxDensityControllerEnt, - &priv::EyeballEnt, - &priv::FireFleaEnt, - &priv::FishCloudEnt, - &priv::FishCloudModifierEnt, - &priv::FlaahgraEnt, - &priv::FlaahgraTentacleEnt, - &priv::FlickerBatEnt, - &priv::FlyingPirateEnt, - &priv::FogVolumeEnt, - &priv::GeemerEnt, - &priv::GeneratorEnt, - &priv::GrapplePointEnt, - &priv::GunTurretEnt, - &priv::HUDMemoEnt, - &priv::IceSheegothEnt, - &priv::IceZoomerEnt, - &priv::JellyZapEnt, - &priv::MagdoliteEnt, - &priv::MazeNodeEnt, - &priv::MemoryRelayEnt, - &priv::MetareeAlphaEnt, - &priv::MetroidAlphaEnt, - &priv::MetroidBetaEnt, - &priv::MetroidPrimeStage1Ent, - &priv::MetroidPrimeStage2Ent, - &priv::MidiEnt, - &priv::NewCameraShakerEnt, - &priv::NewIntroBossEnt, - &priv::OculusEnt, - &priv::OmegaPirateEnt, - &priv::ParasiteEnt, - &priv::PathCameraEnt, - &priv::PhazonHealingNoduleEnt, - &priv::PhazonPoolEnt, - &priv::PickupEnt, - &priv::PickupGeneratorEnt, - &priv::PlatformEnt, - &priv::PlayerActorEnt, - &priv::PlayerHintEnt, - &priv::PlayerStateChangeEnt, - &priv::PointOfInterestEnt, - &priv::PuddleSporeEnt, - &priv::PuddleToadGammaEnt, - &priv::PufferEnt, - &priv::RadialDamageEnt, - &priv::RandomRelayEnt, - &priv::RelayEnt, - &priv::RepulsorEnt, - &priv::RidleyEnt, - &priv::RipperEnt, - &priv::RippleEnt, - &priv::RoomAcousticsEnt, - &priv::RumbleEffectEnt, - &priv::ScriptBeamEnt, - &priv::SeedlingEnt, - &priv::ShadowProjectorEnt, - &priv::SnakeWeedSwarmEnt, - &priv::SoundEnt, - &priv::SpacePirateEnt, - &priv::SpankWeedEnt, - &priv::SpawnPointEnt, - &priv::SpecialFunctionEnt, - &priv::SpiderBallAttractionSurfaceEnt, - &priv::SpiderBallWaypointEnt, - &priv::SpindleCameraEnt, - &priv::SteamEnt, - &priv::StreamedAudioEnt, - &priv::SwitchEnt, - &priv::TargetingPointEnt, - &priv::TeamAIMgrEnt, - &priv::ThardusEnt, - &priv::ThardusRockProjectileEnt, - &priv::ThermalHeatFaderEnt, - &priv::TimerEnt, - &priv::TriggerEnt, - &priv::TryclopsEnt, - &priv::VisorFlareEnt, - &priv::VisorGooEnt, - &priv::WallCrawlerSwarmEnt, - &priv::WarwaspEnt, - &priv::WaterEnt, - &priv::WaypointEnt, - &priv::WorldLightFaderEnt, - &priv::WorldTeleporterx52Ent, - &priv::WorldTeleporterx62Ent, -}; - -zeus::CTransform ConvertEditorEulerToTransform4f(const zeus::CVector3f& scale, const zeus::CVector3f& orientation, - const zeus::CVector3f& position) { - zeus::simd_floats f(orientation.mSimd); - return zeus::CTransform::RotateZ(zeus::degToRad(f[2])) * zeus::CTransform::RotateY(zeus::degToRad(f[1])) * - zeus::CTransform::RotateX(zeus::degToRad(f[0])) * zeus::CTransform::Scale(scale) + - position; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/IScriptObject.hpp b/DataSpec/DNAMP1/ScriptObjects/IScriptObject.hpp deleted file mode 100644 index 53f118ef8..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/IScriptObject.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include "../../DNACommon/DNACommon.hpp" -#include "../DNAMP1.hpp" -#include "../SAVW.hpp" -#include "zeus/CAABox.hpp" - -#include - -namespace DataSpec::DNAMP1 { - -zeus::CTransform ConvertEditorEulerToTransform4f(const zeus::CVector3f& scale, const zeus::CVector3f& orientation, - const zeus::CVector3f& position); - -struct IScriptObject : BigDNAVYaml { - AT_DECL_DNA_YAMLV - atUint32 type; - Value id; - struct Connection : BigDNA { - AT_DECL_DNA_YAML - Value state; - Value msg; - Value target; - }; - - Value connectionCount; - Vector connections; - Value propertyCount; - ~IScriptObject() override = default; - - virtual void addCMDLRigPairs(PAKRouter&, CharacterAssociations& charAssoc) const {} - virtual void nameIDs(PAKRouter& pakRouter) const {} - virtual void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const {} - virtual void gatherScans(std::vector& scansOut) const {} - virtual zeus::CAABox getVISIAABB(hecl::blender::Token& btok) const { return {}; } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/IceSheegoth.hpp b/DataSpec/DNAMP1/ScriptObjects/IceSheegoth.hpp deleted file mode 100644 index 1df66c93a..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/IceSheegoth.hpp +++ /dev/null @@ -1,115 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct IceSheegoth : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - DamageVulnerability damageVulnerabilty1; - DamageVulnerability damageVulnerabilty2; - DamageVulnerability damageVulnerabilty3; - UniqueID32 wpsc1; - DamageInfo damageInfo1; - Value unknown5; - Value unknown6; - UniqueID32 wpsc2; - UniqueID32 particle1; - DamageInfo damageInfo2; - UniqueID32 particle2; - UniqueID32 particle3; - UniqueID32 particle4; - UniqueID32 particle5; - UniqueID32 elsc; - Value unknown7; - Value unknown8; - DamageInfo damageInfo3; - Value soundID1; - Value unknown9; - Value unknown10; - Value unknown11; - UniqueID32 texture; - Value soundID2; - UniqueID32 particle6; - Value unknown12; - Value unknown13; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); - ent->name = name + "_wpsc1"; - } - if (wpsc2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); - ent->name = name + "_wpsc2"; - } - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - if (particle5.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle5); - ent->name = name + "_part5"; - } - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_texture"; - } - if (particle6.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle6); - ent->name = name + "_part6"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc1, pathsOut); - g_curSpec->flattenDependencies(wpsc2, pathsOut); - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - g_curSpec->flattenDependencies(particle5, pathsOut); - g_curSpec->flattenDependencies(elsc, pathsOut); - g_curSpec->flattenDependencies(texture, pathsOut); - g_curSpec->flattenDependencies(particle6, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/IceZoomer.hpp b/DataSpec/DNAMP1/ScriptObjects/IceZoomer.hpp deleted file mode 100644 index b768f8b7f..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/IceZoomer.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct IceZoomer : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value advanceWpRadius; - Value unknown2; - Value alignAngleVel; - Value unknown4; - Value playerObstructionMinDist; - Value moveForwardWeight; - UniqueID32 modelRes; - UniqueID32 skinRes; - DamageVulnerability damageVulnerabilty; - Value unknown9; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - g_curSpec->flattenDependencies(modelRes, pathsOut); - g_curSpec->flattenDependencies(skinRes, pathsOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/JellyZap.hpp b/DataSpec/DNAMP1/ScriptObjects/JellyZap.hpp deleted file mode 100644 index 26dacd35a..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/JellyZap.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct JellyZap : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - DamageInfo damageInfo; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Magdolite.hpp b/DataSpec/DNAMP1/ScriptObjects/Magdolite.hpp deleted file mode 100644 index 0b690e242..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Magdolite.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Magdolite : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - DamageInfo damageInfo1; - DamageInfo damageInfo2; - DamageVulnerability damageVulnerabilty1; - DamageVulnerability damageVulnerabilty2; - UniqueID32 cmdlHeadless; - UniqueID32 cskrHeadless; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - struct MagdoliteParameters : BigDNA { - AT_DECL_DNA - Value propertyCount; - Value unknown1; - UniqueID32 particle; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - } magdoliteParameters; - Value unknown7; - Value unknown8; - Value unknown9; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - UniqueID32 cinf = patternedInfo.animationParameters.getCINF(pakRouter); - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - - if (cmdlHeadless.isValid() && cskrHeadless.isValid()) { - charAssoc.m_cmdlRigs[cmdlHeadless] = {cskrHeadless, cinf}; - charAssoc.m_cskrToCharacter[cskrHeadless] = - std::make_pair(patternedInfo.animationParameters.animationCharacterSet, - fmt::format(FMT_STRING("ATTACH.HEADLESS_{}.CSKR"), cskrHeadless)); - charAssoc.addAttachmentRig(patternedInfo.animationParameters.animationCharacterSet, {}, cmdlHeadless, "HEADLESS"); - } - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (cmdlHeadless.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(cmdlHeadless); - ent->name = name + "_emodel"; - } - if (cskrHeadless.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(cskrHeadless); - ent->name = name + "_eskin"; - } - if (magdoliteParameters.particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(magdoliteParameters.particle); - ent->name = name + "_part"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(cmdlHeadless, pathsOut); - g_curSpec->flattenDependencies(cskrHeadless, pathsOut); - g_curSpec->flattenDependencies(magdoliteParameters.particle, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/MazeNode.hpp b/DataSpec/DNAMP1/ScriptObjects/MazeNode.hpp deleted file mode 100644 index b93a60691..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/MazeNode.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct MazeNode : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value col; - Value row; - Value side; - Value actorPos; - Value triggerPos; - Value effectPos; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/MemoryRelay.hpp b/DataSpec/DNAMP1/ScriptObjects/MemoryRelay.hpp deleted file mode 100644 index 6b95a5788..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/MemoryRelay.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct MemoryRelay : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value skipSendActive; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/MetareeAlpha.hpp b/DataSpec/DNAMP1/ScriptObjects/MetareeAlpha.hpp deleted file mode 100644 index 7d96cc102..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/MetareeAlpha.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct MetareeAlpha : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - DamageInfo damageInfo; - Value dropHeight; - Value offset; - Value attackSpeed; - Value delay; - Value unknown5; // Appears to be unused - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/MetroidAlpha.hpp b/DataSpec/DNAMP1/ScriptObjects/MetroidAlpha.hpp deleted file mode 100644 index 08c2126df..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/MetroidAlpha.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct MetroidAlpha : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value unknown1; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - DamageVulnerability damageVulnerabilty1; - DamageVulnerability damageVulnerabilty2; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - AnimationParameters animationParameters1; - AnimationParameters animationParameters2; - AnimationParameters animationParameters3; - AnimationParameters animationParameters4; - Value unknown8; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - animationParameters1.nameANCS(pakRouter, name + "_animp1"); - animationParameters2.nameANCS(pakRouter, name + "_animp2"); - animationParameters3.nameANCS(pakRouter, name + "_animp3"); - animationParameters4.nameANCS(pakRouter, name + "_animp4"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - animationParameters1.depANCS(pathsOut); - animationParameters2.depANCS(pathsOut); - animationParameters3.depANCS(pathsOut); - animationParameters4.depANCS(pathsOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/MetroidBeta.hpp b/DataSpec/DNAMP1/ScriptObjects/MetroidBeta.hpp deleted file mode 100644 index 0b04c0562..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/MetroidBeta.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct MetroidBeta : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - DamageVulnerability damageVulnerabilty1; - DamageVulnerability damageVulnerabilty2; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - UniqueID32 particle1; - UniqueID32 swhc; - UniqueID32 particle2; - UniqueID32 particle3; - UniqueID32 particle4; - Value unknown10; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - if (swhc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(swhc); - ent->name = name + "_swhc"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - g_curSpec->flattenDependencies(swhc, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/MetroidPrimeStage1.hpp b/DataSpec/DNAMP1/ScriptObjects/MetroidPrimeStage1.hpp deleted file mode 100644 index f89f2be46..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/MetroidPrimeStage1.hpp +++ /dev/null @@ -1,303 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct MetroidPrimeStage1 : IScriptObject { - AT_DECL_DNA_YAMLV - Value version; - String<-1> name; - Value location; - Value orientation; - Value scale; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - HealthInfo healthInfo1; - HealthInfo healthInfo2; - Value unknown9; - - struct PrimeParameters1 : BigDNA { - AT_DECL_DNA - Value propertyCount; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - } primeStruct1[4]; - - Value unknown10; - Value unknown11; - - struct MassivePrimeStruct : BigDNA { - AT_DECL_DNA - Value propertyCount; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown2; - struct CameraShakeData : BigDNA { - AT_DECL_DNA - Value useSfx; - Value duration; - Value sfxDist; - struct CameraShakerComponent : BigDNA { - AT_DECL_DNA - Value useModulation; - struct CameraShakePoint : BigDNA { - AT_DECL_DNA - Value attackTime; - Value sustainTime; - Value duration; - Value magnitude; - }; - CameraShakePoint am; - CameraShakePoint fm; - } shakerComponents[3]; - } shakeDatas[3]; - - struct PrimeStruct2B : BigDNA { - AT_DECL_DNA - Value propertyCount; - UniqueID32 particle1; - UniqueID32 particle2; - UniqueID32 particle3; - DamageInfo damageInfo1; - Value unknown5; - Value unknown6; - UniqueID32 texture1; - Value unknown7; - Value unknown8; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (texture1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture1); - ent->name = name + "_tex1"; - } - } - - void depIDs(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(texture1, pathsOut); - } - } primeStruct2b; - - UniqueID32 particle4; - - struct PrimeStruct4 : BigDNA { - AT_DECL_DNA - BeamInfo beamInfo; - UniqueID32 wpsc; - DamageInfo damageInfo1; - struct PrimeStruct5 : BigDNA { - AT_DECL_DNA - Value propertyCount; - UniqueID32 unknown1; - Value unknown2; - UniqueID32 unknown3; - UniqueID32 unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - if (unknown1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(unknown1); - ent->name = name + "_unk1"; - } - if (unknown3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(unknown3); - ent->name = name + "_unk3"; - } - if (unknown4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(unknown4); - ent->name = name + "_unk4"; - } - } - - void depIDs(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(unknown1, pathsOut); - g_curSpec->flattenDependencies(unknown3, pathsOut); - g_curSpec->flattenDependencies(unknown4, pathsOut); - } - } primeStruct5; - Value unknown14; - DamageInfo damageInfo2; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - beamInfo.nameIDs(pakRouter, name + "_beamInfo"); - if (wpsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); - ent->name = name + "_wpsc"; - } - primeStruct5.nameIDs(pakRouter, name + "_prime5"); - } - - void depIDs(std::vector& pathsOut) const { - beamInfo.depIDs(pathsOut); - g_curSpec->flattenDependencies(wpsc, pathsOut); - primeStruct5.depIDs(pathsOut); - } - } primeStruct4s[4]; - - UniqueID32 wpsc1; - DamageInfo damageInfo2; - CameraShakeData primeStruct2_4; - UniqueID32 wpsc2; - DamageInfo damageInfo3; - CameraShakeData primeStruct2_5; - - struct PrimeProjectileInfo : BigDNA { - AT_DECL_DNA - Value propertyCount; - UniqueID32 particle; - DamageInfo damageInfo4; - Value unknown9; - Value unknown10; - Value unknown11; - UniqueID32 texture; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_tex"; - } - } - - void depIDs(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(particle, pathsOut); - g_curSpec->flattenDependencies(texture, pathsOut); - } - } projectileInfo; - - DamageInfo damageInfo5; - CameraShakeData primeStruct2_6; - UniqueID32 particle6; - UniqueID32 swhc; - UniqueID32 particle7; - UniqueID32 particle8; - - struct PrimeStruct6 : BigDNA { - AT_DECL_DNA - Value propertyCount; - DamageVulnerability damageVulnerability; - DNAColor unknown1; - Value unknown2; - Value unknown3; - } primeStruct6s[4]; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - primeStruct2b.nameIDs(pakRouter, name + "_prime2b"); - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - if (particle6.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle6); - ent->name = name + "_part6"; - } - if (particle7.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle7); - ent->name = name + "_part7"; - } - if (particle8.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle8); - ent->name = name + "_part8"; - } - if (swhc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(swhc); - ent->name = name + "_swhc"; - } - if (wpsc1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); - ent->name = name + "_wpsc1"; - } - if (wpsc2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); - ent->name = name + "_wpsc2"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - primeStruct4s[0].nameIDs(pakRouter, name + "_prime41"); - primeStruct4s[1].nameIDs(pakRouter, name + "_prime42"); - primeStruct4s[2].nameIDs(pakRouter, name + "_prime43"); - primeStruct4s[3].nameIDs(pakRouter, name + "_prime44"); - projectileInfo.nameIDs(pakRouter, name + "_projectileInfo"); - } - - void depIDs(std::vector& pathsOut, std::vector& lazyOut) const { - primeStruct2b.depIDs(pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - g_curSpec->flattenDependencies(particle6, pathsOut); - g_curSpec->flattenDependencies(particle7, pathsOut); - g_curSpec->flattenDependencies(particle8, pathsOut); - g_curSpec->flattenDependencies(swhc, pathsOut); - g_curSpec->flattenDependencies(wpsc1, pathsOut); - g_curSpec->flattenDependencies(wpsc2, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - primeStruct4s[0].depIDs(pathsOut); - primeStruct4s[1].depIDs(pathsOut); - primeStruct4s[2].depIDs(pathsOut); - primeStruct4s[3].depIDs(pathsOut); - projectileInfo.depIDs(pathsOut); - } - - void scanIDs(std::vector& scansOut) const { actorParameters.scanIDs(scansOut); } - } massivePrimeStruct; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - massivePrimeStruct.actorParameters.addCMDLRigPairs(pakRouter, charAssoc, - massivePrimeStruct.patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - massivePrimeStruct.nameIDs(pakRouter, name + "_massiveStruct"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - massivePrimeStruct.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { massivePrimeStruct.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/MetroidPrimeStage2.hpp b/DataSpec/DNAMP1/ScriptObjects/MetroidPrimeStage2.hpp deleted file mode 100644 index 5ca1e250d..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/MetroidPrimeStage2.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct MetroidPrimeStage2 : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - UniqueID32 particle1; - DamageInfo damageInfo; - UniqueID32 elsc; - Value unknown; - UniqueID32 particle2; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(elsc, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Midi.hpp b/DataSpec/DNAMP1/ScriptObjects/Midi.hpp deleted file mode 100644 index 99bcb9413..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Midi.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Midi : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - UniqueID32 song; - Value fadeInTime; - Value fadeOutTime; - Value volume; - - void nameIDs(PAKRouter& pakRouter) const override { - if (song.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(song); - ent->name = name + "_song"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - // Dedicated PAK for this - // g_curSpec->flattenDependencies(song, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/NewCameraShaker.hpp b/DataSpec/DNAMP1/ScriptObjects/NewCameraShaker.hpp deleted file mode 100644 index 747ebbe16..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/NewCameraShaker.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct NewCameraShaker : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value active; - PropertyFlags flags; - Value duration; - Value sfxDist; - struct CameraShakerComponent : BigDNA { - AT_DECL_DNA - PropertyFlags flags; - struct CameraShakePoint : BigDNA { - AT_DECL_DNA - PropertyFlags flags; - Value attackTime; - Value sustainTime; - Value duration; - Value magnitude; - }; - CameraShakePoint am; - CameraShakePoint fm; - } shakerComponents[3]; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/NewIntroBoss.hpp b/DataSpec/DNAMP1/ScriptObjects/NewIntroBoss.hpp deleted file mode 100644 index 23174930d..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/NewIntroBoss.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct NewIntroBoss : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value minTurnAngle; - UniqueID32 weaponDesc; - DamageInfo damageInfo; - UniqueID32 beamContactFxId; - UniqueID32 beamPulseFxId; - UniqueID32 beamTextureId; - UniqueID32 beamGlowTextureId; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (beamContactFxId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamContactFxId); - ent->name = name + "_beamContactFxId"; - } - if (beamPulseFxId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamPulseFxId); - ent->name = name + "_beamPulseFxId"; - } - if (beamTextureId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamTextureId); - ent->name = name + "_beamTextureId"; - } - if (beamGlowTextureId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamGlowTextureId); - ent->name = name + "_beamGlowTextureId"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(weaponDesc, pathsOut); - g_curSpec->flattenDependencies(beamContactFxId, pathsOut); - g_curSpec->flattenDependencies(beamPulseFxId, pathsOut); - g_curSpec->flattenDependencies(beamTextureId, pathsOut); - g_curSpec->flattenDependencies(beamGlowTextureId, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Oculus.cpp b/DataSpec/DNAMP1/ScriptObjects/Oculus.cpp deleted file mode 100644 index 158db716f..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Oculus.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "Oculus.hpp" - -namespace DataSpec::DNAMP1 { - -template -void Oculus::Enumerate(typename Op::StreamT& s) { - IScriptObject::Enumerate(s); - Do(athena::io::PropId{"name"}, name, s); - Do(athena::io::PropId{"location"}, location, s); - Do(athena::io::PropId{"orientation"}, orientation, s); - Do(athena::io::PropId{"scale"}, scale, s); - Do(athena::io::PropId{"patternedInfo"}, patternedInfo, s); - Do(athena::io::PropId{"actorParameters"}, actorParameters, s); - Do(athena::io::PropId{"unknown1"}, unknown1, s); - Do(athena::io::PropId{"unknown2"}, unknown2, s); - Do(athena::io::PropId{"unknown3"}, unknown3, s); - Do(athena::io::PropId{"unknown4"}, unknown4, s); - Do(athena::io::PropId{"unknown5"}, unknown5, s); - Do(athena::io::PropId{"unknown6"}, unknown6, s); - Do(athena::io::PropId{"damageVulnerabilty"}, damageVulnerabilty, s); - Do(athena::io::PropId{"unknown7"}, unknown7, s); - Do(athena::io::PropId{"damageInfo"}, damageInfo, s); - if (propertyCount == 16) - Do(athena::io::PropId{"unknown8"}, unknown8, s); - else - unknown8 = 0.f; -} - -std::string_view Oculus::DNAType() { return "DNAMP1::Oculus"sv; } - -AT_SPECIALIZE_DNA_YAML(Oculus) - -} // namespace DataSpec::DNAMP1 \ No newline at end of file diff --git a/DataSpec/DNAMP1/ScriptObjects/Oculus.hpp b/DataSpec/DNAMP1/ScriptObjects/Oculus.hpp deleted file mode 100644 index ee69e2d5f..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Oculus.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Oculus : IScriptObject { - AT_DECL_EXPLICIT_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - DamageVulnerability damageVulnerabilty; - Value unknown7; - DamageInfo damageInfo; - - /* Trilogy addition */ - Value unknown8; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/OmegaPirate.hpp b/DataSpec/DNAMP1/ScriptObjects/OmegaPirate.hpp deleted file mode 100644 index c65cf752c..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/OmegaPirate.hpp +++ /dev/null @@ -1,149 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct OmegaPirate : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters1; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - UniqueID32 particle1; - Value soundID1; - ActorParameters actorParameters2; - AnimationParameters animationParameters; - UniqueID32 particle2; - Value soundID2; - UniqueID32 model1; - DamageInfo damageInfo1; - Value unknown9; - UniqueID32 particle3; - UniqueID32 particle4; - UniqueID32 particle5; - UniqueID32 particle6; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - Value unknown16; - Value soundID3; - Value soundID4; - UniqueID32 particle7; - DamageInfo damageInfo2; - UniqueID32 elsc; - Value soundID5; - Value unknown17; - Value unknown18; - UniqueID32 cmdlPhazonVeins; - UniqueID32 cskrPhazonVeins; - UniqueID32 cinfPhazonVeins; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters1.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - actorParameters2.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - if (cmdlPhazonVeins.isValid() && cskrPhazonVeins.isValid() && cinfPhazonVeins.isValid()) { - charAssoc.m_cmdlRigs[cmdlPhazonVeins] = {cskrPhazonVeins, cinfPhazonVeins}; - charAssoc.m_cskrToCharacter[cskrPhazonVeins] = - std::make_pair(patternedInfo.animationParameters.animationCharacterSet, - fmt::format(FMT_STRING("ATTACH.VEINS_{}.CSKR"), cskrPhazonVeins)); - charAssoc.addAttachmentRig(patternedInfo.animationParameters.animationCharacterSet, cinfPhazonVeins, - cmdlPhazonVeins, "VEINS"); - } - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - if (particle5.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle5); - ent->name = name + "_part5"; - } - if (particle6.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle6); - ent->name = name + "_part6"; - } - if (particle7.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle7); - ent->name = name + "_part7"; - } - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - if (model1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model1); - ent->name = name + "_model1"; - } - if (cmdlPhazonVeins.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(cmdlPhazonVeins); - ent->name = name + "_model2"; - } - if (cskrPhazonVeins.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(cskrPhazonVeins); - ent->name = name + "_skin"; - } - if (cinfPhazonVeins.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(cinfPhazonVeins); - ent->name = name + "_rig"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters1.nameIDs(pakRouter, name + "_actp1"); - actorParameters2.nameIDs(pakRouter, name + "_actp2"); - animationParameters.nameANCS(pakRouter, name + "_animp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - g_curSpec->flattenDependencies(particle5, pathsOut); - g_curSpec->flattenDependencies(particle6, pathsOut); - g_curSpec->flattenDependencies(particle7, pathsOut); - g_curSpec->flattenDependencies(elsc, pathsOut); - g_curSpec->flattenDependencies(model1, pathsOut); - g_curSpec->flattenDependencies(cmdlPhazonVeins, pathsOut); - g_curSpec->flattenDependencies(cskrPhazonVeins, pathsOut); - g_curSpec->flattenDependencies(cinfPhazonVeins, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters1.depIDs(pathsOut, lazyOut); - actorParameters2.depIDs(pathsOut, lazyOut); - animationParameters.depANCS(pathsOut); - } - - void gatherScans(std::vector& scansOut) const override { - actorParameters1.scanIDs(scansOut); - actorParameters2.scanIDs(scansOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Parameters.cpp b/DataSpec/DNAMP1/ScriptObjects/Parameters.cpp deleted file mode 100644 index 8fbb0a3d7..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Parameters.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "Parameters.hpp" -#include "../ANCS.hpp" - -namespace DataSpec::DNAMP1 { - -UniqueID32 AnimationParameters::getCINF(PAKRouter& pakRouter) const { - if (!animationCharacterSet.isValid()) - return UniqueID32(); - const nod::Node* node; - const PAK::Entry* ancsEnt = pakRouter.lookupEntry(animationCharacterSet, &node); - ANCS ancs; - { - PAKEntryReadStream rs = ancsEnt->beginReadStream(*node); - ancs.read(rs); - } - return ancs.characterSet.characters.at(character).cinf; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp b/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp deleted file mode 100644 index 15a7abecb..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp +++ /dev/null @@ -1,471 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "../DNAMP1.hpp" -#include "../SAVW.hpp" - -namespace DataSpec::DNAMP1 { - -enum class EPickupType : atUint32 { - PowerBeam = 0, - IceBeam = 1, - WaveBeam = 2, - PlasmaBeam = 3, - Missile = 4, - ScanVisor = 5, - MorphBallBomb = 6, - PowerBomb = 7, - Flamethrower = 8, - ThermalVisor = 9, - ChargeBeam = 10, - SuperMissile = 11, - GrappleBeam = 12, - XRayVisor = 13, - IceSpreader = 14, - SpaceJump = 15, - MorphBall = 16, - CombatVisor = 17, - BoostBall = 18, - SpiderBall = 19, - PowerSuit = 20, - GravitySuit = 21, - VariaSuit = 22, - PhazonSuit = 23, - EnergyTank = 24, - UnknownItem1 = 25, - HealthRefill = 26, - UnknownItem2 = 27, - WaveBuster = 28, - Truth = 29, - Strength = 30, - Elder = 31, - Wild = 32, - LifeGiver = 33, - Warrior = 34, - Chozo = 35, - Nature = 36, - Sun = 37, - World = 38, - Spirit = 39, - Newborn = 40 -}; - -enum class ESpecialFunctionType : atUint32 { - What, - PlayerFollowLocator, - SpinnerController, - ObjectFollowLocator, - ChaffTarget, - InventoryActivator, - MapStation, - SaveStation, - IntroBossRingController, - ViewFrustumTest, - ShotSpinnerController, - EscapeSequence, - BossEnergyBar, - EndGame, - HUDFadeIn, - CinematicSkip, - ScriptLayerController, - RainSimulator, - AreaDamage, - ObjectFollowObject, - HintSystem, - DropBomb, - ScaleActor, - MissileStation, - Billboard, - PlayerInAreaRelay, - HUDTarget, - FogFader, - EnterLogbook, - PowerBombStation, - Ending, - FusionRelay, - WeaponSwitch // PAL Only -}; - -struct AnimationParameters : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 animationCharacterSet; - Value character; - Value defaultAnimation; - - UniqueID32 getCINF(PAKRouter& pakRouter) const; - - void nameANCS(PAKRouter& pakRouter, const std::string& name) const { - if (!animationCharacterSet.isValid()) - return; - PAK::Entry* ancsEnt = (PAK::Entry*)pakRouter.lookupEntry(animationCharacterSet); - if (ancsEnt->name.empty()) - ancsEnt->name = name; - } - - void depANCS(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(animationCharacterSet, pathsOut, character); - } - - void depANCSAll(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(animationCharacterSet, pathsOut); - } -}; - -struct BehaveChance : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; -}; - -struct DamageInfo : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value weaponType; - Value damage; - Value radius; - Value knockbackPower; -}; - -struct DamageVulnerability : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value power; - Value ice; - Value wave; - Value plasma; - Value bomb; - Value powerBomb; - Value missile; - Value boostBall; - Value phazon; - Value enemyWeapon1; - Value enemyWeapon2Poison; - Value enemyWeapon3Lava; - Value enemyWeapon4; - Value unkownWeapon1; - Value unkownWeapon2; - Value deflected; - struct ChargedBeams : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value power; - Value ice; - Value wave; - Value plasma; - Value deflected; - } chargedBeams; - - struct BeamCombos : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value superMissiles; - Value iceSpreader; - Value wavebuster; - Value flameThrower; - Value deflected; - } beamCombos; -}; - -struct FlareDefinition : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - UniqueID32 texture; - Value unknown1; - Value unknown2; - Value unknown4; // CColor - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_texture"; - } - } - - void depIDs(std::vector& pathsOut) const { g_curSpec->flattenDependencies(texture, pathsOut); } -}; - -struct GrappleParameters : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value disableTurning; -}; - -struct HealthInfo : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value health; - Value knockbackResistance; -}; - -struct LightParameters : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value castShadow; - Value shadowScale; - Value shadowTesselation; - Value shadowAlpha; - Value maxShadowHeight; - Value ambientColor; // CColor - Value makeLights; - Value worldLightingOptions; - Value lightRecalculation; - Value lightingPositionOffset; - Value numDynamicLights; - Value numAreaLights; - Value ambientChannelOverflow; - Value layerIndex; -}; - -struct PatternedInfo : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value mass; - Value speed; - Value turnSpeed; - Value detectionRange; - Value detectionHeightRange; - Value dectectionAngle; - Value minAttackRange; - Value maxAttackRange; - Value averageAttackTime; - Value attackTimeVariation; - Value leashRadius; - Value playerLeashRadius; - Value playerLeashTime; - DamageInfo contactDamage; - Value damageWaitTime; - HealthInfo healthInfo; - DamageVulnerability damageVulnerability; - Value halfExtent; - Value height; - Value bodyOrigin; - Value stepUpHeight; - Value xDamage; - Value frozenXDamage; - Value xDamageDelay; - Value deathSfx; - AnimationParameters animationParameters; - Value active; - UniqueID32 stateMachine; - Value intoFreezeDur; - Value outOfFreezeDur; - Value unknown10; - Value pathfindingIndex; - Value particle1Scale; - UniqueID32 particle1; - UniqueID32 electric; - Value particle2Scale; - UniqueID32 particle2; - Value iceShatterSfx; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - animationParameters.nameANCS(pakRouter, name + "_animp"); - if (stateMachine.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(stateMachine); - ent->name = name + "_fsm"; - } - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (electric.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(electric); - ent->name = name + "_elsc"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - } - - void depIDs(std::vector& pathsOut) const { - animationParameters.depANCS(pathsOut); - g_curSpec->flattenDependencies(stateMachine, pathsOut); - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(electric, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - } -}; - -struct PlayerHintParameters : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value unknown1; - Value unknown2; - Value extendTargetDistance; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; -}; - -struct ScannableParameters : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - UniqueID32 scanId; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - if (scanId.isValid()) { - PAK::Entry* scanEnt = (PAK::Entry*)pakRouter.lookupEntry(scanId); - scanEnt->name = name + "_scan"; - } - } - - void depIDs(std::vector& pathsOut) const { g_curSpec->flattenDependencies(scanId, pathsOut); } - - void scanIDs(std::vector& scansOut) const { scansOut.emplace_back(scanId); } -}; - -struct VisorParameters : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value unknown1; - Value scanPassthrough; - Value visorMask; -}; - -struct PropertyFlags : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Vector bools; -}; - -struct ActorParameters : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - LightParameters lightParameters; - ScannableParameters scannableParameters; - UniqueID32 cmdlXray; - UniqueID32 cskrXray; - UniqueID32 cmdlThermal; - UniqueID32 cskrThermal; - Value globalTimeProvider; - Value fadeInTime; - Value fadeOutTime; - VisorParameters visorParameters; - Value thermalHeat; - Value renderUnsorted; - Value noSortThermal; - Value thermalMag; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc, - const AnimationParameters& animParms) const { - auto cinf = animParms.getCINF(pakRouter); - if (cmdlXray.isValid() && cskrXray.isValid()) { - charAssoc.m_cmdlRigs[cmdlXray] = {cskrXray, cinf}; - charAssoc.m_cskrToCharacter[cskrXray] = - std::make_pair(animParms.animationCharacterSet, fmt::format(FMT_STRING("ATTACH.XRAY_{}.CSKR"), cskrXray)); - charAssoc.addAttachmentRig(animParms.animationCharacterSet, {}, cmdlXray, "XRAY"); - } - if (cmdlThermal.isValid() && cskrThermal.isValid()) { - charAssoc.m_cmdlRigs[cmdlThermal] = {cskrThermal, cinf}; - charAssoc.m_cskrToCharacter[cskrThermal] = std::make_pair( - animParms.animationCharacterSet, fmt::format(FMT_STRING("ATTACH.THERMAL_{}.CSKR"), cskrThermal)); - charAssoc.addAttachmentRig(animParms.animationCharacterSet, {}, cmdlThermal, "THERMAL"); - } - } - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - scannableParameters.nameIDs(pakRouter, name); - if (cmdlXray.isValid()) { - PAK::Entry* xmEnt = (PAK::Entry*)pakRouter.lookupEntry(cmdlXray); - xmEnt->name = name + "_xraymodel"; - } - if (cskrXray.isValid()) { - PAK::Entry* xsEnt = (PAK::Entry*)pakRouter.lookupEntry(cskrXray); - xsEnt->name = name + "_xrayskin"; - } - if (cmdlThermal.isValid()) { - PAK::Entry* xmEnt = (PAK::Entry*)pakRouter.lookupEntry(cmdlThermal); - xmEnt->name = name + "_thermalmodel"; - } - if (cskrThermal.isValid()) { - PAK::Entry* xsEnt = (PAK::Entry*)pakRouter.lookupEntry(cskrThermal); - xsEnt->name = name + "_thermalskin"; - } - } - - void depIDs(std::vector& pathsOut, std::vector& lazyOut) const { - scannableParameters.depIDs(lazyOut); - g_curSpec->flattenDependencies(cmdlXray, pathsOut); - g_curSpec->flattenDependencies(cskrXray, pathsOut); - g_curSpec->flattenDependencies(cmdlThermal, pathsOut); - g_curSpec->flattenDependencies(cskrThermal, pathsOut); - } - - void scanIDs(std::vector& scansOut) const { scannableParameters.scanIDs(scansOut); } -}; - -struct BeamInfo : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value beamAttributes; - UniqueID32 contactFxId; - UniqueID32 pulseFxId; - UniqueID32 textureId; - UniqueID32 glowTextureId; - Value length; - Value radius; - Value expansionSpeed; - Value lifeTime; - Value pulseSpeed; - Value shutdownTime; - Value contactFxScale; - Value pulseFxScale; - Value travelSpeed; - DNAColor innerColor; - DNAColor outerColor; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - if (contactFxId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(contactFxId); - ent->name = name + "_part1"; - } - if (pulseFxId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(pulseFxId); - ent->name = name + "_part2"; - } - if (textureId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(textureId); - ent->name = name + "_tex1"; - } - if (glowTextureId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(glowTextureId); - ent->name = name + "_tex2"; - } - } - - void depIDs(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(contactFxId, pathsOut); - g_curSpec->flattenDependencies(pulseFxId, pathsOut); - g_curSpec->flattenDependencies(textureId, pathsOut); - g_curSpec->flattenDependencies(glowTextureId, pathsOut); - } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Parasite.hpp b/DataSpec/DNAMP1/ScriptObjects/Parasite.hpp deleted file mode 100644 index e748bd5af..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Parasite.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Parasite : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value flavor; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value maxTelegraphReactDist; - Value advanceWpRadius; - Value unknown4; - Value alignAngVel; - Value unknown6; - Value stuckTimeThreshold; - Value collisionCloseMargin; - Value parasiteSearchRadius; - Value parasiteSeparationDist; - Value parasiteSeparationWeight; - Value parasiteAlignmentWeight; - Value parasiteCohesionWeight; - Value destinationSeekWeight; - Value forwardMoveWeight; - Value playerSeparationDist; - Value playerSeparationWeight; - Value playerObstructionMinDist; - Value disableMove; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PathCamera.hpp b/DataSpec/DNAMP1/ScriptObjects/PathCamera.hpp deleted file mode 100644 index e63b82501..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PathCamera.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PathCamera : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - struct CameraParameters : BigDNA { - AT_DECL_DNA - Value propertyCount; - Value closedLoop; - Value noFilter; - Value tangentOrientation; - Value easeDist; - Value useHintLookZ; - Value clampToClosedDoor; - } cameraParameters; - - Value lengthExtent; - Value filterMag; - Value filterProportion; - Value initPos; - Value minEaseDist; - Value maxEaseDist; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PhazonHealingNodule.hpp b/DataSpec/DNAMP1/ScriptObjects/PhazonHealingNodule.hpp deleted file mode 100644 index 4106f2525..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PhazonHealingNodule.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PhazonHealingNodule : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - UniqueID32 elsc; - String<-1> unknown2; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(elsc, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PhazonPool.hpp b/DataSpec/DNAMP1/ScriptObjects/PhazonPool.hpp deleted file mode 100644 index 608be50e2..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PhazonPool.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PhazonPool : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value unknown1; - UniqueID32 model1; - UniqueID32 model2; - UniqueID32 particle1; - UniqueID32 particle2; - Value unknown2; - DamageInfo damageInfo; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (model1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model1); - ent->name = name + "_model1"; - } - if (model2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model2); - ent->name = name + "_model2"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(model1, pathsOut); - g_curSpec->flattenDependencies(model2, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Pickup.hpp b/DataSpec/DNAMP1/ScriptObjects/Pickup.hpp deleted file mode 100644 index fe70a5049..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Pickup.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { - -struct Pickup : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value hitboxVolume; - Value scanPosition; - Value pickupType; - Value capacity; - Value amount; - Value possibility; - Value lifeTime; - Value fadeInTime; - UniqueID32 model; - AnimationParameters animationParameters; - ActorParameters actorParameters; - Value active; - Value startDelay; - UniqueID32 pickupParticle; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (pickupParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(pickupParticle); - ent->name = name + "_part"; - } - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(pickupParticle, pathsOut); - g_curSpec->flattenDependencies(model, pathsOut); - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PickupGenerator.hpp b/DataSpec/DNAMP1/ScriptObjects/PickupGenerator.hpp deleted file mode 100644 index baf4aa9a0..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PickupGenerator.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PickupGenerator : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value offset; - Value active; - Value frequency; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Platform.cpp b/DataSpec/DNAMP1/ScriptObjects/Platform.cpp deleted file mode 100644 index a468a110b..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Platform.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "Platform.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -zeus::CAABox Platform::getVISIAABB(hecl::blender::Token& btok) const { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - zeus::CAABox aabbOut; - - if (model.isValid()) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(model); - conn.openBlend(path); - hecl::blender::DataStream ds = conn.beginData(); - auto aabb = ds.getMeshAABB(); - aabbOut = zeus::CAABox(aabb.first, aabb.second); - } else if (animationParameters.animationCharacterSet.isValid()) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(animationParameters.animationCharacterSet); - conn.openBlend(path.getWithExtension(".blend", true)); - hecl::blender::DataStream ds = conn.beginData(); - auto aabb = ds.getMeshAABB(); - aabbOut = zeus::CAABox(aabb.first, aabb.second); - } - - if (aabbOut.min.x() > aabbOut.max.x()) - return {}; - - zeus::CTransform xf = ConvertEditorEulerToTransform4f(scale, orientation, location); - return aabbOut.getTransformedAABox(xf); -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Platform.hpp b/DataSpec/DNAMP1/ScriptObjects/Platform.hpp deleted file mode 100644 index ddb88e5f2..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Platform.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Platform : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value extent; - Value collisionCenter; - UniqueID32 model; - AnimationParameters animationParameters; - ActorParameters actorParameters; - Value speed; - Value active; - UniqueID32 dcln; - HealthInfo healthInfo; - DamageVulnerability damageVulnerabilty; - Value detectCollision; - Value xrayAlpha; - Value rainSplashes; - Value maxRainSplashes; - Value rainGenRate; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (dcln.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(dcln); - ent->name = name + "_dcln"; - } - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(dcln, pathsOut); - g_curSpec->flattenDependencies(model, pathsOut); - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } - - zeus::CAABox getVISIAABB(hecl::blender::Token& btok) const override; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PlayerActor.hpp b/DataSpec/DNAMP1/ScriptObjects/PlayerActor.hpp deleted file mode 100644 index 46081d82b..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PlayerActor.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PlayerActor : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value boxExtents; - Value boxOffset; - Value mass; - Value zMomentum; - HealthInfo healthInfo; - DamageVulnerability damageVulnerability; - UniqueID32 model; - AnimationParameters animationParameters; - ActorParameters actorParameters; - Value loop; - Value snow; - Value solid; - Value active; - PropertyFlags playerParameters; - Value beamId; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(model, pathsOut); - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - animationParameters.depANCSAll(lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PlayerHint.hpp b/DataSpec/DNAMP1/ScriptObjects/PlayerHint.hpp deleted file mode 100644 index bb6ff2fb2..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PlayerHint.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PlayerHint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - PlayerHintParameters playerHintParameters; - Value priority; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PlayerStateChange.hpp b/DataSpec/DNAMP1/ScriptObjects/PlayerStateChange.hpp deleted file mode 100644 index ea3ebf4de..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PlayerStateChange.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PlayerStateChange : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value item; - Value itemCount; - Value itemCapacity; - Value control; - Value controlCommandOption; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PointOfInterest.hpp b/DataSpec/DNAMP1/ScriptObjects/PointOfInterest.hpp deleted file mode 100644 index 59ab42b40..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PointOfInterest.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PointOfInterest : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - ScannableParameters scannableParameters; - Value pointSize; - - void nameIDs(PAKRouter& pakRouter) const override { - scannableParameters.nameIDs(pakRouter, name + "_scanp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - scannableParameters.depIDs(lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { scannableParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PuddleSpore.hpp b/DataSpec/DNAMP1/ScriptObjects/PuddleSpore.hpp deleted file mode 100644 index fb5dc119e..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PuddleSpore.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PuddleSpore : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value unknown1; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown2; - UniqueID32 particle; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - UniqueID32 wpsc; - DamageInfo damageInfo; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - if (wpsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); - ent->name = name + "_wpsc"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle, pathsOut); - g_curSpec->flattenDependencies(wpsc, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PuddleToadGamma.hpp b/DataSpec/DNAMP1/ScriptObjects/PuddleToadGamma.hpp deleted file mode 100644 index ba5a71b6a..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PuddleToadGamma.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PuddleToadGamma : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value flavor; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value suckForceMultiplier; - Value suckAngle; - Value playerSuckRange; - Value localShootDir; - Value playerShootSpeed; - Value shouldAttackWaitTime; - Value spotPlayerWaitTime; - DamageInfo playerShootDamage; - DamageInfo damageInfo2; - UniqueID32 dcln; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (dcln.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(dcln); - ent->name = name + "_dcln"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(dcln, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Puffer.hpp b/DataSpec/DNAMP1/ScriptObjects/Puffer.hpp deleted file mode 100644 index 0865c51a1..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Puffer.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Puffer : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - UniqueID32 particle; - DamageInfo damageInfo1; - UniqueID32 texture; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - DamageInfo damageInfo2; - Value unknown6; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_texture"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle, pathsOut); - g_curSpec->flattenDependencies(texture, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/RadialDamage.hpp b/DataSpec/DNAMP1/ScriptObjects/RadialDamage.hpp deleted file mode 100644 index 942d2a0b6..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/RadialDamage.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct RadialDamage : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value active; - DamageInfo damageInfo; - Value radius; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/RandomRelay.hpp b/DataSpec/DNAMP1/ScriptObjects/RandomRelay.hpp deleted file mode 100644 index 6ad61808d..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/RandomRelay.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct RandomRelay : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value sendSetSize; - Value sendSetVariance; - Value percentSize; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Relay.hpp b/DataSpec/DNAMP1/ScriptObjects/Relay.hpp deleted file mode 100644 index 6a29f6c9a..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Relay.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Relay : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Repulsor.hpp b/DataSpec/DNAMP1/ScriptObjects/Repulsor.hpp deleted file mode 100644 index 4b7d4befa..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Repulsor.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Repulsor : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value active; - Value radius; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Ridley.cpp b/DataSpec/DNAMP1/ScriptObjects/Ridley.cpp deleted file mode 100644 index 1fff77f17..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Ridley.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "Ridley.hpp" - -namespace DataSpec::DNAMP1 { - -template -void Ridley::Enumerate(typename Op::StreamT& s) { - IScriptObject::Enumerate(s); - Do(athena::io::PropId{"name"}, name, s); - Do(athena::io::PropId{"location"}, location, s); - Do(athena::io::PropId{"orientation"}, orientation, s); - Do(athena::io::PropId{"scale"}, scale, s); - Do(athena::io::PropId{"patternedInfo"}, patternedInfo, s); - Do(athena::io::PropId{"actorParameters"}, actorParameters, s); - Do(athena::io::PropId{"model1"}, model1, s); - Do(athena::io::PropId{"model2"}, model2, s); - if (propertyCount == 48) { - Do(athena::io::PropId{"model3"}, model3, s); - Do(athena::io::PropId{"model4"}, model4, s); - Do(athena::io::PropId{"model5"}, model5, s); - Do(athena::io::PropId{"model6"}, model6, s); - Do(athena::io::PropId{"model7"}, model7, s); - Do(athena::io::PropId{"model8"}, model8, s); - Do(athena::io::PropId{"model9"}, model9, s); - Do(athena::io::PropId{"model10"}, model10, s); - Do(athena::io::PropId{"model11"}, model11, s); - Do(athena::io::PropId{"model12"}, model12, s); - } - Do(athena::io::PropId{"particle"}, particle, s); - Do(athena::io::PropId{"unknown1"}, unknown1, s); - Do(athena::io::PropId{"unknown2"}, unknown2, s); - Do(athena::io::PropId{"unknown3"}, unknown3, s); - Do(athena::io::PropId{"unknown4"}, unknown4, s); - Do(athena::io::PropId{"wpsc1"}, wpsc1, s); - Do(athena::io::PropId{"damageInfo1"}, damageInfo1, s); - Do(athena::io::PropId{"ridleyStruct1"}, ridleyStruct1, s); - Do(athena::io::PropId{"soundID1"}, soundID1, s); - Do(athena::io::PropId{"wpsc2"}, wpsc2, s); - if (propertyCount == 40) - Do(athena::io::PropId{"wpsc3"}, wpsc3, s); - Do(athena::io::PropId{"damageInfo2"}, damageInfo2, s); - Do(athena::io::PropId{"ridleyStruct2_1"}, ridleyStruct2_1, s); - Do(athena::io::PropId{"wpsc4"}, wpsc4, s); - Do(athena::io::PropId{"damageInfo3"}, damageInfo3, s); - Do(athena::io::PropId{"ridleyStruct2_2"}, ridleyStruct2_2, s); - Do(athena::io::PropId{"soundID2"}, soundID2, s); - Do(athena::io::PropId{"damageInfo4"}, damageInfo4, s); - Do(athena::io::PropId{"ridleyStruct2_3"}, ridleyStruct2_3, s); - Do(athena::io::PropId{"unknown5"}, unknown5, s); - Do(athena::io::PropId{"unknown6"}, unknown6, s); - Do(athena::io::PropId{"damageInfo5"}, damageInfo5, s); - Do(athena::io::PropId{"unknown7"}, unknown7, s); - Do(athena::io::PropId{"damageInfo6"}, damageInfo6, s); - Do(athena::io::PropId{"unknown8"}, unknown8, s); - Do(athena::io::PropId{"damageInfo7"}, damageInfo7, s); - Do(athena::io::PropId{"unknown9"}, unknown9, s); - Do(athena::io::PropId{"elsc"}, elsc, s); - Do(athena::io::PropId{"unknown10"}, unknown10, s); - Do(athena::io::PropId{"soundID3"}, soundID3, s); - Do(athena::io::PropId{"damageInfo8"}, damageInfo8, s); - if (propertyCount == 40) - Do(athena::io::PropId{"damageInfo9"}, damageInfo9, s); -} - -std::string_view Ridley::DNAType() { return "DNAMP1::Ridley"sv; } - -AT_SPECIALIZE_DNA_YAML(Ridley) - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Ridley.hpp b/DataSpec/DNAMP1/ScriptObjects/Ridley.hpp deleted file mode 100644 index 5bf6ad001..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Ridley.hpp +++ /dev/null @@ -1,231 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Ridley : IScriptObject { - AT_DECL_EXPLICIT_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - UniqueID32 model1; - UniqueID32 model2; - UniqueID32 model3; - UniqueID32 model4; - UniqueID32 model5; - UniqueID32 model6; - UniqueID32 model7; - UniqueID32 model8; - UniqueID32 model9; - UniqueID32 model10; - UniqueID32 model11; - UniqueID32 model12; - UniqueID32 particle; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - UniqueID32 wpsc1; - DamageInfo damageInfo1; - struct RidleyStruct1 : BigDNA { - AT_DECL_DNA_YAML - Value unknown1; - Value unknown2; - UniqueID32 particle1; - UniqueID32 particle2; - UniqueID32 texture1; - UniqueID32 texture2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; // CColor - Value unknown13; // CColor - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (texture1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture1); - ent->name = name + "_tex1"; - } - if (texture2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture2); - ent->name = name + "_tex2"; - } - } - - void depIDs(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(texture1, pathsOut); - g_curSpec->flattenDependencies(texture2, pathsOut); - } - } ridleyStruct1; - - Value soundID1; - UniqueID32 wpsc2; - UniqueID32 wpsc3; - DamageInfo damageInfo2; - - struct RidleyStruct2 : BigDNA { - AT_DECL_DNA_YAML - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - } ridleyStruct2_1; - - UniqueID32 wpsc4; - DamageInfo damageInfo3; - RidleyStruct2 ridleyStruct2_2; - Value soundID2; - DamageInfo damageInfo4; - RidleyStruct2 ridleyStruct2_3; - Value unknown5; - Value unknown6; - DamageInfo damageInfo5; - Value unknown7; - DamageInfo damageInfo6; - Value unknown8; - DamageInfo damageInfo7; - Value unknown9; - UniqueID32 elsc; - Value unknown10; - Value soundID3; - DamageInfo damageInfo8; - - /* Trilogy addition */ - DamageInfo damageInfo9; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - if (model1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model1); - ent->name = name + "_model1"; - } - if (model2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model2); - ent->name = name + "_model2"; - } - if (model3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model3); - ent->name = name + "_model3"; - } - if (model4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model4); - ent->name = name + "_model4"; - } - if (model5.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model5); - ent->name = name + "_model5"; - } - if (model6.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model6); - ent->name = name + "_model6"; - } - if (model7.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model7); - ent->name = name + "_model7"; - } - if (model8.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model8); - ent->name = name + "_model8"; - } - if (model9.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model9); - ent->name = name + "_model9"; - } - if (model10.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model10); - ent->name = name + "_model10"; - } - if (model11.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model11); - ent->name = name + "_model11"; - } - if (model12.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model12); - ent->name = name + "_model12"; - } - if (wpsc1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); - ent->name = name + "_wpsc1"; - } - if (wpsc2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); - ent->name = name + "_wpsc2"; - } - if (wpsc3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc3); - ent->name = name + "_wpsc3"; - } - if (wpsc4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc4); - ent->name = name + "_wpsc4"; - } - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - ridleyStruct1.nameIDs(pakRouter, name + "_ridley1"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle, pathsOut); - g_curSpec->flattenDependencies(model1, pathsOut); - g_curSpec->flattenDependencies(model2, pathsOut); - g_curSpec->flattenDependencies(model3, pathsOut); - g_curSpec->flattenDependencies(model4, pathsOut); - g_curSpec->flattenDependencies(model5, pathsOut); - g_curSpec->flattenDependencies(model6, pathsOut); - g_curSpec->flattenDependencies(model7, pathsOut); - g_curSpec->flattenDependencies(model8, pathsOut); - g_curSpec->flattenDependencies(model9, pathsOut); - g_curSpec->flattenDependencies(model10, pathsOut); - g_curSpec->flattenDependencies(model11, pathsOut); - g_curSpec->flattenDependencies(model12, pathsOut); - g_curSpec->flattenDependencies(wpsc1, pathsOut); - g_curSpec->flattenDependencies(wpsc2, pathsOut); - g_curSpec->flattenDependencies(wpsc3, pathsOut); - g_curSpec->flattenDependencies(wpsc4, pathsOut); - g_curSpec->flattenDependencies(elsc, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - ridleyStruct1.depIDs(pathsOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Ripper.hpp b/DataSpec/DNAMP1/ScriptObjects/Ripper.hpp deleted file mode 100644 index 4dd779ddf..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Ripper.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Ripper : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value unknown1; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - GrappleParameters grappleParameters; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Ripple.hpp b/DataSpec/DNAMP1/ScriptObjects/Ripple.hpp deleted file mode 100644 index ea3b3378b..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Ripple.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Ripple : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value active; - Value mag; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/RoomAcoustics.hpp b/DataSpec/DNAMP1/ScriptObjects/RoomAcoustics.hpp deleted file mode 100644 index 1c4bfe6e8..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/RoomAcoustics.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct RoomAcoustics : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value volumeScale; - Value reverbHiEnable; - Value reverbHiTmpDisable; - Value reverbHiColoration; - Value reverbHiMix; - Value reverbHiTime; - Value reverbHiDamping; - Value reverbHiPreDelay; - Value reverbHiCrosstalk; - Value chorusEnable; - Value baseDelay; - Value variation; - Value period; - Value reverbStdEnable; - Value reverbStdTmpDisable; - Value reverbStdColoration; - Value reverbStdMix; - Value reverbStdTime; - Value reverbStdDamping; - Value reverbStdPreDelay; - Value delayEnable; - Value delay[3]; - Value feedback[3]; - Value output[3]; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/RumbleEffect.hpp b/DataSpec/DNAMP1/ScriptObjects/RumbleEffect.hpp deleted file mode 100644 index 3dd327406..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/RumbleEffect.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct RumbleEffect : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value unknown1; - Value unknown2; - Value unknown3; - struct RumbleEffectParameters : BigDNA { - AT_DECL_DNA - Value propertyCount; - Value unknown1; - Value unknown2; - } rumbleParameters; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ScriptBeam.hpp b/DataSpec/DNAMP1/ScriptObjects/ScriptBeam.hpp deleted file mode 100644 index bf2230180..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ScriptBeam.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ScriptBeam : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - UniqueID32 wpsc; - BeamInfo beamInfo; - DamageInfo damageInfo; - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); - ent->name = name + "_wpsc"; - } - beamInfo.nameIDs(pakRouter, name + "_beamInfo"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc, pathsOut); - beamInfo.depIDs(pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ScriptTypes.hpp b/DataSpec/DNAMP1/ScriptObjects/ScriptTypes.hpp deleted file mode 100644 index b0febb999..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ScriptTypes.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -#include - -namespace DataSpec::DNAMP1 { -struct IScriptObject; - -struct ScriptObjectSpec { - atUint8 type; - IScriptObject* (*loader)(); -}; - -using ScriptObjectDBArray = std::array; - -extern const ScriptObjectDBArray SCRIPT_OBJECT_DB; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Seedling.hpp b/DataSpec/DNAMP1/ScriptObjects/Seedling.hpp deleted file mode 100644 index 71250eb37..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Seedling.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Seedling : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - UniqueID32 unknown1; - UniqueID32 unknown2; - DamageInfo damageInfo1; - DamageInfo damageInfo2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (unknown1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(unknown1); - ent->name = name + "_unk1"; - } - if (unknown2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(unknown2); - ent->name = name + "_unk2"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(unknown1, pathsOut); - g_curSpec->flattenDependencies(unknown2, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ShadowProjector.hpp b/DataSpec/DNAMP1/ScriptObjects/ShadowProjector.hpp deleted file mode 100644 index f3073eb99..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ShadowProjector.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ShadowProjector : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SnakeWeedSwarm.hpp b/DataSpec/DNAMP1/ScriptObjects/SnakeWeedSwarm.hpp deleted file mode 100644 index 948d6e116..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SnakeWeedSwarm.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct SnakeWeedSwarm : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value volume; - Value unknown1; - AnimationParameters animationParameters; - ActorParameters actorParameters; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - DamageInfo damageInfo; - Value unknown16; - Value unknown17; - Value unknown18; - Value unknown19; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Sound.hpp b/DataSpec/DNAMP1/ScriptObjects/Sound.hpp deleted file mode 100644 index b7d029c13..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Sound.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Sound : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value soundID; - Value active; - Value maxDist; - Value distComp; - Value startDelay; - Value minVol; - Value vol; - Value prio; - Value pan; - Value loop; - Value nonEmitter; - Value autoStart; - Value occlusionTest; - Value acoustics; - Value worldSfx; - Value allowDuplicates; - Value pitch; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SpacePirate.hpp b/DataSpec/DNAMP1/ScriptObjects/SpacePirate.hpp deleted file mode 100644 index d1553ecb7..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SpacePirate.hpp +++ /dev/null @@ -1,93 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct SpacePirate : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value AggressionCheck; - Value CoverCheck; - Value SearchRadius; - Value FallBackCheck; - Value FallBackRadius; - Value HearingRadius; - /* - * 0x1: pendingAmbush - * 0x2: ceilingAmbush - * 0x4: nonAggressive - * 0x8: melee - * 0x10: noShuffleCloseCheck - * 0x20: onlyAttackInRange - * 0x40: unk - * 0x80: noKnockbackImpulseReset - * 0x200: noMeleeAttack - * 0x400: breakAttack - * 0x1000: seated - * 0x2000: shadowPirate - * 0x4000: alertBeforeCloak - * 0x8000: noBreakDodge - * 0x10000: floatingCorpse - * 0x20000: ragdollNoAiCollision - * 0x40000: trooper - */ - Value flags; - Value unknown8; - UniqueID32 Projectile; - DamageInfo ProjectileDamage; - Value Sound_Projectile; - DamageInfo BladeDamage; - Value KneelAttackChance; - UniqueID32 KneelAttackShot; - DamageInfo KneelAttackDamage; - Value DodgeCheck; - Value Sound_Impact; - Value averageNextShotTime; - Value nextShotTimeVariation; - Value Sound_Alert; - Value GunTrackDelay; - Value firstBurstCount; - Value CloakOpacity; - Value MaxCloakOpacity; - Value dodgeDelayTimeMin; - Value dodgeDelayTimeMax; - Value Sound_Hurled; - Value Sound_Death; - Value unknown19; - Value AvoidDistance; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (Projectile.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(Projectile); - ent->name = name + "_Projectile"; - } - if (KneelAttackShot.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(KneelAttackShot); - ent->name = name + "_KneelAttackShot"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(Projectile, pathsOut); - g_curSpec->flattenDependencies(KneelAttackShot, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SpankWeed.hpp b/DataSpec/DNAMP1/ScriptObjects/SpankWeed.hpp deleted file mode 100644 index eba767cd3..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SpankWeed.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct SpankWeed : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unused; - Value maxDetectionRange; - Value maxHearingrange; - Value maxSightRange; - Value hideTime; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SpawnPoint.hpp b/DataSpec/DNAMP1/ScriptObjects/SpawnPoint.hpp deleted file mode 100644 index 25a955e82..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SpawnPoint.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct SpawnPoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value powerBeam; - Value iceBeam; - Value waveBeam; - Value plasmaBeam; - Value missiles; - Value scanVisor; - Value morphBallBombs; - Value powerBombs; - Value flameThrower; - Value thermalVisor; - Value chargeBeam; - Value superMissile; - Value grappleBeam; - Value xrayVisor; - Value iceSpreader; - Value spaceJump; - Value morphBall; - Value combatVisor; - Value boostBall; - Value spiderBall; - Value powerSuit; - Value gravitySuit; - Value variaSuit; - Value phazonSuit; - Value energyTanks; - Value unknownItem1; - Value healthRefill; - Value unknownItem2; - Value waveBuster; - Value defaultSpawn; - Value active; - Value morphed; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SpecialFunction.hpp b/DataSpec/DNAMP1/ScriptObjects/SpecialFunction.hpp deleted file mode 100644 index e9dabe3b3..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SpecialFunction.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct SpecialFunction : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value function; - String<-1> unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - struct LayerSwitch : BigDNA { - AT_DECL_DNA - Value area; - Value layerIdx; - } layerSwitch; - Value pickup; - Value unknown5; - Value unknown6; - Value unknown7; // Used by SpinnerController 1 - Value unknown8; // Used by SpinnerController 2 - Value unknown9; // Used by SpinnerController 3 -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SpiderBallAttractionSurface.hpp b/DataSpec/DNAMP1/ScriptObjects/SpiderBallAttractionSurface.hpp deleted file mode 100644 index 1b5205fb6..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SpiderBallAttractionSurface.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct SpiderBallAttractionSurface : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SpiderBallWaypoint.hpp b/DataSpec/DNAMP1/ScriptObjects/SpiderBallWaypoint.hpp deleted file mode 100644 index 62c2bf7b2..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SpiderBallWaypoint.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct SpiderBallWaypoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value unknown2; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SpindleCamera.hpp b/DataSpec/DNAMP1/ScriptObjects/SpindleCamera.hpp deleted file mode 100644 index 7ea264dcf..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SpindleCamera.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { - -struct SpindleCamera : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - /* - * 0x1: Look toward hint - * 0x2: Flat look delta - * 0x8: force minimum-clamp ball-to-cam azimuth - * 0x10: minimum-clamp ball-to-cam azimuth - * 0x20: Enable clampedAzimuthFromHintDir - * 0x40: Enable distOffsetFromBallDist - * 0x80: Use ball pos for cam pos Z (vs. hint pos) - * 0x100: Enable deltaAngleScaleWithCamDist - * 0x200: Use ball pos for look pos Z (vs. hint pos) - * 0x400: unused - * 0x800: Variable hint-to-ball direction - * 0x1000: Damp look azimuth with hint ball-to-cam azimuth < 10-degrees - * 0x2000: Enable deleteHintBallDist - * 0x4000: Ignore ball-to-cam azimuth sign - */ - PropertyFlags flags; - Value hintToCamDistMin; - Value hintToCamDistMax; - Value hintToCamVOffMin; - Value hintToCamVOffMax; - struct SpindleCameraParameters : BigDNA { - AT_DECL_DNA_YAML - Value input; - PropertyFlags flags; // high reflect, low reflect - Value lowOut; - Value highOut; - Value lowIn; - Value highIn; - }; - SpindleCameraParameters targetHintToCamDeltaAngleVel; - SpindleCameraParameters deltaAngleScaleWithCamDist; - SpindleCameraParameters hintToCamDist; - SpindleCameraParameters distOffsetFromBallDist; - SpindleCameraParameters hintBallToCamAzimuth; - SpindleCameraParameters unused; - SpindleCameraParameters maxHintBallToCamAzimuth; - SpindleCameraParameters camLookRelAzimuth; - SpindleCameraParameters lookPosZOffset; - SpindleCameraParameters camPosZOffset; - SpindleCameraParameters clampedAzimuthFromHintDir; - SpindleCameraParameters dampingAzimuthSpeed; - SpindleCameraParameters targetHintToCamDeltaAngleVelRange; - SpindleCameraParameters deleteHintBallDist; - SpindleCameraParameters recoverClampedAzimuthFromHintDir; -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Steam.hpp b/DataSpec/DNAMP1/ScriptObjects/Steam.hpp deleted file mode 100644 index bc1ac20f9..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Steam.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Steam : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value volume; - DamageInfo damageInfo; - Value unknown1; - Value unknown2; - Value unknown3; - UniqueID32 texture; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - - void nameIDs(PAKRouter& pakRouter) const override { - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_texture"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(texture, lazyOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/StreamedAudio.hpp b/DataSpec/DNAMP1/ScriptObjects/StreamedAudio.hpp deleted file mode 100644 index 7a099e5ac..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/StreamedAudio.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct StreamedAudio : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - String<-1> fileName; - Value noStopOnDeactivate; - Value fadeInTime; - Value fadeOutTime; - Value volume; - Value oneShot; - Value music; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Switch.hpp b/DataSpec/DNAMP1/ScriptObjects/Switch.hpp deleted file mode 100644 index 64baaa7cc..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Switch.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Switch : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value opened; - Value closeOnOpened; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/TargetingPoint.hpp b/DataSpec/DNAMP1/ScriptObjects/TargetingPoint.hpp deleted file mode 100644 index 596846efd..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/TargetingPoint.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct TargetingPoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/TeamAIMgr.hpp b/DataSpec/DNAMP1/ScriptObjects/TeamAIMgr.hpp deleted file mode 100644 index 4b77f903b..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/TeamAIMgr.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct TeamAIMgr : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value aiCount; - Value meleeCount; - Value projectileCount; - Value unknownCount; - Value maxMeleeAttackerCount; - Value maxProjectileAttackerCount; - Value positionMode; - Value meleeTimeInterval; - Value projectileTimeInterval; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Thardus.hpp b/DataSpec/DNAMP1/ScriptObjects/Thardus.hpp deleted file mode 100644 index 4146bc5ff..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Thardus.hpp +++ /dev/null @@ -1,165 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Thardus : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - UniqueID32 models[14]; - UniqueID32 particles1[3]; - UniqueID32 stateMachine; - UniqueID32 particles2[6]; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - UniqueID32 texture; - Value unknown9; - UniqueID32 particle; - Value unknown10; - Value unknown11; - Value unknown12; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (models[0].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[0]); - ent->name = name + "_model1"; - } - if (models[1].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[1]); - ent->name = name + "_model2"; - } - if (models[2].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[2]); - ent->name = name + "_model3"; - } - if (models[3].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[3]); - ent->name = name + "_model4"; - } - if (models[4].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[4]); - ent->name = name + "_model5"; - } - if (models[5].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[5]); - ent->name = name + "_model6"; - } - if (models[6].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[6]); - ent->name = name + "_model7"; - } - if (models[7].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[7]); - ent->name = name + "_model8"; - } - if (models[8].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[8]); - ent->name = name + "_model9"; - } - if (models[9].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[9]); - ent->name = name + "_model10"; - } - if (models[10].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[10]); - ent->name = name + "_model11"; - } - if (models[11].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[11]); - ent->name = name + "_model12"; - } - if (models[12].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[12]); - ent->name = name + "_model13"; - } - if (models[13].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[13]); - ent->name = name + "_model14"; - } - if (particles1[0].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles1[0]); - ent->name = name + "_part1"; - } - if (particles1[1].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles1[1]); - ent->name = name + "_part2"; - } - if (particles1[2].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles1[2]); - ent->name = name + "_part3"; - } - if (stateMachine.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(stateMachine); - ent->name = name + "_fsm"; - } - if (particles2[0].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles2[0]); - ent->name = name + "_part4"; - } - if (particles2[1].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles2[1]); - ent->name = name + "_part5"; - } - if (particles2[2].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles2[2]); - ent->name = name + "_part6"; - } - if (particles2[3].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles2[3]); - ent->name = name + "_part7"; - } - if (particles2[4].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles2[4]); - ent->name = name + "_part8"; - } - if (particles2[5].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles2[5]); - ent->name = name + "_part9"; - } - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part10"; - } - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_texture"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - for (int i = 0; i < 14; ++i) - g_curSpec->flattenDependencies(models[i], pathsOut); - for (int i = 0; i < 3; ++i) - g_curSpec->flattenDependencies(particles1[i], pathsOut); - g_curSpec->flattenDependencies(stateMachine, pathsOut); - for (int i = 0; i < 6; ++i) - g_curSpec->flattenDependencies(particles2[i], pathsOut); - g_curSpec->flattenDependencies(particle, pathsOut); - g_curSpec->flattenDependencies(texture, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ThardusRockProjectile.hpp b/DataSpec/DNAMP1/ScriptObjects/ThardusRockProjectile.hpp deleted file mode 100644 index 5df16cd50..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ThardusRockProjectile.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ThardusRockProjectile : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - Value unknown3; - UniqueID32 model; - UniqueID32 stateMachine; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - if (stateMachine.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(stateMachine); - ent->name = name + "_fsm"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(model, pathsOut); - g_curSpec->flattenDependencies(stateMachine, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ThermalHeatFader.hpp b/DataSpec/DNAMP1/ScriptObjects/ThermalHeatFader.hpp deleted file mode 100644 index 1048b7127..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ThermalHeatFader.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ThermalHeatFader : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value fadedLevel; - Value initialLevel; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Timer.hpp b/DataSpec/DNAMP1/ScriptObjects/Timer.hpp deleted file mode 100644 index fe9c5f67c..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Timer.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Timer : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value startTime; - Value maxRandomAddition; - Value resetToZero; - Value startImmediately; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Trigger.hpp b/DataSpec/DNAMP1/ScriptObjects/Trigger.hpp deleted file mode 100644 index 15478e3c3..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Trigger.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Trigger : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value volume; - DamageInfo damageInfo; - Value force; - Value flags; - Value active; - Value deactivateOnEntered; - Value deactivateOnExited; - - zeus::CAABox getVISIAABB(hecl::blender::Token& btok) const override { - zeus::CVector3f halfExtent = zeus::CVector3f(volume) / 2.f; - zeus::CVector3f loc(location); - return zeus::CAABox(loc - halfExtent, loc + halfExtent); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Tryclops.hpp b/DataSpec/DNAMP1/ScriptObjects/Tryclops.hpp deleted file mode 100644 index 4bf127ee8..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Tryclops.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Tryclops : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/VisorFlare.hpp b/DataSpec/DNAMP1/ScriptObjects/VisorFlare.hpp deleted file mode 100644 index f617719ce..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/VisorFlare.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct VisorFlare : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - FlareDefinition flareDefinitions[5]; - - void nameIDs(PAKRouter& pakRouter) const override { - flareDefinitions[0].nameIDs(pakRouter, name + "_flare1"); - flareDefinitions[1].nameIDs(pakRouter, name + "_flare2"); - flareDefinitions[2].nameIDs(pakRouter, name + "_flare3"); - flareDefinitions[3].nameIDs(pakRouter, name + "_flare4"); - flareDefinitions[4].nameIDs(pakRouter, name + "_flare5"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - for (int i = 0; i < 5; ++i) - flareDefinitions[i].depIDs(pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/VisorGoo.hpp b/DataSpec/DNAMP1/ScriptObjects/VisorGoo.hpp deleted file mode 100644 index 01ba8e833..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/VisorGoo.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct VisorGoo : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value position; - UniqueID32 particle; - UniqueID32 electric; - Value minDist; - Value maxDist; - Value nearProb; - Value farProb; - DNAColor color; - Value sfx; - Value skipAngleTest; - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - if (electric.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(electric); - ent->name = name + "_elsc"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle, pathsOut); - g_curSpec->flattenDependencies(electric, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/WallCrawlerSwarm.hpp b/DataSpec/DNAMP1/ScriptObjects/WallCrawlerSwarm.hpp deleted file mode 100644 index 94c76b4f5..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/WallCrawlerSwarm.hpp +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct WallCrawlerSwarm : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value volume; - Value active; - ActorParameters actorParameters; - Value flavor; - AnimationParameters animationParameters; - Value launchAnim; - Value attractAnim; - UniqueID32 part1; - UniqueID32 part2; - UniqueID32 part3; - UniqueID32 part4; - DamageInfo crabDamage; - Value crabDamageCooldown; - DamageInfo scarabExplodeDamage; - Value boidRadius; - Value touchRadius; - Value playerTouchRadius; - Value animPlaybackSpeed; - Value numBoids; - Value maxCreatedBoids; - Value separationRadius; - Value cohesionMagnitude; - Value alignmentWeight; - Value separationMagnitude; - Value moveToWaypointWeight; - Value attractionMagnitude; - Value attractionRadius; - Value boidGenRate; - Value maxLaunches; - Value scarabBoxMargin; - Value scarabScatterXYVelocity; - Value scarabTimeToExplode; - HealthInfo healthInfo; - DamageVulnerability damageVulnerabilty; - Value launchSfx; - Value scatterSfx; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (part1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part1); - ent->name = name + "_part1"; - } - if (part2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part2); - ent->name = name + "_part2"; - } - if (part3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part3); - ent->name = name + "_part3"; - } - if (part4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part4); - ent->name = name + "_part4"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(part1, pathsOut); - g_curSpec->flattenDependencies(part2, pathsOut); - g_curSpec->flattenDependencies(part3, pathsOut); - g_curSpec->flattenDependencies(part4, pathsOut); - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Warwasp.hpp b/DataSpec/DNAMP1/ScriptObjects/Warwasp.hpp deleted file mode 100644 index cf6a692ff..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Warwasp.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Warwasp : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value flavor; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value colliderType; - DamageInfo damageInfo1; - UniqueID32 projectileWeapon; - DamageInfo projectileDamage; - UniqueID32 projectileVisorParticle; - Value projectileVisorSfx; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (projectileWeapon.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(projectileWeapon); - ent->name = name + "_wpsc"; - } - if (projectileVisorParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(projectileVisorParticle); - ent->name = name + "_part"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(projectileWeapon, pathsOut); - g_curSpec->flattenDependencies(projectileVisorParticle, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Water.cpp b/DataSpec/DNAMP1/ScriptObjects/Water.cpp deleted file mode 100644 index 2306b7943..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Water.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "Water.hpp" - -namespace DataSpec::DNAMP1 { - -template <> -void Water::UnusedBitset::Enumerate(typename Read::StreamT& in) { - if (in.readBool()) { - atUint32 bitVal0 = in.readUint16Big(); - atUint32 bitVal1 = in.readUint16Big(); - atUint32 len = ((bitVal0 * bitVal1) + 31) / 31; - in.seek(len * 4); - } -} -template <> -void Water::UnusedBitset::Enumerate(typename Write::StreamT& out) { - out.writeBool(false); -} -template <> -void Water::UnusedBitset::Enumerate(typename ReadYaml::StreamT& r) {} -template <> -void Water::UnusedBitset::Enumerate(typename WriteYaml::StreamT& w) {} -template <> -void Water::UnusedBitset::Enumerate(typename BinarySize::StreamT& s) { - s += 1; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Water.hpp b/DataSpec/DNAMP1/ScriptObjects/Water.hpp deleted file mode 100644 index 51350be4d..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Water.hpp +++ /dev/null @@ -1,163 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Water : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value volume; - DamageInfo damageInfo; - Value orientedForce; - Value triggerFlags; - Value thermalCold; - Value displaySurface; - UniqueID32 patternMap1; - UniqueID32 patternMap2; - UniqueID32 colorMap; - UniqueID32 bumpMap; - UniqueID32 envMap; - UniqueID32 envBumpMap; - Value bumpLightDir; - Value bumpScale; - Value morphInTime; - Value morphOutTime; - Value active; - Value fluidType; - Value unknownBool; - Value alpha; - struct FluidUVMotion : BigDNA { - AT_DECL_DNA - struct FluidLayerMotion : BigDNA { - AT_DECL_DNA - Value motionType; - Value timeToWrap; - Value orientation; - Value magnitude; - Value uvMul; - }; - - FluidLayerMotion pattern1Layer; - FluidLayerMotion pattern2Layer; - FluidLayerMotion colorLayer; - Value timeToWrap; - Value orientation; - } fluidUVMotion; - - Value turbulenceSpeed; - Value turbulenceDistance; - Value turbulenceFrequencyMax; - Value turbulenceFrequencyMin; - Value turbulencePhaseMax; - Value turbulencePhaseMin; - Value turbulenceAmplitudeMax; - Value turbulenceAmplitudeMin; - Value splashColor; - Value insideFogColor; - UniqueID32 splashParticle1; - UniqueID32 splashParticle2; - UniqueID32 splashParticle3; - UniqueID32 visorRunoffParticle; - UniqueID32 unmorphVisorRunoffParticle; - Value visorRunoffSfx; - Value unmorphVisorRunoffSfx; - Value splashSfx1; - Value splashSfx2; - Value splashSfx3; - Value tileSize; - Value tileSubdivisions; - Value specularMin; - Value specularMax; - Value reflectionSize; - Value rippleIntensity; - Value reflectionBlend; - Value fogBias; - Value fogMagnitude; - Value fogSpeed; - Value fogColor; - UniqueID32 lightmap; - Value unitsPerLightmapTexel; - Value alphaInTime; - Value alphaOutTime; - Value unusedInt1; - Value unusedInt2; - - struct UnusedBitset : BigDNA{AT_DECL_EXPLICIT_DNA} unusedBitset; - - void nameIDs(PAKRouter& pakRouter) const override { - if (patternMap1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternMap1); - ent->name = name + "_patternMap1"; - } - if (patternMap2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternMap2); - ent->name = name + "_patternMap2"; - } - if (colorMap.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(colorMap); - ent->name = name + "_colorMap"; - } - if (bumpMap.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(bumpMap); - ent->name = name + "_bumpMap"; - } - if (envMap.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(envMap); - ent->name = name + "_envMap"; - } - if (envBumpMap.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(envBumpMap); - ent->name = name + "_envBumpMap"; - } - if (lightmap.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(lightmap); - ent->name = name + "_lightmap"; - } - if (splashParticle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle1); - ent->name = name + "_splashParticle1"; - } - if (splashParticle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle2); - ent->name = name + "_splashParticle2"; - } - if (splashParticle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle3); - ent->name = name + "_splashParticle3"; - } - if (visorRunoffParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(visorRunoffParticle); - ent->name = name + "_visorRunoffParticle"; - } - if (unmorphVisorRunoffParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(unmorphVisorRunoffParticle); - ent->name = name + "_unmorphVisorRunoffParticle"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(patternMap1, pathsOut); - g_curSpec->flattenDependencies(patternMap2, pathsOut); - g_curSpec->flattenDependencies(colorMap, pathsOut); - g_curSpec->flattenDependencies(bumpMap, pathsOut); - g_curSpec->flattenDependencies(envMap, pathsOut); - g_curSpec->flattenDependencies(envBumpMap, pathsOut); - g_curSpec->flattenDependencies(lightmap, pathsOut); - g_curSpec->flattenDependencies(splashParticle1, pathsOut); - g_curSpec->flattenDependencies(splashParticle2, pathsOut); - g_curSpec->flattenDependencies(splashParticle3, pathsOut); - g_curSpec->flattenDependencies(visorRunoffParticle, pathsOut); - g_curSpec->flattenDependencies(unmorphVisorRunoffParticle, pathsOut); - } - - zeus::CAABox getVISIAABB(hecl::blender::Token& btok) const override { - zeus::CVector3f halfExtent = zeus::CVector3f(volume) / 2.f; - zeus::CVector3f loc(location); - return zeus::CAABox(loc - halfExtent, loc + halfExtent); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Waypoint.hpp b/DataSpec/DNAMP1/ScriptObjects/Waypoint.hpp deleted file mode 100644 index db0ec0cd2..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Waypoint.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Waypoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value speed; - Value pause; - Value patternTranslate; - Value patternOrient; - Value patternFit; - Value behaviour; - Value behaviourOrient; - Value behaviourModifiers; // 0x2: single, 0x4: double - Value animation; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/WorldLightFader.hpp b/DataSpec/DNAMP1/ScriptObjects/WorldLightFader.hpp deleted file mode 100644 index 18eaec3ba..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/WorldLightFader.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct WorldLightFader : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value fadedLevel; - Value intialLevel; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/WorldTeleporter.cpp b/DataSpec/DNAMP1/ScriptObjects/WorldTeleporter.cpp deleted file mode 100644 index 54fcd60b0..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/WorldTeleporter.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "WorldTeleporter.hpp" - -namespace DataSpec::DNAMP1 { - -template -void WorldTeleporter::Enumerate(typename Op::StreamT& s) { - IScriptObject::Enumerate(s); - Do(athena::io::PropId{"name"}, name, s); - Do(athena::io::PropId{"active"}, active, s); - Do(athena::io::PropId{"mlvl"}, mlvl, s); - Do(athena::io::PropId{"mrea"}, mrea, s); - Do(athena::io::PropId{"animationParameters"}, animationParameters, s); - Do(athena::io::PropId{"playerScale"}, playerScale, s); - Do(athena::io::PropId{"platformModel"}, platformModel, s); - Do(athena::io::PropId{"platformScale"}, platformScale, s); - Do(athena::io::PropId{"blackgroundModel"}, backgroundModel, s); - Do(athena::io::PropId{"backgroundScale"}, backgroundScale, s); - Do(athena::io::PropId{"upElevator"}, upElevator, s); - Do(athena::io::PropId{"elevatorSound"}, elevatorSound, s); - Do(athena::io::PropId{"volume"}, volume, s); - Do(athena::io::PropId{"panning"}, panning, s); - Do(athena::io::PropId{"showText"}, showText, s); - Do(athena::io::PropId{"font"}, font, s); - Do(athena::io::PropId{"strg"}, strg, s); - Do(athena::io::PropId{"fadeWhite"}, fadeWhite, s); - Do(athena::io::PropId{"charFadeInTime"}, charFadeInTime, s); - Do(athena::io::PropId{"charsPerSecond"}, charsPerSecond, s); - Do(athena::io::PropId{"showDelay"}, showDelay, s); - - if (propertyCount == 26) { - Do(athena::io::PropId{"audioStream"}, audioStream, s); - Do(athena::io::PropId{"unknown13"}, unknown13, s); - Do(athena::io::PropId{"unknown14"}, unknown14, s); - Do(athena::io::PropId{"unknown15"}, unknown15, s); - Do(athena::io::PropId{"unknown16"}, unknown16, s); - } else { - unknown13 = false; - unknown14 = 0.0; - unknown15 = 0.0; - unknown16 = 0.0; - } -} - -std::string_view WorldTeleporter::DNAType() { return "DNAMP1::WorldTeleporter"sv; } - -AT_SPECIALIZE_DNA_YAML(WorldTeleporter) - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/WorldTeleporter.hpp b/DataSpec/DNAMP1/ScriptObjects/WorldTeleporter.hpp deleted file mode 100644 index 559f2e371..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/WorldTeleporter.hpp +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { - -struct WorldTeleporter : IScriptObject { - AT_DECL_EXPLICIT_DNA_YAMLV - String<-1> name; - Value active; - UniqueID32 mlvl; - UniqueID32 mrea; - AnimationParameters animationParameters; - Value playerScale; - UniqueID32 platformModel; - Value platformScale; - UniqueID32 backgroundModel; - Value backgroundScale; - Value upElevator; - Value elevatorSound; // needs verifcation - Value volume; - Value panning; - Value showText; - UniqueID32 font; - UniqueID32 strg; - Value fadeWhite; - Value charFadeInTime; - Value charsPerSecond; - Value showDelay; - - /* Trilogy additions (property count 26) */ - String<-1> audioStream; - Value unknown13; - Value unknown14; - Value unknown15; - Value unknown16; - - void nameIDs(PAKRouter& pakRouter) const override { - if (platformModel.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(platformModel); - ent->name = name + "_model1"; - } - if (backgroundModel.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(backgroundModel); - ent->name = name + "_model2"; - } - if (strg.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(strg); - ent->name = name + "_strg"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(platformModel, pathsOut); - g_curSpec->flattenDependencies(backgroundModel, pathsOut); - g_curSpec->flattenDependencies(strg, pathsOut); - } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/SnowForces.hpp b/DataSpec/DNAMP1/SnowForces.hpp deleted file mode 100644 index d96ca7c2b..000000000 --- a/DataSpec/DNAMP1/SnowForces.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { -struct SnowForces : BigDNA { - AT_DECL_DNA_YAML - struct Force : BigDNA { - AT_DECL_DNA - Value gravity; - Value wind; - }; - - Value forces[256]; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp b/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp deleted file mode 100644 index a0f9e6609..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp" - -#include - -namespace hecl { -class CVar; -} - -namespace DataSpec::DNAMP1 { -struct CTweakAutoMapper final : public ITweakAutoMapper { - AT_DECL_DNA_YAML - Value x4_24_showOneMiniMapArea; - Value x4_25_; - Value x4_26_scaleMoveSpeedWithCamDist; - Value x8_camDist; - Value xc_minCamDist; - Value x10_maxCamDist; - Value x14_minCamRotateX; - Value x18_maxCamRotateX; - Value x1c_camAngle; - Value x20_; - DNAColor x24_automapperWidgetColor; - Value x28_miniCamDist; - Value x2c_miniCamXAngle; - Value x30_miniCamAngle; - Value x34_; - DNAColor x38_automapperWidgetMiniColor; - DNAColor x3c_surfColorVisited; - DNAColor x40_outlineColorVisited; - DNAColor x44_surfColorUnvisited; - DNAColor x48_outlineColorUnvisited; - DNAColor x4c_surfaceSelectColorVisited; - DNAColor x50_outlineSelectColorVisited; - Value x54_mapSurfaceNormColorLinear; - Value x58_mapSurfaceNormColorConstant; - Value x5c_; - float x60_ = 0.4f; - Value x64_openMapScreenTime; - Value x68_closeMapScreenTime; - Value x6c_hintPanTime; - Value x70_zoomUnitsPerFrame; - Value x74_rotateDegPerFrame; - Value x78_baseMapScreenCameraMoveSpeed; - DNAColor x7c_surfaceSelectColorUnvisited; - DNAColor x80_outlineSelectColorUnvisited; - Value x84_miniAlphaSurfaceVisited; - Value x88_alphaSurfaceVisited; - Value x8c_miniAlphaOutlineVisited; - Value x90_alphaOutlineVisited; - Value x94_miniAlphaSurfaceUnvisited; - Value x98_alphaSurfaceUnvisited; - Value x9c_miniAlphaOutlineUnvisited; - Value xa0_alphaOutlineUnvisited; - /* Originally 4 separate floats */ - Value xa4_doorCenter; - Value xb0_; - Value xb4_; - Value xb8_miniMapViewportWidth; - Value xbc_miniMapViewportHeight; - Value xc0_miniMapCamDistScale; - Value xc4_mapPlaneScaleX; - Value xc8_mapPlaneScaleZ; - Value xcc_; - Value xd0_universeCamDist; - Value xd4_minUniverseCamDist; - Value xd8_maxUniverseCamDist; - Value xdc_switchToFromUniverseTime; - Value xe0_camPanUnitsPerFrame; - Value xe4_automapperScaleX; - Value xe8_automapperScaleZ; - Value xec_camVerticalOffset; - DNAColor xf0_miniMapSamusModColor; - DNAColor xf4_areaFlashPulseColor; - DNAColor xf8_; - DNAColor xfc_; - Value x100_doorColorCount; - Vector x104_doorColors; - DNAColor x118_doorBorderColor; - DNAColor x11c_openDoorColor; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakBall.cpp b/DataSpec/DNAMP1/Tweaks/CTweakBall.cpp deleted file mode 100644 index c67d19b24..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakBall.cpp +++ /dev/null @@ -1,920 +0,0 @@ -#include "CTweakBall.hpp" - -namespace DataSpec::DNAMP1 { - -template <> -void CTweakBall::Enumerate(typename Read::StreamT& __dna_reader) { - /* x4_maxTranslationAcceleration[0] */ - x4_maxTranslationAcceleration[0] = __dna_reader.readFloatBig(); - /* x4_maxTranslationAcceleration[1] */ - x4_maxTranslationAcceleration[1] = __dna_reader.readFloatBig(); - /* x4_maxTranslationAcceleration[2] */ - x4_maxTranslationAcceleration[2] = __dna_reader.readFloatBig(); - /* x4_maxTranslationAcceleration[3] */ - x4_maxTranslationAcceleration[3] = __dna_reader.readFloatBig(); - /* x4_maxTranslationAcceleration[4] */ - x4_maxTranslationAcceleration[4] = __dna_reader.readFloatBig(); - /* x4_maxTranslationAcceleration[5] */ - x4_maxTranslationAcceleration[5] = __dna_reader.readFloatBig(); - /* x4_maxTranslationAcceleration[6] */ - x4_maxTranslationAcceleration[6] = __dna_reader.readFloatBig(); - /* x4_maxTranslationAcceleration[7] */ - x4_maxTranslationAcceleration[7] = __dna_reader.readFloatBig(); - /* x24_translationFriction[0] */ - x24_translationFriction[0] = __dna_reader.readFloatBig(); - /* x24_translationFriction[1] */ - x24_translationFriction[1] = __dna_reader.readFloatBig(); - /* x24_translationFriction[2] */ - x24_translationFriction[2] = __dna_reader.readFloatBig(); - /* x24_translationFriction[3] */ - x24_translationFriction[3] = __dna_reader.readFloatBig(); - /* x24_translationFriction[4] */ - x24_translationFriction[4] = __dna_reader.readFloatBig(); - /* x24_translationFriction[5] */ - x24_translationFriction[5] = __dna_reader.readFloatBig(); - /* x24_translationFriction[6] */ - x24_translationFriction[6] = __dna_reader.readFloatBig(); - /* x24_translationFriction[7] */ - x24_translationFriction[7] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[0] */ - x44_translationMaxSpeed[0] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[1] */ - x44_translationMaxSpeed[1] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[2] */ - x44_translationMaxSpeed[2] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[3] */ - x44_translationMaxSpeed[3] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[4] */ - x44_translationMaxSpeed[4] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[5] */ - x44_translationMaxSpeed[5] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[6] */ - x44_translationMaxSpeed[6] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[7] */ - x44_translationMaxSpeed[7] = __dna_reader.readFloatBig(); - /* x64_ */ - x64_ = __dna_reader.readFloatBig(); - /* x68_ */ - x68_ = __dna_reader.readFloatBig(); - /* x6c_ */ - x6c_ = __dna_reader.readFloatBig(); - /* x70_ */ - x70_ = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[0] */ - xc4_ballForwardBrakingAcceleration[0] = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[1] */ - xc4_ballForwardBrakingAcceleration[1] = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[2] */ - xc4_ballForwardBrakingAcceleration[2] = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[3] */ - xc4_ballForwardBrakingAcceleration[3] = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[4] */ - xc4_ballForwardBrakingAcceleration[4] = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[5] */ - xc4_ballForwardBrakingAcceleration[5] = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[6] */ - xc4_ballForwardBrakingAcceleration[6] = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[7] */ - xc4_ballForwardBrakingAcceleration[7] = __dna_reader.readFloatBig(); - /* xe4_ballGravity */ - xe4_ballGravity = __dna_reader.readFloatBig(); - /* xe8_ballWaterGravity */ - xe8_ballWaterGravity = __dna_reader.readFloatBig(); - /* x14c_ */ - x14c_ = __dna_reader.readFloatBig(); - /* x150_ */ - x150_ = __dna_reader.readFloatBig(); - /* x158_ */ - x158_ = __dna_reader.readFloatBig(); - /* x1dc_minimumAlignmentSpeed */ - x1dc_minimumAlignmentSpeed = __dna_reader.readFloatBig(); - /* x1e0_tireness */ - x1e0_tireness = __dna_reader.readFloatBig(); - /* x1ec_maxLeanAngle */ - x1ec_maxLeanAngle = __dna_reader.readFloatBig(); - /* x1f0_tireToMarbleThresholdSpeed */ - x1f0_tireToMarbleThresholdSpeed = __dna_reader.readFloatBig(); - /* x1f4_marbleToTireThresholdSpeed */ - x1f4_marbleToTireThresholdSpeed = __dna_reader.readFloatBig(); - /* x1f8_forceToLeanGain */ - x1f8_forceToLeanGain = __dna_reader.readFloatBig(); - /* x1fc_leanTrackingGain */ - x1fc_leanTrackingGain = __dna_reader.readFloatBig(); - /* x74_ballCameraAnglePerSecond */ - x74_ballCameraAnglePerSecond = __dna_reader.readFloatBig(); - /* x78_ballCameraOffset */ - x78_ballCameraOffset = __dna_reader.readVec3fBig(); - /* x84_ballCameraMinSpeedDistance */ - x84_ballCameraMinSpeedDistance = __dna_reader.readFloatBig(); - /* x88_ballCameraMaxSpeedDistance */ - x88_ballCameraMaxSpeedDistance = __dna_reader.readFloatBig(); - /* x8c_ballCameraBackwardsDistance */ - x8c_ballCameraBackwardsDistance = __dna_reader.readFloatBig(); - /* x90_ */ - x90_ = __dna_reader.readFloatBig(); - /* x94_ballCameraSpringConstant */ - x94_ballCameraSpringConstant = __dna_reader.readFloatBig(); - /* x98_ballCameraSpringMax */ - x98_ballCameraSpringMax = __dna_reader.readFloatBig(); - /* x9c_ballCameraSpringTardis */ - x9c_ballCameraSpringTardis = __dna_reader.readFloatBig(); - /* xa0_ballCameraCentroidSpringConstant */ - xa0_ballCameraCentroidSpringConstant = __dna_reader.readFloatBig(); - /* xa4_ballCameraCentroidSpringMax */ - xa4_ballCameraCentroidSpringMax = __dna_reader.readFloatBig(); - /* xa8_ballCameraCentroidSpringTardis */ - xa8_ballCameraCentroidSpringTardis = __dna_reader.readFloatBig(); - /* xac_ballCameraCentroidDistanceSpringConstant */ - xac_ballCameraCentroidDistanceSpringConstant = __dna_reader.readFloatBig(); - /* xb0_ballCameraCentroidDistanceSpringMax */ - xb0_ballCameraCentroidDistanceSpringMax = __dna_reader.readFloatBig(); - /* xb4_ballCameraCentroidDistanceSpringTardis */ - xb4_ballCameraCentroidDistanceSpringTardis = __dna_reader.readFloatBig(); - /* xb8_ballCameraLookAtSpringConstant */ - xb8_ballCameraLookAtSpringConstant = __dna_reader.readFloatBig(); - /* xbc_ballCameraLookAtSpringMax */ - xbc_ballCameraLookAtSpringMax = __dna_reader.readFloatBig(); - /* xc0_ballCameraLookAtSpringTardis */ - xc0_ballCameraLookAtSpringTardis = __dna_reader.readFloatBig(); - /* x154_ */ - x154_ = __dna_reader.readFloatBig(); - /* x15c_ */ - x15c_ = __dna_reader.readFloatBig(); - /* x160_ */ - x160_ = __dna_reader.readFloatBig(); - /* x164_ */ - x164_ = __dna_reader.readFloatBig(); - /* x168_ */ - x168_ = __dna_reader.readFloatBig(); - /* x16c_ */ - x16c_ = __dna_reader.readFloatBig(); - /* x170_conservativeDoorCamDistance */ - x170_conservativeDoorCamDistance = __dna_reader.readFloatBig(); - /* x174_ */ - x174_ = __dna_reader.readFloatBig(); - /* x178_ballCameraChaseElevation */ - x178_ballCameraChaseElevation = __dna_reader.readFloatBig(); - /* x17c_ballCameraChaseDampenAngle */ - x17c_ballCameraChaseDampenAngle = __dna_reader.readFloatBig(); - /* x180_ballCameraChaseDistance */ - x180_ballCameraChaseDistance = __dna_reader.readFloatBig(); - /* x184_ballCameraChaseYawSpeed */ - x184_ballCameraChaseYawSpeed = __dna_reader.readFloatBig(); - /* x188_ballCameraChaseAnglePerSecond */ - x188_ballCameraChaseAnglePerSecond = __dna_reader.readFloatBig(); - /* x18c_ballCameraChaseLookAtOffset */ - x18c_ballCameraChaseLookAtOffset = __dna_reader.readVec3fBig(); - /* x198_ballCameraChaseSpringConstant */ - x198_ballCameraChaseSpringConstant = __dna_reader.readFloatBig(); - /* x19c_ballCameraChaseSpringMax */ - x19c_ballCameraChaseSpringMax = __dna_reader.readFloatBig(); - /* x1a0_ballCameraChaseSpringTardis */ - x1a0_ballCameraChaseSpringTardis = __dna_reader.readFloatBig(); - /* x1a4_ballCameraBoostElevation */ - x1a4_ballCameraBoostElevation = __dna_reader.readFloatBig(); - /* x1a8_ballCameraBoostDampenAngle */ - x1a8_ballCameraBoostDampenAngle = __dna_reader.readFloatBig(); - /* x1ac_ballCameraBoostDistance */ - x1ac_ballCameraBoostDistance = __dna_reader.readFloatBig(); - /* x1b0_ballCameraBoostYawSpeed */ - x1b0_ballCameraBoostYawSpeed = __dna_reader.readFloatBig(); - /* x1b4_ballCameraBoostAnglePerSecond */ - x1b4_ballCameraBoostAnglePerSecond = __dna_reader.readFloatBig(); - /* x1b8_ballCameraBoostLookAtOffset */ - x1b8_ballCameraBoostLookAtOffset = __dna_reader.readVec3fBig(); - /* x1c4_ballCameraBoostSpringConstant */ - x1c4_ballCameraBoostSpringConstant = __dna_reader.readFloatBig(); - /* x1c8_ballCameraBoostSpringMax */ - x1c8_ballCameraBoostSpringMax = __dna_reader.readFloatBig(); - /* x1cc_ballCameraBoostSpringTardis */ - x1cc_ballCameraBoostSpringTardis = __dna_reader.readFloatBig(); - /* x1d0_ballCameraControlDistance */ - x1d0_ballCameraControlDistance = __dna_reader.readFloatBig(); - /* x1d4_ */ - x1d4_ = __dna_reader.readFloatBig(); - /* x1d8_ */ - x1d8_ = __dna_reader.readFloatBig(); - /* x1e4_leftStickDivisor */ - x1e4_leftStickDivisor = __dna_reader.readFloatBig(); - /* x1e8_rightStickDivisor */ - x1e8_rightStickDivisor = __dna_reader.readFloatBig(); - /* x200_ */ - x200_ = __dna_reader.readFloatBig(); - /* x204_ballTouchRadius */ - x204_ballTouchRadius = __dna_reader.readFloatBig(); - /* x20c_boostBallDrainTime */ - x20c_boostBallDrainTime = __dna_reader.readFloatBig(); - /* x218_boostBallMinChargeTime */ - x218_boostBallMinChargeTime = __dna_reader.readFloatBig(); - /* x21c_boostBallMinRelativeSpeedForDamage */ - x21c_boostBallMinRelativeSpeedForDamage = __dna_reader.readFloatBig(); - /* x220_boostBallChargeTime0 */ - x220_boostBallChargeTime0 = __dna_reader.readFloatBig(); - /* x224_boostBallChargeTime1 */ - x224_boostBallChargeTime1 = __dna_reader.readFloatBig(); - /* x210_boostBallMaxChargeTime */ - x228_boostBallChargeTime2 = x210_boostBallMaxChargeTime = __dna_reader.readFloatBig(); - /* x22c_boostBallIncrementalSpeed0 */ - x22c_boostBallIncrementalSpeed0 = __dna_reader.readFloatBig(); - /* x230_boostBallIncrementalSpeed1 */ - x230_boostBallIncrementalSpeed1 = __dna_reader.readFloatBig(); - /* x234_boostBallIncrementalSpeed2 */ - x234_boostBallIncrementalSpeed2 = __dna_reader.readFloatBig(); -} - -template <> -void CTweakBall::Enumerate(typename Write::StreamT& __dna_writer) { - /* x4_maxTranslationAcceleration[0] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[0]); - /* x4_maxTranslationAcceleration[1] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[1]); - /* x4_maxTranslationAcceleration[2] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[2]); - /* x4_maxTranslationAcceleration[3] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[3]); - /* x4_maxTranslationAcceleration[4] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[4]); - /* x4_maxTranslationAcceleration[5] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[5]); - /* x4_maxTranslationAcceleration[6] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[6]); - /* x4_maxTranslationAcceleration[7] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[7]); - /* x24_translationFriction[0] */ - __dna_writer.writeFloatBig(x24_translationFriction[0]); - /* x24_translationFriction[1] */ - __dna_writer.writeFloatBig(x24_translationFriction[1]); - /* x24_translationFriction[2] */ - __dna_writer.writeFloatBig(x24_translationFriction[2]); - /* x24_translationFriction[3] */ - __dna_writer.writeFloatBig(x24_translationFriction[3]); - /* x24_translationFriction[4] */ - __dna_writer.writeFloatBig(x24_translationFriction[4]); - /* x24_translationFriction[5] */ - __dna_writer.writeFloatBig(x24_translationFriction[5]); - /* x24_translationFriction[6] */ - __dna_writer.writeFloatBig(x24_translationFriction[6]); - /* x24_translationFriction[7] */ - __dna_writer.writeFloatBig(x24_translationFriction[7]); - /* x44_translationMaxSpeed[0] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[0]); - /* x44_translationMaxSpeed[1] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[1]); - /* x44_translationMaxSpeed[2] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[2]); - /* x44_translationMaxSpeed[3] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[3]); - /* x44_translationMaxSpeed[4] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[4]); - /* x44_translationMaxSpeed[5] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[5]); - /* x44_translationMaxSpeed[6] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[6]); - /* x44_translationMaxSpeed[7] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[7]); - /* x64_ */ - __dna_writer.writeFloatBig(x64_); - /* x68_ */ - __dna_writer.writeFloatBig(x68_); - /* x6c_ */ - __dna_writer.writeFloatBig(x6c_); - /* x70_ */ - __dna_writer.writeFloatBig(x70_); - /* xc4_ballForwardBrakingAcceleration[0] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[0]); - /* xc4_ballForwardBrakingAcceleration[1] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[1]); - /* xc4_ballForwardBrakingAcceleration[2] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[2]); - /* xc4_ballForwardBrakingAcceleration[3] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[3]); - /* xc4_ballForwardBrakingAcceleration[4] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[4]); - /* xc4_ballForwardBrakingAcceleration[5] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[5]); - /* xc4_ballForwardBrakingAcceleration[6] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[6]); - /* xc4_ballForwardBrakingAcceleration[7] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[7]); - /* xe4_ballGravity */ - __dna_writer.writeFloatBig(xe4_ballGravity); - /* xe8_ballWaterGravity */ - __dna_writer.writeFloatBig(xe8_ballWaterGravity); - /* x14c_ */ - __dna_writer.writeFloatBig(x14c_); - /* x150_ */ - __dna_writer.writeFloatBig(x150_); - /* x158_ */ - __dna_writer.writeFloatBig(x158_); - /* x1dc_minimumAlignmentSpeed */ - __dna_writer.writeFloatBig(x1dc_minimumAlignmentSpeed); - /* x1e0_tireness */ - __dna_writer.writeFloatBig(x1e0_tireness); - /* x1ec_maxLeanAngle */ - __dna_writer.writeFloatBig(x1ec_maxLeanAngle); - /* x1f0_tireToMarbleThresholdSpeed */ - __dna_writer.writeFloatBig(x1f0_tireToMarbleThresholdSpeed); - /* x1f4_marbleToTireThresholdSpeed */ - __dna_writer.writeFloatBig(x1f4_marbleToTireThresholdSpeed); - /* x1f8_forceToLeanGain */ - __dna_writer.writeFloatBig(x1f8_forceToLeanGain); - /* x1fc_leanTrackingGain */ - __dna_writer.writeFloatBig(x1fc_leanTrackingGain); - /* x74_ballCameraAnglePerSecond */ - __dna_writer.writeFloatBig(x74_ballCameraAnglePerSecond); - /* x78_ballCameraOffset */ - __dna_writer.writeVec3fBig(x78_ballCameraOffset); - /* x84_ballCameraMinSpeedDistance */ - __dna_writer.writeFloatBig(x84_ballCameraMinSpeedDistance); - /* x88_ballCameraMaxSpeedDistance */ - __dna_writer.writeFloatBig(x88_ballCameraMaxSpeedDistance); - /* x8c_ballCameraBackwardsDistance */ - __dna_writer.writeFloatBig(x8c_ballCameraBackwardsDistance); - /* x90_ */ - __dna_writer.writeFloatBig(x90_); - /* x94_ballCameraSpringConstant */ - __dna_writer.writeFloatBig(x94_ballCameraSpringConstant); - /* x98_ballCameraSpringMax */ - __dna_writer.writeFloatBig(x98_ballCameraSpringMax); - /* x9c_ballCameraSpringTardis */ - __dna_writer.writeFloatBig(x9c_ballCameraSpringTardis); - /* xa0_ballCameraCentroidSpringConstant */ - __dna_writer.writeFloatBig(xa0_ballCameraCentroidSpringConstant); - /* xa4_ballCameraCentroidSpringMax */ - __dna_writer.writeFloatBig(xa4_ballCameraCentroidSpringMax); - /* xa8_ballCameraCentroidSpringTardis */ - __dna_writer.writeFloatBig(xa8_ballCameraCentroidSpringTardis); - /* xac_ballCameraCentroidDistanceSpringConstant */ - __dna_writer.writeFloatBig(xac_ballCameraCentroidDistanceSpringConstant); - /* xb0_ballCameraCentroidDistanceSpringMax */ - __dna_writer.writeFloatBig(xb0_ballCameraCentroidDistanceSpringMax); - /* xb4_ballCameraCentroidDistanceSpringTardis */ - __dna_writer.writeFloatBig(xb4_ballCameraCentroidDistanceSpringTardis); - /* xb8_ballCameraLookAtSpringConstant */ - __dna_writer.writeFloatBig(xb8_ballCameraLookAtSpringConstant); - /* xbc_ballCameraLookAtSpringMax */ - __dna_writer.writeFloatBig(xbc_ballCameraLookAtSpringMax); - /* xc0_ballCameraLookAtSpringTardis */ - __dna_writer.writeFloatBig(xc0_ballCameraLookAtSpringTardis); - /* x154_ */ - __dna_writer.writeFloatBig(x154_); - /* x15c_ */ - __dna_writer.writeFloatBig(x15c_); - /* x160_ */ - __dna_writer.writeFloatBig(x160_); - /* x164_ */ - __dna_writer.writeFloatBig(x164_); - /* x168_ */ - __dna_writer.writeFloatBig(x168_); - /* x16c_ */ - __dna_writer.writeFloatBig(x16c_); - /* x170_conservativeDoorCamDistance */ - __dna_writer.writeFloatBig(x170_conservativeDoorCamDistance); - /* x174_ */ - __dna_writer.writeFloatBig(x174_); - /* x178_ballCameraChaseElevation */ - __dna_writer.writeFloatBig(x178_ballCameraChaseElevation); - /* x17c_ballCameraChaseDampenAngle */ - __dna_writer.writeFloatBig(x17c_ballCameraChaseDampenAngle); - /* x180_ballCameraChaseDistance */ - __dna_writer.writeFloatBig(x180_ballCameraChaseDistance); - /* x184_ballCameraChaseYawSpeed */ - __dna_writer.writeFloatBig(x184_ballCameraChaseYawSpeed); - /* x188_ballCameraChaseAnglePerSecond */ - __dna_writer.writeFloatBig(x188_ballCameraChaseAnglePerSecond); - /* x18c_ballCameraChaseLookAtOffset */ - __dna_writer.writeVec3fBig(x18c_ballCameraChaseLookAtOffset); - /* x198_ballCameraChaseSpringConstant */ - __dna_writer.writeFloatBig(x198_ballCameraChaseSpringConstant); - /* x19c_ballCameraChaseSpringMax */ - __dna_writer.writeFloatBig(x19c_ballCameraChaseSpringMax); - /* x1a0_ballCameraChaseSpringTardis */ - __dna_writer.writeFloatBig(x1a0_ballCameraChaseSpringTardis); - /* x1a4_ballCameraBoostElevation */ - __dna_writer.writeFloatBig(x1a4_ballCameraBoostElevation); - /* x1a8_ballCameraBoostDampenAngle */ - __dna_writer.writeFloatBig(x1a8_ballCameraBoostDampenAngle); - /* x1ac_ballCameraBoostDistance */ - __dna_writer.writeFloatBig(x1ac_ballCameraBoostDistance); - /* x1b0_ballCameraBoostYawSpeed */ - __dna_writer.writeFloatBig(x1b0_ballCameraBoostYawSpeed); - /* x1b4_ballCameraBoostAnglePerSecond */ - __dna_writer.writeFloatBig(x1b4_ballCameraBoostAnglePerSecond); - /* x1b8_ballCameraBoostLookAtOffset */ - __dna_writer.writeVec3fBig(x1b8_ballCameraBoostLookAtOffset); - /* x1c4_ballCameraBoostSpringConstant */ - __dna_writer.writeFloatBig(x1c4_ballCameraBoostSpringConstant); - /* x1c8_ballCameraBoostSpringMax */ - __dna_writer.writeFloatBig(x1c8_ballCameraBoostSpringMax); - /* x1cc_ballCameraBoostSpringTardis */ - __dna_writer.writeFloatBig(x1cc_ballCameraBoostSpringTardis); - /* x1d0_ballCameraControlDistance */ - __dna_writer.writeFloatBig(x1d0_ballCameraControlDistance); - /* x1d4_ */ - __dna_writer.writeFloatBig(x1d4_); - /* x1d8_ */ - __dna_writer.writeFloatBig(x1d8_); - /* x1e4_leftStickDivisor */ - __dna_writer.writeFloatBig(x1e4_leftStickDivisor); - /* x1e8_rightStickDivisor */ - __dna_writer.writeFloatBig(x1e8_rightStickDivisor); - /* x200_ */ - __dna_writer.writeFloatBig(x200_); - /* x204_ballTouchRadius */ - __dna_writer.writeFloatBig(x204_ballTouchRadius); - /* x20c_boostBallDrainTime */ - __dna_writer.writeFloatBig(x20c_boostBallDrainTime); - /* x218_boostBallMinChargeTime */ - __dna_writer.writeFloatBig(x218_boostBallMinChargeTime); - /* x21c_boostBallMinRelativeSpeedForDamage */ - __dna_writer.writeFloatBig(x21c_boostBallMinRelativeSpeedForDamage); - /* x220_boostBallChargeTime0 */ - __dna_writer.writeFloatBig(x220_boostBallChargeTime0); - /* x224_boostBallChargeTime1 */ - __dna_writer.writeFloatBig(x224_boostBallChargeTime1); - /* x210_boostBallMaxChargeTime */ - __dna_writer.writeFloatBig(x210_boostBallMaxChargeTime); - /* x22c_boostBallIncrementalSpeed0 */ - __dna_writer.writeFloatBig(x22c_boostBallIncrementalSpeed0); - /* x230_boostBallIncrementalSpeed1 */ - __dna_writer.writeFloatBig(x230_boostBallIncrementalSpeed1); - /* x234_boostBallIncrementalSpeed2 */ - __dna_writer.writeFloatBig(x234_boostBallIncrementalSpeed2); -} - -template <> -void CTweakBall::Enumerate(typename ReadYaml::StreamT& __dna_docin) { - /* x4_maxTranslationAcceleration */ - size_t __x4_Count; - if (auto v = __dna_docin.enterSubVector("x4_maxTranslationAcceleration", __x4_Count)) { - /* x4_maxTranslationAcceleration[0] */ - x4_maxTranslationAcceleration[0] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - /* x4_maxTranslationAcceleration[1] */ - x4_maxTranslationAcceleration[1] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - /* x4_maxTranslationAcceleration[2] */ - x4_maxTranslationAcceleration[2] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - /* x4_maxTranslationAcceleration[3] */ - x4_maxTranslationAcceleration[3] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - /* x4_maxTranslationAcceleration[4] */ - x4_maxTranslationAcceleration[4] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - /* x4_maxTranslationAcceleration[5] */ - x4_maxTranslationAcceleration[5] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - /* x4_maxTranslationAcceleration[6] */ - x4_maxTranslationAcceleration[6] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - /* x4_maxTranslationAcceleration[7] */ - x4_maxTranslationAcceleration[7] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - } - /* x24_translationFriction */ - size_t __x24_Count; - if (auto v = __dna_docin.enterSubVector("x24_translationFriction", __x24_Count)) { - /* x24_translationFriction[0] */ - x24_translationFriction[0] = __dna_docin.readFloat("x24_translationFriction"); - /* x24_translationFriction[1] */ - x24_translationFriction[1] = __dna_docin.readFloat("x24_translationFriction"); - /* x24_translationFriction[2] */ - x24_translationFriction[2] = __dna_docin.readFloat("x24_translationFriction"); - /* x24_translationFriction[3] */ - x24_translationFriction[3] = __dna_docin.readFloat("x24_translationFriction"); - /* x24_translationFriction[4] */ - x24_translationFriction[4] = __dna_docin.readFloat("x24_translationFriction"); - /* x24_translationFriction[5] */ - x24_translationFriction[5] = __dna_docin.readFloat("x24_translationFriction"); - /* x24_translationFriction[6] */ - x24_translationFriction[6] = __dna_docin.readFloat("x24_translationFriction"); - /* x24_translationFriction[7] */ - x24_translationFriction[7] = __dna_docin.readFloat("x24_translationFriction"); - } - /* x44_translationMaxSpeed */ - size_t __x44_Count; - if (auto v = __dna_docin.enterSubVector("x44_translationMaxSpeed", __x44_Count)) { - /* x44_translationMaxSpeed[0] */ - x44_translationMaxSpeed[0] = __dna_docin.readFloat("x44_translationMaxSpeed"); - /* x44_translationMaxSpeed[1] */ - x44_translationMaxSpeed[1] = __dna_docin.readFloat("x44_translationMaxSpeed"); - /* x44_translationMaxSpeed[2] */ - x44_translationMaxSpeed[2] = __dna_docin.readFloat("x44_translationMaxSpeed"); - /* x44_translationMaxSpeed[3] */ - x44_translationMaxSpeed[3] = __dna_docin.readFloat("x44_translationMaxSpeed"); - /* x44_translationMaxSpeed[4] */ - x44_translationMaxSpeed[4] = __dna_docin.readFloat("x44_translationMaxSpeed"); - /* x44_translationMaxSpeed[5] */ - x44_translationMaxSpeed[5] = __dna_docin.readFloat("x44_translationMaxSpeed"); - /* x44_translationMaxSpeed[6] */ - x44_translationMaxSpeed[6] = __dna_docin.readFloat("x44_translationMaxSpeed"); - /* x44_translationMaxSpeed[7] */ - x44_translationMaxSpeed[7] = __dna_docin.readFloat("x44_translationMaxSpeed"); - } - /* x64_ */ - x64_ = __dna_docin.readFloat("x64_"); - /* x68_ */ - x68_ = __dna_docin.readFloat("x68_"); - /* x6c_ */ - x6c_ = __dna_docin.readFloat("x6c_"); - /* x70_ */ - x70_ = __dna_docin.readFloat("x70_"); - /* xc4_ballForwardBrakingAcceleration */ - size_t __xc4_Count; - if (auto v = __dna_docin.enterSubVector("xc4_ballForwardBrakingAcceleration", __xc4_Count)) { - /* xc4_ballForwardBrakingAcceleration[0] */ - xc4_ballForwardBrakingAcceleration[0] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - /* xc4_ballForwardBrakingAcceleration[1] */ - xc4_ballForwardBrakingAcceleration[1] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - /* xc4_ballForwardBrakingAcceleration[2] */ - xc4_ballForwardBrakingAcceleration[2] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - /* xc4_ballForwardBrakingAcceleration[3] */ - xc4_ballForwardBrakingAcceleration[3] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - /* xc4_ballForwardBrakingAcceleration[4] */ - xc4_ballForwardBrakingAcceleration[4] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - /* xc4_ballForwardBrakingAcceleration[5] */ - xc4_ballForwardBrakingAcceleration[5] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - /* xc4_ballForwardBrakingAcceleration[6] */ - xc4_ballForwardBrakingAcceleration[6] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - /* xc4_ballForwardBrakingAcceleration[7] */ - xc4_ballForwardBrakingAcceleration[7] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - } - /* xe4_ballGravity */ - xe4_ballGravity = __dna_docin.readFloat("xe4_ballGravity"); - /* xe8_ballWaterGravity */ - xe8_ballWaterGravity = __dna_docin.readFloat("xe8_ballWaterGravity"); - /* x14c_ */ - x14c_ = __dna_docin.readFloat("x14c_"); - /* x150_ */ - x150_ = __dna_docin.readFloat("x150_"); - /* x158_ */ - x158_ = __dna_docin.readFloat("x158_"); - /* x1dc_minimumAlignmentSpeed */ - x1dc_minimumAlignmentSpeed = __dna_docin.readFloat("x1dc_minimumAlignmentSpeed"); - /* x1e0_tireness */ - x1e0_tireness = __dna_docin.readFloat("x1e0_tireness"); - /* x1ec_maxLeanAngle */ - x1ec_maxLeanAngle = __dna_docin.readFloat("x1ec_maxLeanAngle"); - /* x1f0_tireToMarbleThresholdSpeed */ - x1f0_tireToMarbleThresholdSpeed = __dna_docin.readFloat("x1f0_tireToMarbleThresholdSpeed"); - /* x1f4_marbleToTireThresholdSpeed */ - x1f4_marbleToTireThresholdSpeed = __dna_docin.readFloat("x1f4_marbleToTireThresholdSpeed"); - /* x1f8_forceToLeanGain */ - x1f8_forceToLeanGain = __dna_docin.readFloat("x1f8_forceToLeanGain"); - /* x1fc_leanTrackingGain */ - x1fc_leanTrackingGain = __dna_docin.readFloat("x1fc_leanTrackingGain"); - /* x74_ballCameraAnglePerSecond */ - x74_ballCameraAnglePerSecond = __dna_docin.readFloat("x74_ballCameraAnglePerSecond"); - /* x78_ballCameraOffset */ - x78_ballCameraOffset = __dna_docin.readVec3f("x78_ballCameraOffset"); - /* x84_ballCameraMinSpeedDistance */ - x84_ballCameraMinSpeedDistance = __dna_docin.readFloat("x84_ballCameraMinSpeedDistance"); - /* x88_ballCameraMaxSpeedDistance */ - x88_ballCameraMaxSpeedDistance = __dna_docin.readFloat("x88_ballCameraMaxSpeedDistance"); - /* x8c_ballCameraBackwardsDistance */ - x8c_ballCameraBackwardsDistance = __dna_docin.readFloat("x8c_ballCameraBackwardsDistance"); - /* x90_ */ - x90_ = __dna_docin.readFloat("x90_"); - /* x94_ballCameraSpringConstant */ - x94_ballCameraSpringConstant = __dna_docin.readFloat("x94_ballCameraSpringConstant"); - /* x98_ballCameraSpringMax */ - x98_ballCameraSpringMax = __dna_docin.readFloat("x98_ballCameraSpringMax"); - /* x9c_ballCameraSpringTardis */ - x9c_ballCameraSpringTardis = __dna_docin.readFloat("x9c_ballCameraSpringTardis"); - /* xa0_ballCameraCentroidSpringConstant */ - xa0_ballCameraCentroidSpringConstant = __dna_docin.readFloat("xa0_ballCameraCentroidSpringConstant"); - /* xa4_ballCameraCentroidSpringMax */ - xa4_ballCameraCentroidSpringMax = __dna_docin.readFloat("xa4_ballCameraCentroidSpringMax"); - /* xa8_ballCameraCentroidSpringTardis */ - xa8_ballCameraCentroidSpringTardis = __dna_docin.readFloat("xa8_ballCameraCentroidSpringTardis"); - /* xac_ballCameraCentroidDistanceSpringConstant */ - xac_ballCameraCentroidDistanceSpringConstant = __dna_docin.readFloat("xac_ballCameraCentroidDistanceSpringConstant"); - /* xb0_ballCameraCentroidDistanceSpringMax */ - xb0_ballCameraCentroidDistanceSpringMax = __dna_docin.readFloat("xb0_ballCameraCentroidDistanceSpringMax"); - /* xb4_ballCameraCentroidDistanceSpringTardis */ - xb4_ballCameraCentroidDistanceSpringTardis = __dna_docin.readFloat("xb4_ballCameraCentroidDistanceSpringTardis"); - /* xb8_ballCameraLookAtSpringConstant */ - xb8_ballCameraLookAtSpringConstant = __dna_docin.readFloat("xb8_ballCameraLookAtSpringConstant"); - /* xbc_ballCameraLookAtSpringMax */ - xbc_ballCameraLookAtSpringMax = __dna_docin.readFloat("xbc_ballCameraLookAtSpringMax"); - /* xc0_ballCameraLookAtSpringTardis */ - xc0_ballCameraLookAtSpringTardis = __dna_docin.readFloat("xc0_ballCameraLookAtSpringTardis"); - /* x154_ */ - x154_ = __dna_docin.readFloat("x154_"); - /* x15c_ */ - x15c_ = __dna_docin.readFloat("x15c_"); - /* x160_ */ - x160_ = __dna_docin.readFloat("x160_"); - /* x164_ */ - x164_ = __dna_docin.readFloat("x164_"); - /* x168_ */ - x168_ = __dna_docin.readFloat("x168_"); - /* x16c_ */ - x16c_ = __dna_docin.readFloat("x16c_"); - /* x170_conservativeDoorCamDistance */ - x170_conservativeDoorCamDistance = __dna_docin.readFloat("x170_conservativeDoorCamDistance"); - /* x174_ */ - x174_ = __dna_docin.readFloat("x174_"); - /* x178_ballCameraChaseElevation */ - x178_ballCameraChaseElevation = __dna_docin.readFloat("x178_ballCameraChaseElevation"); - /* x17c_ballCameraChaseDampenAngle */ - x17c_ballCameraChaseDampenAngle = __dna_docin.readFloat("x17c_ballCameraChaseDampenAngle"); - /* x180_ballCameraChaseDistance */ - x180_ballCameraChaseDistance = __dna_docin.readFloat("x180_ballCameraChaseDistance"); - /* x184_ballCameraChaseYawSpeed */ - x184_ballCameraChaseYawSpeed = __dna_docin.readFloat("x184_ballCameraChaseYawSpeed"); - /* x188_ballCameraChaseAnglePerSecond */ - x188_ballCameraChaseAnglePerSecond = __dna_docin.readFloat("x188_ballCameraChaseAnglePerSecond"); - /* x18c_ballCameraChaseLookAtOffset */ - x18c_ballCameraChaseLookAtOffset = __dna_docin.readVec3f("x18c_ballCameraChaseLookAtOffset"); - /* x198_ballCameraChaseSpringConstant */ - x198_ballCameraChaseSpringConstant = __dna_docin.readFloat("x198_ballCameraChaseSpringConstant"); - /* x19c_ballCameraChaseSpringMax */ - x19c_ballCameraChaseSpringMax = __dna_docin.readFloat("x19c_ballCameraChaseSpringMax"); - /* x1a0_ballCameraChaseSpringTardis */ - x1a0_ballCameraChaseSpringTardis = __dna_docin.readFloat("x1a0_ballCameraChaseSpringTardis"); - /* x1a4_ballCameraBoostElevation */ - x1a4_ballCameraBoostElevation = __dna_docin.readFloat("x1a4_ballCameraBoostElevation"); - /* x1a8_ballCameraBoostDampenAngle */ - x1a8_ballCameraBoostDampenAngle = __dna_docin.readFloat("x1a8_ballCameraBoostDampenAngle"); - /* x1ac_ballCameraBoostDistance */ - x1ac_ballCameraBoostDistance = __dna_docin.readFloat("x1ac_ballCameraBoostDistance"); - /* x1b0_ballCameraBoostYawSpeed */ - x1b0_ballCameraBoostYawSpeed = __dna_docin.readFloat("x1b0_ballCameraBoostYawSpeed"); - /* x1b4_ballCameraBoostAnglePerSecond */ - x1b4_ballCameraBoostAnglePerSecond = __dna_docin.readFloat("x1b4_ballCameraBoostAnglePerSecond"); - /* x1b8_ballCameraBoostLookAtOffset */ - x1b8_ballCameraBoostLookAtOffset = __dna_docin.readVec3f("x1b8_ballCameraBoostLookAtOffset"); - /* x1c4_ballCameraBoostSpringConstant */ - x1c4_ballCameraBoostSpringConstant = __dna_docin.readFloat("x1c4_ballCameraBoostSpringConstant"); - /* x1c8_ballCameraBoostSpringMax */ - x1c8_ballCameraBoostSpringMax = __dna_docin.readFloat("x1c8_ballCameraBoostSpringMax"); - /* x1cc_ballCameraBoostSpringTardis */ - x1cc_ballCameraBoostSpringTardis = __dna_docin.readFloat("x1cc_ballCameraBoostSpringTardis"); - /* x1d0_ballCameraControlDistance */ - x1d0_ballCameraControlDistance = __dna_docin.readFloat("x1d0_ballCameraControlDistance"); - /* x1d4_ */ - x1d4_ = __dna_docin.readFloat("x1d4_"); - /* x1d8_ */ - x1d8_ = __dna_docin.readFloat("x1d8_"); - /* x1e4_leftStickDivisor */ - x1e4_leftStickDivisor = __dna_docin.readFloat("x1e4_leftStickDivisor"); - /* x1e8_rightStickDivisor */ - x1e8_rightStickDivisor = __dna_docin.readFloat("x1e8_rightStickDivisor"); - /* x200_ */ - x200_ = __dna_docin.readFloat("x200_"); - /* x204_ballTouchRadius */ - x204_ballTouchRadius = __dna_docin.readFloat("x204_ballTouchRadius"); - /* x20c_boostBallDrainTime */ - x20c_boostBallDrainTime = __dna_docin.readFloat("x20c_boostBallDrainTime"); - /* x218_boostBallMinChargeTime */ - x218_boostBallMinChargeTime = __dna_docin.readFloat("x218_boostBallMinChargeTime"); - /* x21c_boostBallMinRelativeSpeedForDamage */ - x21c_boostBallMinRelativeSpeedForDamage = __dna_docin.readFloat("x21c_boostBallMinRelativeSpeedForDamage"); - /* x220_boostBallChargeTime0 */ - x220_boostBallChargeTime0 = __dna_docin.readFloat("x220_boostBallChargeTime0"); - /* x224_boostBallChargeTime1 */ - x224_boostBallChargeTime1 = __dna_docin.readFloat("x224_boostBallChargeTime1"); - /* x210_boostBallMaxChargeTime */ - x228_boostBallChargeTime2 = x210_boostBallMaxChargeTime = __dna_docin.readFloat("x210_boostBallMaxChargeTime"); - /* x22c_boostBallIncrementalSpeed0 */ - x22c_boostBallIncrementalSpeed0 = __dna_docin.readFloat("x22c_boostBallIncrementalSpeed0"); - /* x230_boostBallIncrementalSpeed1 */ - x230_boostBallIncrementalSpeed1 = __dna_docin.readFloat("x230_boostBallIncrementalSpeed1"); - /* x234_boostBallIncrementalSpeed2 */ - x234_boostBallIncrementalSpeed2 = __dna_docin.readFloat("x234_boostBallIncrementalSpeed2"); -} - -template <> -void CTweakBall::Enumerate(typename WriteYaml::StreamT& __dna_docout) { - /* x4_maxTranslationAcceleration */ - if (auto v = __dna_docout.enterSubVector("x4_maxTranslationAcceleration")) { - /* x4_maxTranslationAcceleration[0] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[0]); - /* x4_maxTranslationAcceleration[1] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[1]); - /* x4_maxTranslationAcceleration[2] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[2]); - /* x4_maxTranslationAcceleration[3] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[3]); - /* x4_maxTranslationAcceleration[4] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[4]); - /* x4_maxTranslationAcceleration[5] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[5]); - /* x4_maxTranslationAcceleration[6] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[6]); - /* x4_maxTranslationAcceleration[7] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[7]); - } - /* x24_translationFriction */ - if (auto v = __dna_docout.enterSubVector("x24_translationFriction")) { - /* x24_translationFriction[0] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[0]); - /* x24_translationFriction[1] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[1]); - /* x24_translationFriction[2] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[2]); - /* x24_translationFriction[3] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[3]); - /* x24_translationFriction[4] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[4]); - /* x24_translationFriction[5] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[5]); - /* x24_translationFriction[6] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[6]); - /* x24_translationFriction[7] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[7]); - } - /* x44_translationMaxSpeed */ - if (auto v = __dna_docout.enterSubVector("x44_translationMaxSpeed")) { - /* x44_translationMaxSpeed[0] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[0]); - /* x44_translationMaxSpeed[1] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[1]); - /* x44_translationMaxSpeed[2] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[2]); - /* x44_translationMaxSpeed[3] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[3]); - /* x44_translationMaxSpeed[4] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[4]); - /* x44_translationMaxSpeed[5] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[5]); - /* x44_translationMaxSpeed[6] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[6]); - /* x44_translationMaxSpeed[7] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[7]); - } - /* x64_ */ - __dna_docout.writeFloat("x64_", x64_); - /* x68_ */ - __dna_docout.writeFloat("x68_", x68_); - /* x6c_ */ - __dna_docout.writeFloat("x6c_", x6c_); - /* x70_ */ - __dna_docout.writeFloat("x70_", x70_); - /* xc4_ballForwardBrakingAcceleration */ - if (auto v = __dna_docout.enterSubVector("xc4_ballForwardBrakingAcceleration")) { - /* xc4_ballForwardBrakingAcceleration[0] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[0]); - /* xc4_ballForwardBrakingAcceleration[1] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[1]); - /* xc4_ballForwardBrakingAcceleration[2] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[2]); - /* xc4_ballForwardBrakingAcceleration[3] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[3]); - /* xc4_ballForwardBrakingAcceleration[4] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[4]); - /* xc4_ballForwardBrakingAcceleration[5] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[5]); - /* xc4_ballForwardBrakingAcceleration[6] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[6]); - /* xc4_ballForwardBrakingAcceleration[7] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[7]); - } - /* xe4_ballGravity */ - __dna_docout.writeFloat("xe4_ballGravity", xe4_ballGravity); - /* xe8_ballWaterGravity */ - __dna_docout.writeFloat("xe8_ballWaterGravity", xe8_ballWaterGravity); - /* x14c_ */ - __dna_docout.writeFloat("x14c_", x14c_); - /* x150_ */ - __dna_docout.writeFloat("x150_", x150_); - /* x158_ */ - __dna_docout.writeFloat("x158_", x158_); - /* x1dc_minimumAlignmentSpeed */ - __dna_docout.writeFloat("x1dc_minimumAlignmentSpeed", x1dc_minimumAlignmentSpeed); - /* x1e0_tireness */ - __dna_docout.writeFloat("x1e0_tireness", x1e0_tireness); - /* x1ec_maxLeanAngle */ - __dna_docout.writeFloat("x1ec_maxLeanAngle", x1ec_maxLeanAngle); - /* x1f0_tireToMarbleThresholdSpeed */ - __dna_docout.writeFloat("x1f0_tireToMarbleThresholdSpeed", x1f0_tireToMarbleThresholdSpeed); - /* x1f4_marbleToTireThresholdSpeed */ - __dna_docout.writeFloat("x1f4_marbleToTireThresholdSpeed", x1f4_marbleToTireThresholdSpeed); - /* x1f8_forceToLeanGain */ - __dna_docout.writeFloat("x1f8_forceToLeanGain", x1f8_forceToLeanGain); - /* x1fc_leanTrackingGain */ - __dna_docout.writeFloat("x1fc_leanTrackingGain", x1fc_leanTrackingGain); - /* x74_ballCameraAnglePerSecond */ - __dna_docout.writeFloat("x74_ballCameraAnglePerSecond", x74_ballCameraAnglePerSecond); - /* x78_ballCameraOffset */ - __dna_docout.writeVec3f("x78_ballCameraOffset", x78_ballCameraOffset); - /* x84_ballCameraMinSpeedDistance */ - __dna_docout.writeFloat("x84_ballCameraMinSpeedDistance", x84_ballCameraMinSpeedDistance); - /* x88_ballCameraMaxSpeedDistance */ - __dna_docout.writeFloat("x88_ballCameraMaxSpeedDistance", x88_ballCameraMaxSpeedDistance); - /* x8c_ballCameraBackwardsDistance */ - __dna_docout.writeFloat("x8c_ballCameraBackwardsDistance", x8c_ballCameraBackwardsDistance); - /* x90_ */ - __dna_docout.writeFloat("x90_", x90_); - /* x94_ballCameraSpringConstant */ - __dna_docout.writeFloat("x94_ballCameraSpringConstant", x94_ballCameraSpringConstant); - /* x98_ballCameraSpringMax */ - __dna_docout.writeFloat("x98_ballCameraSpringMax", x98_ballCameraSpringMax); - /* x9c_ballCameraSpringTardis */ - __dna_docout.writeFloat("x9c_ballCameraSpringTardis", x9c_ballCameraSpringTardis); - /* xa0_ballCameraCentroidSpringConstant */ - __dna_docout.writeFloat("xa0_ballCameraCentroidSpringConstant", xa0_ballCameraCentroidSpringConstant); - /* xa4_ballCameraCentroidSpringMax */ - __dna_docout.writeFloat("xa4_ballCameraCentroidSpringMax", xa4_ballCameraCentroidSpringMax); - /* xa8_ballCameraCentroidSpringTardis */ - __dna_docout.writeFloat("xa8_ballCameraCentroidSpringTardis", xa8_ballCameraCentroidSpringTardis); - /* xac_ballCameraCentroidDistanceSpringConstant */ - __dna_docout.writeFloat("xac_ballCameraCentroidDistanceSpringConstant", xac_ballCameraCentroidDistanceSpringConstant); - /* xb0_ballCameraCentroidDistanceSpringMax */ - __dna_docout.writeFloat("xb0_ballCameraCentroidDistanceSpringMax", xb0_ballCameraCentroidDistanceSpringMax); - /* xb4_ballCameraCentroidDistanceSpringTardis */ - __dna_docout.writeFloat("xb4_ballCameraCentroidDistanceSpringTardis", xb4_ballCameraCentroidDistanceSpringTardis); - /* xb8_ballCameraLookAtSpringConstant */ - __dna_docout.writeFloat("xb8_ballCameraLookAtSpringConstant", xb8_ballCameraLookAtSpringConstant); - /* xbc_ballCameraLookAtSpringMax */ - __dna_docout.writeFloat("xbc_ballCameraLookAtSpringMax", xbc_ballCameraLookAtSpringMax); - /* xc0_ballCameraLookAtSpringTardis */ - __dna_docout.writeFloat("xc0_ballCameraLookAtSpringTardis", xc0_ballCameraLookAtSpringTardis); - /* x154_ */ - __dna_docout.writeFloat("x154_", x154_); - /* x15c_ */ - __dna_docout.writeFloat("x15c_", x15c_); - /* x160_ */ - __dna_docout.writeFloat("x160_", x160_); - /* x164_ */ - __dna_docout.writeFloat("x164_", x164_); - /* x168_ */ - __dna_docout.writeFloat("x168_", x168_); - /* x16c_ */ - __dna_docout.writeFloat("x16c_", x16c_); - /* x170_conservativeDoorCamDistance */ - __dna_docout.writeFloat("x170_conservativeDoorCamDistance", x170_conservativeDoorCamDistance); - /* x174_ */ - __dna_docout.writeFloat("x174_", x174_); - /* x178_ballCameraChaseElevation */ - __dna_docout.writeFloat("x178_ballCameraChaseElevation", x178_ballCameraChaseElevation); - /* x17c_ballCameraChaseDampenAngle */ - __dna_docout.writeFloat("x17c_ballCameraChaseDampenAngle", x17c_ballCameraChaseDampenAngle); - /* x180_ballCameraChaseDistance */ - __dna_docout.writeFloat("x180_ballCameraChaseDistance", x180_ballCameraChaseDistance); - /* x184_ballCameraChaseYawSpeed */ - __dna_docout.writeFloat("x184_ballCameraChaseYawSpeed", x184_ballCameraChaseYawSpeed); - /* x188_ballCameraChaseAnglePerSecond */ - __dna_docout.writeFloat("x188_ballCameraChaseAnglePerSecond", x188_ballCameraChaseAnglePerSecond); - /* x18c_ballCameraChaseLookAtOffset */ - __dna_docout.writeVec3f("x18c_ballCameraChaseLookAtOffset", x18c_ballCameraChaseLookAtOffset); - /* x198_ballCameraChaseSpringConstant */ - __dna_docout.writeFloat("x198_ballCameraChaseSpringConstant", x198_ballCameraChaseSpringConstant); - /* x19c_ballCameraChaseSpringMax */ - __dna_docout.writeFloat("x19c_ballCameraChaseSpringMax", x19c_ballCameraChaseSpringMax); - /* x1a0_ballCameraChaseSpringTardis */ - __dna_docout.writeFloat("x1a0_ballCameraChaseSpringTardis", x1a0_ballCameraChaseSpringTardis); - /* x1a4_ballCameraBoostElevation */ - __dna_docout.writeFloat("x1a4_ballCameraBoostElevation", x1a4_ballCameraBoostElevation); - /* x1a8_ballCameraBoostDampenAngle */ - __dna_docout.writeFloat("x1a8_ballCameraBoostDampenAngle", x1a8_ballCameraBoostDampenAngle); - /* x1ac_ballCameraBoostDistance */ - __dna_docout.writeFloat("x1ac_ballCameraBoostDistance", x1ac_ballCameraBoostDistance); - /* x1b0_ballCameraBoostYawSpeed */ - __dna_docout.writeFloat("x1b0_ballCameraBoostYawSpeed", x1b0_ballCameraBoostYawSpeed); - /* x1b4_ballCameraBoostAnglePerSecond */ - __dna_docout.writeFloat("x1b4_ballCameraBoostAnglePerSecond", x1b4_ballCameraBoostAnglePerSecond); - /* x1b8_ballCameraBoostLookAtOffset */ - __dna_docout.writeVec3f("x1b8_ballCameraBoostLookAtOffset", x1b8_ballCameraBoostLookAtOffset); - /* x1c4_ballCameraBoostSpringConstant */ - __dna_docout.writeFloat("x1c4_ballCameraBoostSpringConstant", x1c4_ballCameraBoostSpringConstant); - /* x1c8_ballCameraBoostSpringMax */ - __dna_docout.writeFloat("x1c8_ballCameraBoostSpringMax", x1c8_ballCameraBoostSpringMax); - /* x1cc_ballCameraBoostSpringTardis */ - __dna_docout.writeFloat("x1cc_ballCameraBoostSpringTardis", x1cc_ballCameraBoostSpringTardis); - /* x1d0_ballCameraControlDistance */ - __dna_docout.writeFloat("x1d0_ballCameraControlDistance", x1d0_ballCameraControlDistance); - /* x1d4_ */ - __dna_docout.writeFloat("x1d4_", x1d4_); - /* x1d8_ */ - __dna_docout.writeFloat("x1d8_", x1d8_); - /* x1e4_leftStickDivisor */ - __dna_docout.writeFloat("x1e4_leftStickDivisor", x1e4_leftStickDivisor); - /* x1e8_rightStickDivisor */ - __dna_docout.writeFloat("x1e8_rightStickDivisor", x1e8_rightStickDivisor); - /* x200_ */ - __dna_docout.writeFloat("x200_", x200_); - /* x204_ballTouchRadius */ - __dna_docout.writeFloat("x204_ballTouchRadius", x204_ballTouchRadius); - /* x20c_boostBallDrainTime */ - __dna_docout.writeFloat("x20c_boostBallDrainTime", x20c_boostBallDrainTime); - /* x218_boostBallMinChargeTime */ - __dna_docout.writeFloat("x218_boostBallMinChargeTime", x218_boostBallMinChargeTime); - /* x21c_boostBallMinRelativeSpeedForDamage */ - __dna_docout.writeFloat("x21c_boostBallMinRelativeSpeedForDamage", x21c_boostBallMinRelativeSpeedForDamage); - /* x220_boostBallChargeTime0 */ - __dna_docout.writeFloat("x220_boostBallChargeTime0", x220_boostBallChargeTime0); - /* x224_boostBallChargeTime1 */ - __dna_docout.writeFloat("x224_boostBallChargeTime1", x224_boostBallChargeTime1); - /* x210_boostBallMaxChargeTime */ - __dna_docout.writeFloat("x210_boostBallMaxChargeTime", x210_boostBallMaxChargeTime); - /* x22c_boostBallIncrementalSpeed0 */ - __dna_docout.writeFloat("x22c_boostBallIncrementalSpeed0", x22c_boostBallIncrementalSpeed0); - /* x230_boostBallIncrementalSpeed1 */ - __dna_docout.writeFloat("x230_boostBallIncrementalSpeed1", x230_boostBallIncrementalSpeed1); - /* x234_boostBallIncrementalSpeed2 */ - __dna_docout.writeFloat("x234_boostBallIncrementalSpeed2", x234_boostBallIncrementalSpeed2); -} - -std::string_view CTweakBall::DNAType() { return "DataSpec::DNAMP1::CTweakBall"sv; } - -template <> -void CTweakBall::Enumerate(typename BinarySize::StreamT& s) { - s += 456; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakBall.hpp b/DataSpec/DNAMP1/Tweaks/CTweakBall.hpp deleted file mode 100644 index 3e0f94be3..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakBall.hpp +++ /dev/null @@ -1,216 +0,0 @@ -#pragma once - -#include "../../DNACommon/Tweaks/ITweakBall.hpp" -#include "zeus/CVector3f.hpp" - -namespace DataSpec::DNAMP1 { -struct CTweakBall final : public ITweakBall { - AT_DECL_EXPLICIT_DNA_YAML - Value x4_maxTranslationAcceleration[8]; - Value x24_translationFriction[8]; - Value x44_translationMaxSpeed[8]; - Value x64_; - Value x68_; - Value x6c_; - Value x70_; - Value x74_ballCameraAnglePerSecond; - Value x78_ballCameraOffset; - Value x84_ballCameraMinSpeedDistance; - Value x88_ballCameraMaxSpeedDistance; - Value x8c_ballCameraBackwardsDistance; - Value x90_; - Value x94_ballCameraSpringConstant; - Value x98_ballCameraSpringMax; - Value x9c_ballCameraSpringTardis; - Value xa0_ballCameraCentroidSpringConstant; - Value xa4_ballCameraCentroidSpringMax; - Value xa8_ballCameraCentroidSpringTardis; - Value xac_ballCameraCentroidDistanceSpringConstant; - Value xb0_ballCameraCentroidDistanceSpringMax; - Value xb4_ballCameraCentroidDistanceSpringTardis; - Value xb8_ballCameraLookAtSpringConstant; - Value xbc_ballCameraLookAtSpringMax; - Value xc0_ballCameraLookAtSpringTardis; - Value xc4_ballForwardBrakingAcceleration[8]; - Value xe4_ballGravity; - Value xe8_ballWaterGravity; - float xec_ = 10000.f; - float xf0_ = 1000.f; - float xf4_ = 40000.f; - float xf8_ = 40000.f; - float xfc_ = 40000.f; - float x100_ = 40000.f; - float x104_ = 40000.f; - float x108_ = 40000.f; - float x10c_ = 10000.f; - float x110_ = 1000.f; - float x114_ = 40000.f; - float x118_ = 40000.f; - float x11c_ = 40000.f; - float x120_ = 40000.f; - float x124_ = 40000.f; - float x128_ = 40000.f; - float x12c_ballSlipFactor[8] = {10000.f, 10000.f, 1000.f, 10000.f, 2000.f, 2000.f, 2000.f, 2000.f}; - Value x14c_; - Value x150_; - Value x158_; - Value x154_; - Value x15c_; - Value x160_; - Value x164_; - Value x168_; - Value x16c_; - Value x170_conservativeDoorCamDistance; - Value x174_; - Value x178_ballCameraChaseElevation; - Value x17c_ballCameraChaseDampenAngle; - Value x180_ballCameraChaseDistance; - Value x184_ballCameraChaseYawSpeed; - Value x188_ballCameraChaseAnglePerSecond; - Value x18c_ballCameraChaseLookAtOffset; - Value x198_ballCameraChaseSpringConstant; - Value x19c_ballCameraChaseSpringMax; - Value x1a0_ballCameraChaseSpringTardis; - Value x1a4_ballCameraBoostElevation; - Value x1a8_ballCameraBoostDampenAngle; - Value x1ac_ballCameraBoostDistance; - Value x1b0_ballCameraBoostYawSpeed; - Value x1b4_ballCameraBoostAnglePerSecond; - Value x1b8_ballCameraBoostLookAtOffset; - Value x1c4_ballCameraBoostSpringConstant; - Value x1c8_ballCameraBoostSpringMax; - Value x1cc_ballCameraBoostSpringTardis; - Value x1d0_ballCameraControlDistance; - Value x1d4_; - Value x1d8_; - Value x1dc_minimumAlignmentSpeed; - Value x1e0_tireness; - Value x1ec_maxLeanAngle; - Value x1f0_tireToMarbleThresholdSpeed; - Value x1f4_marbleToTireThresholdSpeed; - Value x1f8_forceToLeanGain; - Value x1fc_leanTrackingGain; - Value x1e4_leftStickDivisor; - Value x1e8_rightStickDivisor; - Value x200_; - Value x204_ballTouchRadius; - float x208_; - Value x20c_boostBallDrainTime; - Value x218_boostBallMinChargeTime; - Value x21c_boostBallMinRelativeSpeedForDamage; - Value x220_boostBallChargeTime0; - Value x224_boostBallChargeTime1; - float x228_boostBallChargeTime2; - Value x210_boostBallMaxChargeTime; - Value x22c_boostBallIncrementalSpeed0; - Value x230_boostBallIncrementalSpeed1; - Value x234_boostBallIncrementalSpeed2; - - CTweakBall() = default; - CTweakBall(athena::io::IStreamReader& r) { - this->read(r); - x6c_ = -x6c_; - x70_ = -x70_; - x74_ballCameraAnglePerSecond = zeus::degToRad(x74_ballCameraAnglePerSecond); - x90_ = zeus::degToRad(x90_); - xe4_ballGravity = -xe4_ballGravity; - xe8_ballWaterGravity = -xe8_ballWaterGravity; - x15c_ = zeus::degToRad(x15c_); - x16c_ = zeus::degToRad(x16c_); - x174_ = zeus::degToRad(x174_); - x17c_ballCameraChaseDampenAngle = zeus::degToRad(x17c_ballCameraChaseDampenAngle); - x184_ballCameraChaseYawSpeed = zeus::degToRad(x184_ballCameraChaseYawSpeed); - x188_ballCameraChaseAnglePerSecond = zeus::degToRad(x188_ballCameraChaseAnglePerSecond); - x1a8_ballCameraBoostDampenAngle = zeus::degToRad(x1a8_ballCameraBoostDampenAngle); - x1b0_ballCameraBoostYawSpeed = zeus::degToRad(x1b0_ballCameraBoostYawSpeed); - x1b4_ballCameraBoostAnglePerSecond = zeus::degToRad(x1b4_ballCameraBoostAnglePerSecond); - x1ec_maxLeanAngle = zeus::degToRad(x1ec_maxLeanAngle); - } - - float GetMaxBallTranslationAcceleration(int s) const override { return x4_maxTranslationAcceleration[s]; } - float GetBallTranslationFriction(int s) const override { return x24_translationFriction[s]; } - float GetBallTranslationMaxSpeed(int s) const override { return x44_translationMaxSpeed[s]; } - float GetBallCameraElevation() const override { return 2.736f; } - float GetBallCameraAnglePerSecond() const override { return x74_ballCameraAnglePerSecond; } - const zeus::CVector3f& GetBallCameraOffset() const override { return x78_ballCameraOffset; } - float GetBallCameraMinSpeedDistance() const override { return x84_ballCameraMinSpeedDistance; } - float GetBallCameraMaxSpeedDistance() const override { return x88_ballCameraMaxSpeedDistance; } - float GetBallCameraBackwardsDistance() const override { return x8c_ballCameraBackwardsDistance; } - float GetBallCameraSpringConstant() const override { return x94_ballCameraSpringConstant; } - float GetBallCameraSpringMax() const override { return x98_ballCameraSpringMax; } - float GetBallCameraSpringTardis() const override { return x9c_ballCameraSpringTardis; } - float GetBallCameraCentroidSpringConstant() const override { return xa0_ballCameraCentroidSpringConstant; } - float GetBallCameraCentroidSpringMax() const override { return xa4_ballCameraCentroidSpringMax; } - float GetBallCameraCentroidSpringTardis() const override { return xa8_ballCameraCentroidSpringTardis; } - float GetBallCameraCentroidDistanceSpringConstant() const override { - return xac_ballCameraCentroidDistanceSpringConstant; - } - float GetBallCameraCentroidDistanceSpringMax() const override { return xb0_ballCameraCentroidDistanceSpringMax; } - float GetBallCameraCentroidDistanceSpringTardis() const override { - return xb4_ballCameraCentroidDistanceSpringTardis; - } - float GetBallCameraLookAtSpringConstant() const override { return xb8_ballCameraLookAtSpringConstant; } - float GetBallCameraLookAtSpringMax() const override { return xbc_ballCameraLookAtSpringMax; } - float GetBallCameraLookAtSpringTardis() const override { return xc0_ballCameraLookAtSpringTardis; } - float GetBallForwardBrakingAcceleration(int s) const override { return xc4_ballForwardBrakingAcceleration[s]; } - float GetBallGravity() const override { return xe4_ballGravity; } - float GetBallWaterGravity() const override { return xe8_ballWaterGravity; } - float GetBallSlipFactor(int s) const override { return x12c_ballSlipFactor[s]; } - float GetConservativeDoorCameraDistance() const override { return x170_conservativeDoorCamDistance; } - float GetBallCameraChaseElevation() const override { return x178_ballCameraChaseElevation; } - float GetBallCameraChaseDampenAngle() const override { return x17c_ballCameraChaseDampenAngle; } - float GetBallCameraChaseDistance() const override { return x180_ballCameraChaseDistance; } - float GetBallCameraChaseYawSpeed() const override { return x184_ballCameraChaseYawSpeed; } - float GetBallCameraChaseAnglePerSecond() const override { return x188_ballCameraChaseAnglePerSecond; } - const zeus::CVector3f& GetBallCameraChaseLookAtOffset() const override { return x18c_ballCameraChaseLookAtOffset; } - float GetBallCameraChaseSpringConstant() const override { return x198_ballCameraChaseSpringConstant; } - float GetBallCameraChaseSpringMax() const override { return x19c_ballCameraChaseSpringMax; } - float GetBallCameraChaseSpringTardis() const override { return x1a0_ballCameraChaseSpringTardis; } - float GetBallCameraBoostElevation() const override { return x1a4_ballCameraBoostElevation; } - float GetBallCameraBoostDampenAngle() const override { return x1a8_ballCameraBoostDampenAngle; } - float GetBallCameraBoostDistance() const override { return x1ac_ballCameraBoostDistance; } - float GetBallCameraBoostYawSpeed() const override { return x1b0_ballCameraBoostYawSpeed; } - float GetBallCameraBoostAnglePerSecond() const override { return x1b4_ballCameraBoostAnglePerSecond; } - const zeus::CVector3f& GetBallCameraBoostLookAtOffset() const override { return x1b8_ballCameraBoostLookAtOffset; } - float GetBallCameraBoostSpringConstant() const override { return x1c4_ballCameraBoostSpringConstant; } - float GetBallCameraBoostSpringMax() const override { return x1c8_ballCameraBoostSpringMax; } - float GetBallCameraBoostSpringTardis() const override { return x1cc_ballCameraBoostSpringTardis; } - float GetBallCameraControlDistance() const override { return x1d0_ballCameraControlDistance; } - float GetMinimumAlignmentSpeed() const override { return x1dc_minimumAlignmentSpeed; } - float GetTireness() const override { return x1e0_tireness; } - float GetMaxLeanAngle() const override { return x1ec_maxLeanAngle; } - float GetTireToMarbleThresholdSpeed() const override { return x1f0_tireToMarbleThresholdSpeed; } - float GetMarbleToTireThresholdSpeed() const override { return x1f4_marbleToTireThresholdSpeed; } - float GetForceToLeanGain() const override { return x1f8_forceToLeanGain; } - float GetLeanTrackingGain() const override { return x1fc_leanTrackingGain; } - float GetLeftStickDivisor() const override { return x1e4_leftStickDivisor; } - float GetRightStickDivisor() const override { return x1e8_rightStickDivisor; } - float GetBallTouchRadius() const override { return x204_ballTouchRadius; } - float GetBoostBallDrainTime() const override { return x20c_boostBallDrainTime; } - float GetBoostBallMaxChargeTime() const override { return x210_boostBallMaxChargeTime; } - float GetBoostBallMinChargeTime() const override { return x218_boostBallMinChargeTime; } - float GetBoostBallMinRelativeSpeedForDamage() const override { return x21c_boostBallMinRelativeSpeedForDamage; } - float GetBoostBallChargeTimeTable(int i) const override { - switch (i) { - default: - case 0: - return x220_boostBallChargeTime0; - case 1: - return x224_boostBallChargeTime1; - case 2: - return x228_boostBallChargeTime2; - } - } - float GetBoostBallIncrementalSpeedTable(int i) const override { - switch (i) { - default: - case 0: - return x22c_boostBallIncrementalSpeed0; - case 1: - return x230_boostBallIncrementalSpeed1; - case 2: - return x234_boostBallIncrementalSpeed2; - } - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakCameraBob.hpp b/DataSpec/DNAMP1/Tweaks/CTweakCameraBob.hpp deleted file mode 100644 index 743705047..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakCameraBob.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" - -namespace DataSpec::DNAMP1 { -struct CTweakCameraBob : BigDNA { - AT_DECL_DNA_YAML - Value cameraBobExtentX; - Value cameraBobExtentY; - Value cameraBobPeriod; - Value orbitScale; - Value maxOrbitScale; - Value slowSpeedPeriodScale; - Value targetMagnitudeTrackingRate; - Value landingBobSpringConstant; - Value viewWanderRadius; - Value viewWanderSpeedMin; - Value viewWanderSpeedMax; - Value viewWanderRollVariation; - Value gunBobMagnitude; - Value helmetBobMagnitude; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakGame.hpp b/DataSpec/DNAMP1/Tweaks/CTweakGame.hpp deleted file mode 100644 index da813167b..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakGame.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/Tweaks/ITweakGame.hpp" - -namespace hecl { -class CVar; -} // namespace hecl - -namespace DataSpec::DNAMP1 { - -#define DEFINE_CVAR_GLOBAL(name) extern hecl::CVar* tw_##name; - -DEFINE_CVAR_GLOBAL(WorldPrefix); -DEFINE_CVAR_GLOBAL(FieldOfView); -DEFINE_CVAR_GLOBAL(SplashScreensDisabled); -DEFINE_CVAR_GLOBAL(PressStartDelay); -DEFINE_CVAR_GLOBAL(WavecapIntensityNormal); -DEFINE_CVAR_GLOBAL(WavecapIntensityPoison); -DEFINE_CVAR_GLOBAL(WavecapIntensityLava); -DEFINE_CVAR_GLOBAL(RippleIntensityNormal); -DEFINE_CVAR_GLOBAL(RippleIntensityPoison); -DEFINE_CVAR_GLOBAL(RippleIntensityLava); -DEFINE_CVAR_GLOBAL(FluidEnvBumpScale); -DEFINE_CVAR_GLOBAL(WaterFogDistanceBase); -DEFINE_CVAR_GLOBAL(WaterFogDistanceRange); -DEFINE_CVAR_GLOBAL(GravityWaterFogDistanceBase); -DEFINE_CVAR_GLOBAL(GravityWaterFogDistanceRange); -DEFINE_CVAR_GLOBAL(HardModeDamageMult); -DEFINE_CVAR_GLOBAL(HardModeWeaponMult); - -#undef DEFINE_CVAR_GLOBAL - -struct CTweakGame final : ITweakGame { - AT_DECL_DNA_YAML - String<-1> x4_worldPrefix; - String<-1> x14_defaultRoom; - Value x24_fov; - Value x28_unknown1; - Value x29_unknown2; - Value x2a_unknown3; - Value x2b_splashScreensDisabled; - Value x2c_unknown5; - Value x30_pressStartDelay; - Value x34_wavecapIntensityNormal; - Value x38_wavecapIntensityPoison; - Value x3c_wavecapIntensityLava; - Value x40_rippleIntensityNormal; - Value x44_rippleIntensityPoison; - Value x48_rippleIntensityLava; - Value x4c_fluidEnvBumpScale; - Value x50_waterFogDistanceBase; - Value x54_waterFogDistanceRange; - Value x58_gravityWaterFogDistanceBase; - Value x5c_gravityWaterFogDistanceRange; - Value x60_hardmodeDamageMult; - Value x64_hardmodeWeaponMult; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakGui.hpp b/DataSpec/DNAMP1/Tweaks/CTweakGui.hpp deleted file mode 100644 index e6d6eac15..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakGui.hpp +++ /dev/null @@ -1,187 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/Tweaks/ITweakGui.hpp" - -namespace DataSpec::DNAMP1 { -struct CTweakGui final : ITweakGui { - AT_DECL_DNA_YAML - Value x4_; - Value x8_mapAlphaInterp; - Value xc_pauseBlurFactor; - Value x10_radarXYRadius; - Value x14_; - Value x18_; - Value x1c_; - Value x20_; - Value x24_radarZRadius; - Value x28_radarZCloseRadius; - atUint32 x2c_ = 0; - Value x30_; - Value x34_energyBarFilledSpeed; - Value x38_energyBarShadowSpeed; - Value x3c_energyBarDrainDelay; - Value x40_energyBarAlwaysResetDelay; - Value x44_hudDamagePracticalsGainConstant; - Value x48_hudDamagePracticalsGainLinear; - Value x4c_hudDamagePracticalsInitConstant; - Value x50_hudDamagePracticalsInitLinear; - Value x54_hudDamageLightSpotAngle; - Value x58_damageLightAngleC; - Value x5c_damageLightAngleL; - Value x60_damageLightAngleQ; - Value x64_damageLightPreTranslate; - Value x70_damageLightCenterTranslate; - Value x7c_damageLightXfXAngle; - Value x80_damageLightXfZAngle; - Value x84_hudDecoShakeTranslateVelConstant; - Value x88_hudDecoShakeTranslateVelLinear; - Value x8c_maxDecoDamageShakeTranslate; - Value x90_decoDamageShakeDeceleration; - Value x94_decoShakeGainConstant; - Value x98_decoShakeGainLinear; - Value x9c_decoShakeInitConstant; - Value xa0_decoShakeInitLinear; - Value xa4_maxDecoDamageShakeRotate; - Value xa8_hudCamFovTweak; - Value xac_hudCamYTweak; - Value xb0_hudCamZTweak; - Value xb4_; - Value xb8_; - Value xbc_; - Value xc0_beamVisorMenuAnimTime; - Value xc4_visorBeamMenuItemActiveScale; - Value xc8_visorBeamMenuItemInactiveScale; - Value xcc_visorBeamMenuItemTranslate; - Value xd0_; - Value xd4_; - Value xd8_; - Value xdc_; - Value xe0_; - Value xe4_threatRange; - Value xe8_radarScopeCoordRadius; - Value xec_radarPlayerPaintRadius; - Value xf0_radarEnemyPaintRadius; - Value xf4_missileArrowVisTime; - Value xf8_hudVisMode; - Value xfc_helmetVisMode; - Value x100_enableAutoMapper; - Value x104_; - Value x108_enableTargetingManager; - Value x10c_enablePlayerVisor; - Value x110_threatWarningFraction; - Value x114_missileWarningFraction; - Value x118_freeLookFadeTime; - Value x11c_; - Value x120_; - Value x124_; - Value x128_; - Value x12c_freeLookSfxPitchScale; - Value x130_noAbsoluteFreeLookSfxPitch; - Value x134_; - Value x138_; - Value x13c_faceReflectionOrthoWidth; - Value x140_faceReflectionOrthoHeight; - Value x144_faceReflectionDistance; - Value x148_faceReflectionHeight; - Value x14c_faceReflectionAspect; - String<-1> x150_; - String<-1> x160_; - String<-1> x170_; - String<-1> x180_; - String<-1> x190_; - Value x1a0_missileWarningPulseTime; - Value x1a4_explosionLightFalloffMultConstant; - Value x1a8_explosionLightFalloffMultLinear; - Value x1ac_explosionLightFalloffMultQuadratic; - Value x1b0_; - Value x1b4_hudDamagePeakFactor; - Value x1b8_hudDamageFilterGainConstant; - Value x1bc_hudDamageFilterGainLinear; - Value x1c0_hudDamageFilterInitConstant; - Value x1c4_hudDamageFilterInitLinear; - Value x1c8_energyDrainModPeriod; - Value x1cc_energyDrainSinusoidalPulse; - Value x1cd_energyDrainFilterAdditive; - Value x1d0_hudDamagePulseDuration; - Value x1d4_hudDamageColorGain; - Value x1d8_hudDecoShakeTranslateGain; - Value x1dc_hudLagOffsetScale; - Value x1e0_; - Value x1e4_; - Value x1e8_; - Value x1ec_; - Value x1f0_; - Value x1f4_; - Value x1f8_; - Value x1fc_; - zeus::CColor x200_; - float x204_xrayBlurScaleLinear = 0.0014f; - float x208_xrayBlurScaleQuadratic = 0.0000525f; - Value x20c_; - Value x210_scanSidesAngle; - Value x214_scanSidesXScale; - Value x218_scanSidesPositionEnd; - Value x21c_; - Value x220_scanSidesDuration; - Value x224_scanSidesStartTime; - float x228_scanSidesEndTime; - Value x22c_scanDataDotRadius; - Value x230_scanDataDotPosRandMag; - Value x234_scanDataDotSeekDurationMin; - Value x238_scanDataDotSeekDurationMax; - Value x23c_scanDataDotHoldDurationMin; - Value x240_scanDataDotHoldDurationMax; - Value x244_scanAppearanceDuration; - Value x248_scanPaneFlashFactor; - Value x24c_scanPaneFadeInTime; - Value x250_scanPaneFadeOutTime; - Value x254_ballViewportYReduction; - Value x258_scanWindowIdleW; - Value x25c_scanWindowIdleH; - Value x260_scanWindowActiveW; - Value x264_scanWindowActiveH; - Value x268_scanWindowMagnification; - Value x26c_scanWindowScanningAspect; - Value x270_scanSidesPositionStart; - Value x274_showAutomapperInMorphball; - bool x275_latchArticleText = true; - Value x278_wtMgrCharsPerSfx; - Value x27c_xrayFogMode; - Value x280_xrayFogNearZ; - Value x284_xrayFogFarZ; - DNAColor x288_xrayFogColor; - Value x28c_thermalVisorLevel; - DNAColor x290_thermalVisorColor; - DNAColor x294_hudLightAddPerVisor[4]; - DNAColor x2a4_hudLightMultiplyPerVisor[4]; - DNAColor x2b4_hudReflectivityLightColor; - Value x2b8_hudLightAttMulConstant; - Value x2bc_hudLightAttMulLinear; - Value x2c0_hudLightAttMulQuadratic; - Value m_scanSpeedsCount; - Vector x2c4_scanSpeeds; - String<-1> x2d0_creditsTable; - String<-1> x2e0_creditsFont; - String<-1> x2f0_japaneseCreditsFont; - DNAColor x300_; - DNAColor x304_; - Value x308_; - Value x30c_; - Value x310_; - String<-1> x314_; - String<-1> x324_; - String<-1> x334_; - DNAColor x344_; - DNAColor x348_; - DNAColor x34c_; - DNAColor x350_; - DNAColor x354_; - DNAColor x358_; - Value x35c_; - Value x360_; - Value x364_; - - CTweakGui() = default; -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakGuiColors.hpp b/DataSpec/DNAMP1/Tweaks/CTweakGuiColors.hpp deleted file mode 100644 index 231a18dd2..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakGuiColors.hpp +++ /dev/null @@ -1,227 +0,0 @@ -#pragma once - -#include "../../DNACommon/Tweaks/ITweakGuiColors.hpp" - -namespace DataSpec::DNAMP1 { -struct CTweakGuiColors final : public ITweakGuiColors { - AT_DECL_DNA_YAML - DNAColor x4_pauseBlurFilterColor; - DNAColor x8_radarStuffColor; - DNAColor xc_radarPlayerPaintColor; - DNAColor x10_radarEnemyPaintColor; - DNAColor x14_hudMessageFill; - DNAColor x18_hudMessageOutline; - DNAColor x1c_hudFrameColor; - DNAColor x20_; - DNAColor x24_; - DNAColor x28_missileIconColorActive; - DNAColor x2c_visorBeamMenuItemActive; - DNAColor x30_visorBeamMenuColorInactive; - DNAColor x34_energyBarFilledLowEnergy; - DNAColor x38_energyBarShadowLowEnergy; - DNAColor x3c_energyBarEmptyLowEnergy; - DNAColor x40_hudDamageLightColor; - DNAColor x44_; - DNAColor x48_; - DNAColor x4c_visorMenuTextFont; - DNAColor x50_visorMenuTextOutline; - DNAColor x54_beamMenuTextFont; - DNAColor x58_beamMenuTextOutline; - DNAColor x5c_energyWarningFont; - DNAColor x60_threatWarningFont; - DNAColor x64_missileWarningFont; - DNAColor x68_threatBarFilled; - DNAColor x6c_threatBarShadow; - DNAColor x70_threatBarEmpty; - DNAColor x74_missileBarFilled; - DNAColor x78_missileBarShadow; - DNAColor x7c_missileBarEmpty; - DNAColor x80_threatIconColor; - DNAColor x84_; - DNAColor x88_tickDecoColor; - DNAColor x8c_helmetLightColor; - DNAColor x90_threatIconSafeColor; - DNAColor x94_missileIconColorInactive; - DNAColor x98_missileIconColorChargedCanAlt; - DNAColor x9c_missileIconColorChargedNoAlt; - DNAColor xa0_missileIconColorDepleteAlt; - DNAColor xa4_; - DNAColor xa8_; - DNAColor xac_; - DNAColor xb0_visorBeamMenuLozColor; - DNAColor xb4_energyWarningOutline; - DNAColor xb8_threatWarningOutline; - DNAColor xbc_missileWarningOutline; - DNAColor xc0_; - DNAColor xc4_damageAmbientColor; - DNAColor xc8_scanFrameInactiveColor; - DNAColor xcc_scanFrameActiveColor; - DNAColor xd0_scanFrameImpulseColor; - DNAColor xd4_scanVisorHudLightMultiply; - DNAColor xd8_scanVisorScreenDimColor; - DNAColor xdc_thermalVisorHudLightMultiply; - DNAColor xe0_energyDrainFilterColor; - DNAColor xe4_damageAmbientPulseColor; - DNAColor xe8_energyBarFlashColor; - DNAColor xec_; - DNAColor xf0_; - DNAColor xf4_; - DNAColor xf8_; - DNAColor xfc_; - DNAColor x100_xrayEnergyDecoColor; - DNAColor x104_; - DNAColor x108_; - DNAColor x10c_; - DNAColor x110_; - DNAColor x114_; - DNAColor x118_; - DNAColor x11c_; - DNAColor x120_; - DNAColor x124_; - DNAColor x128_; - DNAColor x12c_; - DNAColor x130_; - DNAColor x134_; - DNAColor x138_scanDataDotColor; - DNAColor x13c_powerBombDigitAvailableFont; - DNAColor x140_powerBombDigitAvailableOutline; - DNAColor x144_; - DNAColor x148_ballBombFilled; - DNAColor x14c_ballBombEmpty; - DNAColor x150_powerBombIconAvailable; - DNAColor x154_; - DNAColor x158_ballEnergyDeco; - DNAColor x15c_ballBombDeco; - DNAColor x160_powerBombDigitDepletedFont; - DNAColor x164_powerBombDigitDepletedOutline; - DNAColor x168_powerBombIconUnavailable; - DNAColor x16c_; - DNAColor x170_; - DNAColor x174_scanDisplayImagePaneColor; - DNAColor x178_; - DNAColor x17c_threatIconWarningColor; - DNAColor x180_hudCounterFill; - DNAColor x184_hudCounterOutline; - DNAColor x188_scanIconCriticalColor; - DNAColor x18c_scanIconCriticalDimColor; - DNAColor x190_scanIconNoncriticalColor; - DNAColor x194_scanIconNoncriticalDimColor; - DNAColor x198_scanReticuleColor; - DNAColor x19c_threatDigitsFont; - DNAColor x1a0_threatDigitsOutline; - DNAColor x1a4_missileDigitsFont; - DNAColor x1a8_missileDigitsOutline; - DNAColor x1ac_thermalDecoColor; - DNAColor x1b0_thermalOutlinesColor; - DNAColor x1b4_; - DNAColor x1b8_thermalLockColor; - DNAColor x1bc_pauseItemAmber; - DNAColor x1c0_pauseItemBlue; - struct PerVisorColors : BigDNA { - AT_DECL_DNA - DNAColor x0_energyBarFilled; - DNAColor x4_energyBarEmpty; - DNAColor x8_energyBarShadow; - DNAColor xc_energyTankFilled; - DNAColor x10_energyTankEmpty; - DNAColor x14_energyDigitsFont; - DNAColor x18_energyDigitsOutline; - }; - Value x1c4_perVisorCount; - /* Combat, Scan, XRay, Thermal, Ball */ - Vector x1c4_perVisorColors; - - CTweakGuiColors() = default; - CTweakGuiColors(athena::io::IStreamReader& r) { this->read(r); } - - const zeus::CColor& GetPauseBlurFilterColor() const override { return x4_pauseBlurFilterColor; } - const zeus::CColor& GetRadarStuffColor() const override { return x8_radarStuffColor; } - const zeus::CColor& GetRadarPlayerPaintColor() const override { return xc_radarPlayerPaintColor; } - const zeus::CColor& GetRadarEnemyPaintColor() const override { return x10_radarEnemyPaintColor; } - const zeus::CColor& GetHudMessageFill() const override { return x14_hudMessageFill; } - const zeus::CColor& GetHudMessageOutline() const override { return x18_hudMessageOutline; } - const zeus::CColor& GetHudFrameColor() const override { return x1c_hudFrameColor; } - const zeus::CColor& GetMissileIconColorActive() const override { return x28_missileIconColorActive; } - const zeus::CColor& GetVisorBeamMenuItemActive() const override { return x2c_visorBeamMenuItemActive; } - const zeus::CColor& GetVisorBeamMenuItemInactive() const override { return x30_visorBeamMenuColorInactive; } - const zeus::CColor& GetEnergyBarFilledLowEnergy() const override { return x34_energyBarFilledLowEnergy; } - const zeus::CColor& GetEnergyBarShadowLowEnergy() const override { return x38_energyBarShadowLowEnergy; } - const zeus::CColor& GetEnergyBarEmptyLowEnergy() const override { return x3c_energyBarEmptyLowEnergy; } - const zeus::CColor& GetHudDamageLightColor() const override { return x40_hudDamageLightColor; } - const zeus::CColor& GetVisorMenuTextFont() const override { return x4c_visorMenuTextFont; } - const zeus::CColor& GetVisorMenuTextOutline() const override { return x50_visorMenuTextOutline; } - const zeus::CColor& GetBeamMenuTextFont() const override { return x54_beamMenuTextFont; } - const zeus::CColor& GetBeamMenuTextOutline() const override { return x58_beamMenuTextOutline; } - const zeus::CColor& GetEnergyWarningFont() const override { return x5c_energyWarningFont; } - const zeus::CColor& GetThreatWarningFont() const override { return x60_threatWarningFont; } - const zeus::CColor& GetMissileWarningFont() const override { return x64_missileWarningFont; } - const zeus::CColor& GetThreatBarFilled() const override { return x68_threatBarFilled; } - const zeus::CColor& GetThreatBarShadow() const override { return x6c_threatBarShadow; } - const zeus::CColor& GetThreatBarEmpty() const override { return x70_threatBarEmpty; } - const zeus::CColor& GetMissileBarFilled() const override { return x74_missileBarFilled; } - const zeus::CColor& GetMissileBarShadow() const override { return x78_missileBarShadow; } - const zeus::CColor& GetMissileBarEmpty() const override { return x7c_missileBarEmpty; } - const zeus::CColor& GetThreatIconColor() const override { return x80_threatIconColor; } - const zeus::CColor& GetTickDecoColor() const override { return x88_tickDecoColor; } - const zeus::CColor& GetHelmetLightColor() const override { return x8c_helmetLightColor; } - const zeus::CColor& GetThreatIconSafeColor() const override { return x90_threatIconSafeColor; } - const zeus::CColor& GetMissileIconColorInactive() const override { return x94_missileIconColorInactive; } - const zeus::CColor& GetMissileIconColorChargedCanAlt() const override { return x98_missileIconColorChargedCanAlt; } - const zeus::CColor& GetMissileIconColorChargedNoAlt() const override { return x9c_missileIconColorChargedNoAlt; } - const zeus::CColor& GetMissileIconColorDepleteAlt() const override { return xa0_missileIconColorDepleteAlt; } - const zeus::CColor& GetVisorBeamMenuLozColor() const override { return xb0_visorBeamMenuLozColor; } - const zeus::CColor& GetEnergyWarningOutline() const override { return xb4_energyWarningOutline; } - const zeus::CColor& GetThreatWarningOutline() const override { return xb8_threatWarningOutline; } - const zeus::CColor& GetMissileWarningOutline() const override { return xbc_missileWarningOutline; } - const zeus::CColor& GetDamageAmbientColor() const override { return xc4_damageAmbientColor; } - const zeus::CColor& GetScanFrameInactiveColor() const override { return xc8_scanFrameInactiveColor; } - const zeus::CColor& GetScanFrameActiveColor() const override { return xcc_scanFrameActiveColor; } - const zeus::CColor& GetScanFrameImpulseColor() const override { return xd0_scanFrameImpulseColor; } - const zeus::CColor& GetScanVisorHudLightMultiply() const override { return xd4_scanVisorHudLightMultiply; } - const zeus::CColor& GetScanVisorScreenDimColor() const override { return xd8_scanVisorScreenDimColor; } - const zeus::CColor& GetThermalVisorHudLightMultiply() const override { return xdc_thermalVisorHudLightMultiply; } - const zeus::CColor& GetEnergyDrainFilterColor() const override { return xe0_energyDrainFilterColor; } - const zeus::CColor& GetDamageAmbientPulseColor() const override { return xe4_damageAmbientPulseColor; } - const zeus::CColor& GetEnergyBarFlashColor() const override { return xe8_energyBarFlashColor; } - const zeus::CColor& GetXRayEnergyDecoColor() const override { return x100_xrayEnergyDecoColor; } - const zeus::CColor& GetScanDataDotColor() const override { return x138_scanDataDotColor; } - const zeus::CColor& GetPowerBombDigitAvailableFont() const override { return x13c_powerBombDigitAvailableFont; } - const zeus::CColor& GetPowerBombDigitAvailableOutline() const override { return x140_powerBombDigitAvailableOutline; } - const zeus::CColor& GetBallBombFilledColor() const override { return x148_ballBombFilled; } - const zeus::CColor& GetBallBombEmptyColor() const override { return x14c_ballBombEmpty; } - const zeus::CColor& GetPowerBombIconAvailableColor() const override { return x150_powerBombIconAvailable; } - const zeus::CColor& GetBallBombEnergyColor() const override { return x158_ballEnergyDeco; } - const zeus::CColor& GetBallBombDecoColor() const override { return x15c_ballBombDeco; } - const zeus::CColor& GetPowerBombDigitDelpetedFont() const override { return x160_powerBombDigitDepletedFont; } - const zeus::CColor& GetPowerBombDigitDelpetedOutline() const override { return x164_powerBombDigitDepletedOutline; } - const zeus::CColor& GetPowerBombIconDepletedColor() const override { return x168_powerBombIconUnavailable; } - const zeus::CColor& GetScanDisplayImagePaneColor() const override { return x174_scanDisplayImagePaneColor; } - const zeus::CColor& GetThreatIconWarningColor() const override { return x17c_threatIconWarningColor; } - const zeus::CColor& GetHudCounterFill() const override { return x180_hudCounterFill; } - const zeus::CColor& GetHudCounterOutline() const override { return x184_hudCounterOutline; } - const zeus::CColor& GetScanIconCriticalColor() const override { return x188_scanIconCriticalColor; } - const zeus::CColor& GetScanIconCriticalDimColor() const override { return x18c_scanIconCriticalDimColor; } - const zeus::CColor& GetScanIconNoncriticalColor() const override { return x190_scanIconNoncriticalColor; } - const zeus::CColor& GetScanIconNoncriticalDimColor() const override { return x194_scanIconNoncriticalDimColor; } - const zeus::CColor& GetScanReticuleColor() const override { return x198_scanReticuleColor; } - const zeus::CColor& GetThreatDigitsFont() const override { return x19c_threatDigitsFont; } - const zeus::CColor& GetThreatDigitsOutline() const override { return x1a0_threatDigitsOutline; } - const zeus::CColor& GetMissileDigitsFont() const override { return x1a4_missileDigitsFont; } - const zeus::CColor& GetMissileDigitsOutline() const override { return x1a8_missileDigitsOutline; } - const zeus::CColor& GetThermalDecoColor() const override { return x1ac_thermalDecoColor; } - const zeus::CColor& GetThermalOutlinesColor() const override { return x1b0_thermalOutlinesColor; } - const zeus::CColor& GetThermalLockColor() const override { return x1b8_thermalLockColor; } - const zeus::CColor& GetPauseItemAmberColor() const override { return x1bc_pauseItemAmber; } - const zeus::CColor& GetPauseItemBlueColor() const override { return x1c0_pauseItemBlue; } - - VisorEnergyInitColors GetVisorEnergyInitColors(int idx) const override { - const PerVisorColors& colors = x1c4_perVisorColors[idx]; - return {colors.xc_energyTankFilled, colors.x10_energyTankEmpty, colors.x14_energyDigitsFont, - colors.x18_energyDigitsOutline}; - } - VisorEnergyBarColors GetVisorEnergyBarColors(int idx) const override { - const PerVisorColors& colors = x1c4_perVisorColors[idx]; - return {colors.x0_energyBarFilled, colors.x4_energyBarEmpty, colors.x8_energyBarShadow}; - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakGunRes.hpp b/DataSpec/DNAMP1/Tweaks/CTweakGunRes.hpp deleted file mode 100644 index 512b2dd8f..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakGunRes.hpp +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include "../../DNACommon/Tweaks/ITweakGunRes.hpp" - -namespace DataSpec::DNAMP1 { - -struct CTweakGunRes final : ITweakGunRes { - AT_DECL_DNA_YAML - - String<-1> m_gunMotion; - String<-1> m_grappleArm; - String<-1> m_rightHand; - - String<-1> m_powerBeam; - String<-1> m_iceBeam; - String<-1> m_waveBeam; - String<-1> m_plasmaBeam; - String<-1> m_phazonBeam; - - String<-1> m_holoTransition; - - String<-1> m_bombSet; - String<-1> m_bombExplode; - String<-1> m_powerBombExplode; - - String<-1> m_powerBeamWp; - String<-1> m_powerBallWp; - String<-1> m_iceBeamWp; - String<-1> m_iceBallWp; - String<-1> m_waveBeamWp; - String<-1> m_waveBallWp; - String<-1> m_plasmaBeamWp; - String<-1> m_plasmaBallWp; - String<-1> m_phazonBeamWp; - String<-1> m_phazonBallWp; - - String<-1> m_powerMuzzle; - String<-1> m_iceMuzzle; - String<-1> m_waveMuzzle; - String<-1> m_plasmaMuzzle; - String<-1> m_phazonMuzzle; - - String<-1> m_powerCharge; - String<-1> m_iceCharge; - String<-1> m_waveCharge; - String<-1> m_plasmaCharge; - String<-1> m_phazonCharge; - - String<-1> m_powerAuxMuzzle; - String<-1> m_iceAuxMuzzle; - String<-1> m_waveAuxMuzzle; - String<-1> m_plasmaAuxMuzzle; - String<-1> m_phazonAuxMuzzle; - - String<-1> m_grappleSegment; - String<-1> m_grappleClaw; - String<-1> m_grappleHit; - String<-1> m_grappleMuzzle; - String<-1> m_grappleSwoosh; - - const std::string& GetGunMotion() const override { return m_gunMotion; } - const std::string& GetGrappleArm() const override { return m_grappleArm; } - const std::string& GetRightHand() const override { return m_rightHand; } - - const std::string& GetPowerBeam() const override { return m_powerBeam; } - const std::string& GetIceBeam() const override { return m_iceBeam; } - const std::string& GetWaveBeam() const override { return m_waveBeam; } - const std::string& GetPlasmaBeam() const override { return m_plasmaBeam; } - const std::string& GetPhazonBeam() const override { return m_phazonBeam; } - - const std::string& GetHoloTransition() const override { return m_holoTransition; } - - const std::string& GetBombSet() const override { return m_bombSet; } - const std::string& GetBombExplode() const override { return m_bombExplode; } - const std::string& GetPowerBombExplode() const override { return m_powerBombExplode; } - - const std::string& GetWeapon(size_t idx, bool ball) const override { return (&m_powerBeamWp)[idx * 2 + ball]; } - const std::string& GetMuzzleParticle(size_t idx) const override { return (&m_powerMuzzle)[idx]; } - const std::string& GetChargeParticle(size_t idx) const override { return (&m_powerCharge)[idx]; } - const std::string& GetAuxMuzzleParticle(size_t idx) const override { return (&m_powerAuxMuzzle)[idx]; } - - const std::string& GetGrappleSegmentParticle() const override { return m_grappleSegment; } - const std::string& GetGrappleClawParticle() const override { return m_grappleClaw; } - const std::string& GetGrappleHitParticle() const override { return m_grappleHit; } - const std::string& GetGrappleMuzzleParticle() const override { return m_grappleMuzzle; } - const std::string& GetGrappleSwooshParticle() const override { return m_grappleSwoosh; } - - CTweakGunRes() = default; - CTweakGunRes(athena::io::IStreamReader& in) { read(in); } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakParticle.hpp b/DataSpec/DNAMP1/Tweaks/CTweakParticle.hpp deleted file mode 100644 index 79e4cfb02..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakParticle.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "../../DNACommon/Tweaks/ITweakParticle.hpp" - -namespace DataSpec::DNAMP1 { - -struct CTweakParticle final : ITweakParticle { - AT_DECL_DNA_YAML - String<-1> m_particle; - String<-1> m_powerBeam; - String<-1> m_genThrust; - - CTweakParticle() = default; - CTweakParticle(athena::io::IStreamReader& reader) { this->read(reader); } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakPlayer.cpp b/DataSpec/DNAMP1/Tweaks/CTweakPlayer.cpp deleted file mode 100644 index d16e5edaf..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakPlayer.cpp +++ /dev/null @@ -1,1875 +0,0 @@ -#include "DataSpec/DNAMP1/Tweaks/CTweakPlayer.hpp" -#include "zeus/Math.hpp" - -namespace DataSpec::DNAMP1 { -template <> -void CTweakPlayer::Enumerate(athena::io::IStreamReader& __dna_reader) { - /* x4_maxTranslationalAcceleration[0] */ - x4_maxTranslationalAcceleration[0] = __dna_reader.readFloatBig(); - /* x4_maxTranslationalAcceleration[1] */ - x4_maxTranslationalAcceleration[1] = __dna_reader.readFloatBig(); - /* x4_maxTranslationalAcceleration[2] */ - x4_maxTranslationalAcceleration[2] = __dna_reader.readFloatBig(); - /* x4_maxTranslationalAcceleration[3] */ - x4_maxTranslationalAcceleration[3] = __dna_reader.readFloatBig(); - /* x4_maxTranslationalAcceleration[4] */ - x4_maxTranslationalAcceleration[4] = __dna_reader.readFloatBig(); - /* x4_maxTranslationalAcceleration[5] */ - x4_maxTranslationalAcceleration[5] = __dna_reader.readFloatBig(); - /* x4_maxTranslationalAcceleration[6] */ - x4_maxTranslationalAcceleration[6] = __dna_reader.readFloatBig(); - /* x4_maxTranslationalAcceleration[7] */ - x4_maxTranslationalAcceleration[7] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[0] */ - x24_maxRotationalAcceleration[0] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[1] */ - x24_maxRotationalAcceleration[1] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[2] */ - x24_maxRotationalAcceleration[2] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[3] */ - x24_maxRotationalAcceleration[3] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[4] */ - x24_maxRotationalAcceleration[4] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[5] */ - x24_maxRotationalAcceleration[5] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[6] */ - x24_maxRotationalAcceleration[6] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[7] */ - x24_maxRotationalAcceleration[7] = __dna_reader.readFloatBig(); - /* x44_translationFriction[0] */ - x44_translationFriction[0] = __dna_reader.readFloatBig(); - /* x44_translationFriction[1] */ - x44_translationFriction[1] = __dna_reader.readFloatBig(); - /* x44_translationFriction[2] */ - x44_translationFriction[2] = __dna_reader.readFloatBig(); - /* x44_translationFriction[3] */ - x44_translationFriction[3] = __dna_reader.readFloatBig(); - /* x44_translationFriction[4] */ - x44_translationFriction[4] = __dna_reader.readFloatBig(); - /* x44_translationFriction[5] */ - x44_translationFriction[5] = __dna_reader.readFloatBig(); - /* x44_translationFriction[6] */ - x44_translationFriction[6] = __dna_reader.readFloatBig(); - /* x44_translationFriction[7] */ - x44_translationFriction[7] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[0] */ - x64_rotationFriction[0] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[1] */ - x64_rotationFriction[1] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[2] */ - x64_rotationFriction[2] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[3] */ - x64_rotationFriction[3] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[4] */ - x64_rotationFriction[4] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[5] */ - x64_rotationFriction[5] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[6] */ - x64_rotationFriction[6] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[7] */ - x64_rotationFriction[7] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[0] */ - x84_rotationMaxSpeed[0] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[1] */ - x84_rotationMaxSpeed[1] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[2] */ - x84_rotationMaxSpeed[2] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[3] */ - x84_rotationMaxSpeed[3] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[4] */ - x84_rotationMaxSpeed[4] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[5] */ - x84_rotationMaxSpeed[5] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[6] */ - x84_rotationMaxSpeed[6] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[7] */ - x84_rotationMaxSpeed[7] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[0] */ - xa4_translationMaxSpeed[0] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[1] */ - xa4_translationMaxSpeed[1] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[2] */ - xa4_translationMaxSpeed[2] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[3] */ - xa4_translationMaxSpeed[3] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[4] */ - xa4_translationMaxSpeed[4] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[5] */ - xa4_translationMaxSpeed[5] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[6] */ - xa4_translationMaxSpeed[6] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[7] */ - xa4_translationMaxSpeed[7] = __dna_reader.readFloatBig(); - /* xc4_normalGravAccel */ - xc4_normalGravAccel = __dna_reader.readFloatBig(); - /* xc8_fluidGravAccel */ - xc8_fluidGravAccel = __dna_reader.readFloatBig(); - /* xcc_verticalJumpAccel */ - xcc_verticalJumpAccel = __dna_reader.readFloatBig(); - /* xd0_horizontalJumpAccel */ - xd0_horizontalJumpAccel = __dna_reader.readFloatBig(); - /* xd4_verticalDoubleJumpAccel */ - xd4_verticalDoubleJumpAccel = __dna_reader.readFloatBig(); - /* xd8_horizontalDoubleJumpAccel */ - xd8_horizontalDoubleJumpAccel = __dna_reader.readFloatBig(); - /* xdc_waterJumpFactor */ - xdc_waterJumpFactor = __dna_reader.readFloatBig(); - /* xe0_waterBallJumpFactor */ - xe0_waterBallJumpFactor = __dna_reader.readFloatBig(); - /* xe4_lavaJumpFactor */ - xe4_lavaJumpFactor = __dna_reader.readFloatBig(); - /* xe8_lavaBallJumpFactor */ - xe8_lavaBallJumpFactor = __dna_reader.readFloatBig(); - /* xec_phazonJumpFactor */ - xec_phazonJumpFactor = __dna_reader.readFloatBig(); - /* xf0_phazonBallJumpFactor */ - xf0_phazonBallJumpFactor = __dna_reader.readFloatBig(); - /* xf4_allowedJumpTime */ - xf4_allowedJumpTime = __dna_reader.readFloatBig(); - /* xf8_allowedDoubleJumpTime */ - xf8_allowedDoubleJumpTime = __dna_reader.readFloatBig(); - /* xfc_minDoubleJumpWindow */ - xfc_minDoubleJumpWindow = __dna_reader.readFloatBig(); - /* x100_maxDoubleJumpWindow */ - x100_maxDoubleJumpWindow = __dna_reader.readFloatBig(); - /* x104_ */ - x104_ = __dna_reader.readFloatBig(); - /* x108_minJumpTime */ - x108_minJumpTime = __dna_reader.readFloatBig(); - /* x10c_minDoubleJumpTime */ - x10c_minDoubleJumpTime = __dna_reader.readFloatBig(); - /* x110_allowedLedgeTime */ - x110_allowedLedgeTime = __dna_reader.readFloatBig(); - /* x114_doubleJumpImpulse */ - x114_doubleJumpImpulse = __dna_reader.readFloatBig(); - /* x118_backwardsForceMultiplier */ - x118_backwardsForceMultiplier = __dna_reader.readFloatBig(); - /* x11c_bombJumpRadius */ - x11c_bombJumpRadius = __dna_reader.readFloatBig(); - /* x120_bombJumpHeight */ - x120_bombJumpHeight = __dna_reader.readFloatBig(); - /* x124_eyeOffset */ - x124_eyeOffset = __dna_reader.readFloatBig(); - /* x128_turnSpeedMultiplier */ - x128_turnSpeedMultiplier = __dna_reader.readFloatBig(); - /* x12c_freeLookTurnSpeedMultiplier */ - x12c_freeLookTurnSpeedMultiplier = __dna_reader.readFloatBig(); - /* x130_horizontalFreeLookAngleVel */ - x130_horizontalFreeLookAngleVel = __dna_reader.readFloatBig(); - /* x134_verticalFreeLookAngleVel */ - x134_verticalFreeLookAngleVel = __dna_reader.readFloatBig(); - /* x138_freeLookSpeed */ - x138_freeLookSpeed = __dna_reader.readFloatBig(); - /* x13c_freeLookSnapSpeed */ - x13c_freeLookSnapSpeed = __dna_reader.readFloatBig(); - /* x140_ */ - x140_ = __dna_reader.readFloatBig(); - /* x144_freeLookCenteredThresholdAngle */ - x144_freeLookCenteredThresholdAngle = __dna_reader.readFloatBig(); - /* x148_freeLookCenteredTime */ - x148_freeLookCenteredTime = __dna_reader.readFloatBig(); - /* x14c_freeLookDampenFactor */ - x14c_freeLookDampenFactor = __dna_reader.readFloatBig(); - /* x150_leftDiv */ - x150_leftDiv = __dna_reader.readFloatBig(); - /* x154_rightDiv */ - x154_rightDiv = __dna_reader.readFloatBig(); - /* x228_24_freelookTurnsPlayer */ - x228_24_freelookTurnsPlayer = __dna_reader.readBool(); - /* x228_25_ */ - x228_25_ = __dna_reader.readBool(); - /* x228_26_ */ - x228_26_ = __dna_reader.readBool(); - /* x228_27_moveDuringFreeLook */ - x228_27_moveDuringFreeLook = __dna_reader.readBool(); - /* x228_28_holdButtonsForFreeLook */ - x228_28_holdButtonsForFreeLook = __dna_reader.readBool(); - /* x228_29_twoButtonsForFreeLook */ - x228_29_twoButtonsForFreeLook = __dna_reader.readBool(); - /* x228_30_ */ - x228_30_ = __dna_reader.readBool(); - /* x228_31_ */ - x228_31_ = __dna_reader.readBool(); - /* x229_24_ */ - x229_24_ = __dna_reader.readBool(); - /* x229_25_aimWhenOrbitingPoint */ - x229_25_aimWhenOrbitingPoint = __dna_reader.readBool(); - /* x229_26_stayInFreeLookWhileFiring */ - x229_26_stayInFreeLookWhileFiring = __dna_reader.readBool(); - /* x229_27_ */ - x229_27_ = __dna_reader.readBool(); - /* x229_28_ */ - x229_28_ = __dna_reader.readBool(); - /* x229_29_orbitFixedOffset */ - x229_29_orbitFixedOffset = __dna_reader.readBool(); - /* x229_30_gunButtonTogglesHolster */ - x229_30_gunButtonTogglesHolster = __dna_reader.readBool(); - /* x229_31_gunNotFiringHolstersGun */ - x229_31_gunNotFiringHolstersGun = __dna_reader.readBool(); - /* x22a_24_fallingDoubleJump */ - x22a_24_fallingDoubleJump = __dna_reader.readBool(); - /* x22a_25_impulseDoubleJump */ - x22a_25_impulseDoubleJump = __dna_reader.readBool(); - /* x22a_26_firingCancelsCameraPitch */ - x22a_26_firingCancelsCameraPitch = __dna_reader.readBool(); - /* x22a_27_assistedAimingIgnoreHorizontal */ - x22a_27_assistedAimingIgnoreHorizontal = __dna_reader.readBool(); - /* x22a_28_assistedAimingIgnoreVertical */ - x22a_28_assistedAimingIgnoreVertical = __dna_reader.readBool(); - /* x22c_ */ - x22c_ = __dna_reader.readFloatBig(); - /* x230_ */ - x230_ = __dna_reader.readFloatBig(); - /* x234_aimMaxDistance */ - x234_aimMaxDistance = __dna_reader.readFloatBig(); - /* x238_ */ - x238_ = __dna_reader.readFloatBig(); - /* x23c_ */ - x23c_ = __dna_reader.readFloatBig(); - /* x240_ */ - x240_ = __dna_reader.readFloatBig(); - /* x244_ */ - x244_ = __dna_reader.readFloatBig(); - /* x248_ */ - x248_ = __dna_reader.readFloatBig(); - /* x24c_aimThresholdDistance */ - x24c_aimThresholdDistance = __dna_reader.readFloatBig(); - /* x250_ */ - x250_ = __dna_reader.readFloatBig(); - /* x254_ */ - x254_ = __dna_reader.readFloatBig(); - /* x258_aimBoxWidth */ - x258_aimBoxWidth = __dna_reader.readFloatBig(); - /* x25c_aimBoxHeight */ - x25c_aimBoxHeight = __dna_reader.readFloatBig(); - /* x260_aimTargetTimer */ - x260_aimTargetTimer = __dna_reader.readFloatBig(); - /* x264_aimAssistHorizontalAngle */ - x264_aimAssistHorizontalAngle = __dna_reader.readFloatBig(); - /* x268_aimAssistVerticalAngle */ - x268_aimAssistVerticalAngle = __dna_reader.readFloatBig(); - /* x158_orbitMinDistance[0] */ - x158_orbitMinDistance[0] = __dna_reader.readFloatBig(); - /* x164_orbitNormalDistance[0] */ - x164_orbitNormalDistance[0] = __dna_reader.readFloatBig(); - /* x170_orbitMaxDistance[0] */ - x170_orbitMaxDistance[0] = __dna_reader.readFloatBig(); - /* x158_orbitMinDistance[1] */ - x158_orbitMinDistance[1] = __dna_reader.readFloatBig(); - /* x164_orbitNormalDistance[1] */ - x164_orbitNormalDistance[1] = __dna_reader.readFloatBig(); - /* x170_orbitMaxDistance[1] */ - x170_orbitMaxDistance[1] = __dna_reader.readFloatBig(); - /* x158_orbitMinDistance[2] */ - x158_orbitMinDistance[2] = __dna_reader.readFloatBig(); - /* x164_orbitNormalDistance[2] */ - x164_orbitNormalDistance[2] = __dna_reader.readFloatBig(); - /* x170_orbitMaxDistance[2] */ - x170_orbitMaxDistance[2] = __dna_reader.readFloatBig(); - /* x17c_ */ - x17c_ = __dna_reader.readFloatBig(); - /* x180_orbitModeTimer */ - x180_orbitModeTimer = __dna_reader.readFloatBig(); - /* x184_orbitCameraSpeed */ - x184_orbitCameraSpeed = __dna_reader.readFloatBig(); - /* x188_orbitUpperAngle */ - x188_orbitUpperAngle = __dna_reader.readFloatBig(); - /* x18c_orbitLowerAngle */ - x18c_orbitLowerAngle = __dna_reader.readFloatBig(); - /* x190_orbitHorizAngle */ - x190_orbitHorizAngle = __dna_reader.readFloatBig(); - /* x194_ */ - x194_ = __dna_reader.readFloatBig(); - /* x198_ */ - x198_ = __dna_reader.readFloatBig(); - /* x19c_orbitMaxTargetDistance */ - x19c_orbitMaxTargetDistance = __dna_reader.readFloatBig(); - /* x1a0_orbitMaxLockDistance */ - x1a0_orbitMaxLockDistance = __dna_reader.readFloatBig(); - /* x1a4_orbitDistanceThreshold */ - x1a4_orbitDistanceThreshold = __dna_reader.readFloatBig(); - /* x1a8_orbitScreenBoxHalfExtentX[0] */ - x1a8_orbitScreenBoxHalfExtentX[0] = __dna_reader.readUint32Big(); - /* x1b0_orbitScreenBoxHalfExtentY[0] */ - x1b0_orbitScreenBoxHalfExtentY[0] = __dna_reader.readUint32Big(); - /* x1b8_orbitScreenBoxCenterX[0] */ - x1b8_orbitScreenBoxCenterX[0] = __dna_reader.readUint32Big(); - /* x1c0_orbitScreenBoxCenterY[0] */ - x1c0_orbitScreenBoxCenterY[0] = __dna_reader.readUint32Big(); - /* x1c8_orbitZoneIdealX[0] */ - x1c8_orbitZoneIdealX[0] = __dna_reader.readUint32Big(); - /* x1d0_orbitZoneIdealY[0] */ - x1d0_orbitZoneIdealY[0] = __dna_reader.readUint32Big(); - /* x1a8_orbitScreenBoxHalfExtentX[1] */ - x1a8_orbitScreenBoxHalfExtentX[1] = __dna_reader.readUint32Big(); - /* x1b0_orbitScreenBoxHalfExtentY[1] */ - x1b0_orbitScreenBoxHalfExtentY[1] = __dna_reader.readUint32Big(); - /* x1b8_orbitScreenBoxCenterX[1] */ - x1b8_orbitScreenBoxCenterX[1] = __dna_reader.readUint32Big(); - /* x1c0_orbitScreenBoxCenterY[1] */ - x1c0_orbitScreenBoxCenterY[1] = __dna_reader.readUint32Big(); - /* x1c8_orbitZoneIdealX[1] */ - x1c8_orbitZoneIdealX[1] = __dna_reader.readUint32Big(); - /* x1d0_orbitZoneIdealY[1] */ - x1d0_orbitZoneIdealY[1] = __dna_reader.readUint32Big(); - /* x1d8_orbitNearX */ - x1d8_orbitNearX = __dna_reader.readFloatBig(); - /* x1dc_orbitNearZ */ - x1dc_orbitNearZ = __dna_reader.readFloatBig(); - /* x1e0_ */ - x1e0_ = __dna_reader.readFloatBig(); - /* x1e4_ */ - x1e4_ = __dna_reader.readFloatBig(); - /* x1e8_orbitFixedOffsetZDiff */ - x1e8_orbitFixedOffsetZDiff = __dna_reader.readFloatBig(); - /* x1ec_orbitZRange */ - x1ec_orbitZRange = __dna_reader.readFloatBig(); - /* x1f0_ */ - x1f0_ = __dna_reader.readFloatBig(); - /* x1f4_ */ - x1f4_ = __dna_reader.readFloatBig(); - /* x1f8_ */ - x1f8_ = __dna_reader.readFloatBig(); - /* x1fc_orbitPreventionTime */ - x1fc_orbitPreventionTime = __dna_reader.readFloatBig(); - /* x200_24_dashEnabled */ - x200_24_dashEnabled = __dna_reader.readBool(); - /* x200_25_dashOnButtonRelease */ - x200_25_dashOnButtonRelease = __dna_reader.readBool(); - /* x204_dashButtonHoldCancelTime */ - x204_dashButtonHoldCancelTime = __dna_reader.readFloatBig(); - /* x208_dashStrafeInputThreshold */ - x208_dashStrafeInputThreshold = __dna_reader.readFloatBig(); - /* x20c_sidewaysDoubleJumpImpulse */ - x20c_sidewaysDoubleJumpImpulse = __dna_reader.readFloatBig(); - /* x210_sidewaysVerticalDoubleJumpAccel */ - x210_sidewaysVerticalDoubleJumpAccel = __dna_reader.readFloatBig(); - /* x214_sidewaysHorizontalDoubleJumpAccel */ - x214_sidewaysHorizontalDoubleJumpAccel = __dna_reader.readFloatBig(); - /* x218_scanningRange */ - x218_scanningRange = __dna_reader.readFloatBig(); - /* x21c_24_scanRetention */ - x21c_24_scanRetention = __dna_reader.readBool(); - /* x21c_25_scanFreezesGame */ - x21c_25_scanFreezesGame = __dna_reader.readBool(); - /* x21c_26_orbitWhileScanning */ - x21c_26_orbitWhileScanning = __dna_reader.readBool(); - /* x220_scanMaxTargetDistance */ - x220_scanMaxTargetDistance = __dna_reader.readFloatBig(); - /* x224_scanMaxLockDistance */ - x224_scanMaxLockDistance = __dna_reader.readFloatBig(); - /* x2a0_orbitDistanceMax */ - x2a0_orbitDistanceMax = __dna_reader.readFloatBig(); - /* x2a4_grappleSwingLength */ - x2a4_grappleSwingLength = __dna_reader.readFloatBig(); - /* x2a8_grappleSwingPeriod */ - x2a8_grappleSwingPeriod = __dna_reader.readFloatBig(); - /* x2ac_grapplePullSpeedMin */ - x2ac_grapplePullSpeedMin = __dna_reader.readFloatBig(); - /* x2b0_grappleCameraSpeed */ - x2b0_grappleCameraSpeed = __dna_reader.readFloatBig(); - /* x2b4_maxGrappleLockedTurnAlignDistance */ - x2b4_maxGrappleLockedTurnAlignDistance = __dna_reader.readFloatBig(); - /* x2b8_grapplePullSpeedProportion */ - x2b8_grapplePullSpeedProportion = __dna_reader.readFloatBig(); - /* x2bc_grapplePullSpeedMax */ - x2bc_grapplePullSpeedMax = __dna_reader.readFloatBig(); - /* x2c0_grappleLookCenterSpeed */ - x2c0_grappleLookCenterSpeed = __dna_reader.readFloatBig(); - /* x2c4_maxGrappleTurnSpeed */ - x2c4_maxGrappleTurnSpeed = __dna_reader.readFloatBig(); - /* x2c8_grappleJumpForce */ - x2c8_grappleJumpForce = __dna_reader.readFloatBig(); - /* x2cc_grappleReleaseTime */ - x2cc_grappleReleaseTime = __dna_reader.readFloatBig(); - /* x2d0_grappleJumpMode */ - x2d0_grappleJumpMode = __dna_reader.readUint32Big(); - /* x2d4_orbitReleaseBreaksGrapple */ - x2d4_orbitReleaseBreaksGrapple = __dna_reader.readBool(); - /* x2d5_invertGrappleTurn */ - x2d5_invertGrappleTurn = __dna_reader.readBool(); - /* x2d8_grappleBeamSpeed */ - x2d8_grappleBeamSpeed = __dna_reader.readFloatBig(); - /* x2dc_grappleBeamXWaveAmplitude */ - x2dc_grappleBeamXWaveAmplitude = __dna_reader.readFloatBig(); - /* x2e0_grappleBeamZWaveAmplitude */ - x2e0_grappleBeamZWaveAmplitude = __dna_reader.readFloatBig(); - /* x2e4_grappleBeamAnglePhaseDelta */ - x2e4_grappleBeamAnglePhaseDelta = __dna_reader.readFloatBig(); - /* x26c_playerHeight */ - x26c_playerHeight = __dna_reader.readFloatBig(); - /* x270_playerXYHalfExtent */ - x270_playerXYHalfExtent = __dna_reader.readFloatBig(); - /* x274_stepUpHeight */ - x274_stepUpHeight = __dna_reader.readFloatBig(); - /* x278_stepDownHeight */ - x278_stepDownHeight = __dna_reader.readFloatBig(); - /* x27c_playerBallHalfExtent */ - x27c_playerBallHalfExtent = __dna_reader.readFloatBig(); - /* x280_ */ - x280_firstPersonCameraSpeed = __dna_reader.readFloatBig(); - /* x284_ */ - x284_ = __dna_reader.readFloatBig(); - /* x288_jumpCameraPitchDownStart */ - x288_jumpCameraPitchDownStart = __dna_reader.readFloatBig(); - /* x28c_jumpCameraPitchDownFull */ - x28c_jumpCameraPitchDownFull = __dna_reader.readFloatBig(); - /* x290_jumpCameraPitchDownAngle */ - x290_jumpCameraPitchDownAngle = __dna_reader.readFloatBig(); - /* x294_fallCameraPitchDownStart */ - x294_fallCameraPitchDownStart = __dna_reader.readFloatBig(); - /* x298_fallCameraPitchDownFull */ - x298_fallCameraPitchDownFull = __dna_reader.readFloatBig(); - /* x29c_fallCameraPitchDownAngle */ - x29c_fallCameraPitchDownAngle = __dna_reader.readFloatBig(); - /* x2e8_ */ - x2e8_ = __dna_reader.readFloatBig(); - /* x2ec_ */ - x2ec_ = __dna_reader.readFloatBig(); - /* x2f0_ */ - x2f0_ = __dna_reader.readFloatBig(); - /* x2f4_ */ - x2f4_ = __dna_reader.readBool(); - /* x2f8_frozenTimeout */ - x2f8_frozenTimeout = __dna_reader.readFloatBig(); - /* x2fc_iceBreakJumpCount */ - x2fc_iceBreakJumpCount = __dna_reader.readUint32Big(); - /* x300_variaDamageReduction */ - x300_variaDamageReduction = __dna_reader.readFloatBig(); - /* x304_gravityDamageReduction */ - x304_gravityDamageReduction = __dna_reader.readFloatBig(); - /* x308_phazonDamageReduction */ - x308_phazonDamageReduction = __dna_reader.readFloatBig(); -} - -template <> -void CTweakPlayer::Enumerate(athena::io::IStreamWriter& __dna_writer) { - /* x4_maxTranslationalAcceleration[0] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[0]); - /* x4_maxTranslationalAcceleration[1] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[1]); - /* x4_maxTranslationalAcceleration[2] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[2]); - /* x4_maxTranslationalAcceleration[3] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[3]); - /* x4_maxTranslationalAcceleration[4] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[4]); - /* x4_maxTranslationalAcceleration[5] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[5]); - /* x4_maxTranslationalAcceleration[6] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[6]); - /* x4_maxTranslationalAcceleration[7] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[7]); - /* x24_maxRotationalAcceleration[0] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[0]); - /* x24_maxRotationalAcceleration[1] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[1]); - /* x24_maxRotationalAcceleration[2] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[2]); - /* x24_maxRotationalAcceleration[3] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[3]); - /* x24_maxRotationalAcceleration[4] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[4]); - /* x24_maxRotationalAcceleration[5] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[5]); - /* x24_maxRotationalAcceleration[6] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[6]); - /* x24_maxRotationalAcceleration[7] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[7]); - /* x44_translationFriction[0] */ - __dna_writer.writeFloatBig(x44_translationFriction[0]); - /* x44_translationFriction[1] */ - __dna_writer.writeFloatBig(x44_translationFriction[1]); - /* x44_translationFriction[2] */ - __dna_writer.writeFloatBig(x44_translationFriction[2]); - /* x44_translationFriction[3] */ - __dna_writer.writeFloatBig(x44_translationFriction[3]); - /* x44_translationFriction[4] */ - __dna_writer.writeFloatBig(x44_translationFriction[4]); - /* x44_translationFriction[5] */ - __dna_writer.writeFloatBig(x44_translationFriction[5]); - /* x44_translationFriction[6] */ - __dna_writer.writeFloatBig(x44_translationFriction[6]); - /* x44_translationFriction[7] */ - __dna_writer.writeFloatBig(x44_translationFriction[7]); - /* x64_rotationFriction[0] */ - __dna_writer.writeFloatBig(x64_rotationFriction[0]); - /* x64_rotationFriction[1] */ - __dna_writer.writeFloatBig(x64_rotationFriction[1]); - /* x64_rotationFriction[2] */ - __dna_writer.writeFloatBig(x64_rotationFriction[2]); - /* x64_rotationFriction[3] */ - __dna_writer.writeFloatBig(x64_rotationFriction[3]); - /* x64_rotationFriction[4] */ - __dna_writer.writeFloatBig(x64_rotationFriction[4]); - /* x64_rotationFriction[5] */ - __dna_writer.writeFloatBig(x64_rotationFriction[5]); - /* x64_rotationFriction[6] */ - __dna_writer.writeFloatBig(x64_rotationFriction[6]); - /* x64_rotationFriction[7] */ - __dna_writer.writeFloatBig(x64_rotationFriction[7]); - /* x84_rotationMaxSpeed[0] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[0]); - /* x84_rotationMaxSpeed[1] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[1]); - /* x84_rotationMaxSpeed[2] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[2]); - /* x84_rotationMaxSpeed[3] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[3]); - /* x84_rotationMaxSpeed[4] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[4]); - /* x84_rotationMaxSpeed[5] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[5]); - /* x84_rotationMaxSpeed[6] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[6]); - /* x84_rotationMaxSpeed[7] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[7]); - /* xa4_translationMaxSpeed[0] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[0]); - /* xa4_translationMaxSpeed[1] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[1]); - /* xa4_translationMaxSpeed[2] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[2]); - /* xa4_translationMaxSpeed[3] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[3]); - /* xa4_translationMaxSpeed[4] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[4]); - /* xa4_translationMaxSpeed[5] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[5]); - /* xa4_translationMaxSpeed[6] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[6]); - /* xa4_translationMaxSpeed[7] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[7]); - /* xc4_normalGravAccel */ - __dna_writer.writeFloatBig(xc4_normalGravAccel); - /* xc8_fluidGravAccel */ - __dna_writer.writeFloatBig(xc8_fluidGravAccel); - /* xcc_verticalJumpAccel */ - __dna_writer.writeFloatBig(xcc_verticalJumpAccel); - /* xd0_horizontalJumpAccel */ - __dna_writer.writeFloatBig(xd0_horizontalJumpAccel); - /* xd4_verticalDoubleJumpAccel */ - __dna_writer.writeFloatBig(xd4_verticalDoubleJumpAccel); - /* xd8_horizontalDoubleJumpAccel */ - __dna_writer.writeFloatBig(xd8_horizontalDoubleJumpAccel); - /* xdc_waterJumpFactor */ - __dna_writer.writeFloatBig(xdc_waterJumpFactor); - /* xe0_waterBallJumpFactor */ - __dna_writer.writeFloatBig(xe0_waterBallJumpFactor); - /* xe4_lavaJumpFactor */ - __dna_writer.writeFloatBig(xe4_lavaJumpFactor); - /* xe8_lavaBallJumpFactor */ - __dna_writer.writeFloatBig(xe8_lavaBallJumpFactor); - /* xec_phazonJumpFactor */ - __dna_writer.writeFloatBig(xec_phazonJumpFactor); - /* xf0_phazonBallJumpFactor */ - __dna_writer.writeFloatBig(xf0_phazonBallJumpFactor); - /* xf4_allowedJumpTime */ - __dna_writer.writeFloatBig(xf4_allowedJumpTime); - /* xf8_allowedDoubleJumpTime */ - __dna_writer.writeFloatBig(xf8_allowedDoubleJumpTime); - /* xfc_minDoubleJumpWindow */ - __dna_writer.writeFloatBig(xfc_minDoubleJumpWindow); - /* x100_maxDoubleJumpWindow */ - __dna_writer.writeFloatBig(x100_maxDoubleJumpWindow); - /* x104_ */ - __dna_writer.writeFloatBig(x104_); - /* x108_minJumpTime */ - __dna_writer.writeFloatBig(x108_minJumpTime); - /* x10c_minDoubleJumpTime */ - __dna_writer.writeFloatBig(x10c_minDoubleJumpTime); - /* x110_allowedLedgeTime */ - __dna_writer.writeFloatBig(x110_allowedLedgeTime); - /* x114_doubleJumpImpulse */ - __dna_writer.writeFloatBig(x114_doubleJumpImpulse); - /* x118_backwardsForceMultiplier */ - __dna_writer.writeFloatBig(x118_backwardsForceMultiplier); - /* x11c_bombJumpRadius */ - __dna_writer.writeFloatBig(x11c_bombJumpRadius); - /* x120_bombJumpHeight */ - __dna_writer.writeFloatBig(x120_bombJumpHeight); - /* x124_eyeOffset */ - __dna_writer.writeFloatBig(x124_eyeOffset); - /* x128_turnSpeedMultiplier */ - __dna_writer.writeFloatBig(x128_turnSpeedMultiplier); - /* x12c_freeLookTurnSpeedMultiplier */ - __dna_writer.writeFloatBig(x12c_freeLookTurnSpeedMultiplier); - /* x130_horizontalFreeLookAngleVel */ - __dna_writer.writeFloatBig(x130_horizontalFreeLookAngleVel); - /* x134_verticalFreeLookAngleVel */ - __dna_writer.writeFloatBig(x134_verticalFreeLookAngleVel); - /* x138_freeLookSpeed */ - __dna_writer.writeFloatBig(x138_freeLookSpeed); - /* x13c_freeLookSnapSpeed */ - __dna_writer.writeFloatBig(x13c_freeLookSnapSpeed); - /* x140_ */ - __dna_writer.writeFloatBig(x140_); - /* x144_freeLookCenteredThresholdAngle */ - __dna_writer.writeFloatBig(x144_freeLookCenteredThresholdAngle); - /* x148_freeLookCenteredTime */ - __dna_writer.writeFloatBig(x148_freeLookCenteredTime); - /* x14c_freeLookDampenFactor */ - __dna_writer.writeFloatBig(x14c_freeLookDampenFactor); - /* x150_leftDiv */ - __dna_writer.writeFloatBig(x150_leftDiv); - /* x154_rightDiv */ - __dna_writer.writeFloatBig(x154_rightDiv); - /* x228_24_freelookTurnsPlayer */ - __dna_writer.writeBool(x228_24_freelookTurnsPlayer); - /* x228_25_ */ - __dna_writer.writeBool(x228_25_); - /* x228_26_ */ - __dna_writer.writeBool(x228_26_); - /* x228_27_moveDuringFreeLook */ - __dna_writer.writeBool(x228_27_moveDuringFreeLook); - /* x228_28_holdButtonsForFreeLook */ - __dna_writer.writeBool(x228_28_holdButtonsForFreeLook); - /* x228_29_twoButtonsForFreeLook */ - __dna_writer.writeBool(x228_29_twoButtonsForFreeLook); - /* x228_30_ */ - __dna_writer.writeBool(x228_30_); - /* x228_31_ */ - __dna_writer.writeBool(x228_31_); - /* x229_24_ */ - __dna_writer.writeBool(x229_24_); - /* x229_25_aimWhenOrbitingPoint */ - __dna_writer.writeBool(x229_25_aimWhenOrbitingPoint); - /* x229_26_stayInFreeLookWhileFiring */ - __dna_writer.writeBool(x229_26_stayInFreeLookWhileFiring); - /* x229_27_ */ - __dna_writer.writeBool(x229_27_); - /* x229_28_ */ - __dna_writer.writeBool(x229_28_); - /* x229_29_orbitFixedOffset */ - __dna_writer.writeBool(x229_29_orbitFixedOffset); - /* x229_30_gunButtonTogglesHolster */ - __dna_writer.writeBool(x229_30_gunButtonTogglesHolster); - /* x229_31_gunNotFiringHolstersGun */ - __dna_writer.writeBool(x229_31_gunNotFiringHolstersGun); - /* x22a_24_fallingDoubleJump */ - __dna_writer.writeBool(x22a_24_fallingDoubleJump); - /* x22a_25_impulseDoubleJump */ - __dna_writer.writeBool(x22a_25_impulseDoubleJump); - /* x22a_26_firingCancelsCameraPitch */ - __dna_writer.writeBool(x22a_26_firingCancelsCameraPitch); - /* x22a_27_assistedAimingIgnoreHorizontal */ - __dna_writer.writeBool(x22a_27_assistedAimingIgnoreHorizontal); - /* x22a_28_assistedAimingIgnoreVertical */ - __dna_writer.writeBool(x22a_28_assistedAimingIgnoreVertical); - /* x22c_ */ - __dna_writer.writeFloatBig(x22c_); - /* x230_ */ - __dna_writer.writeFloatBig(x230_); - /* x234_aimMaxDistance */ - __dna_writer.writeFloatBig(x234_aimMaxDistance); - /* x238_ */ - __dna_writer.writeFloatBig(x238_); - /* x23c_ */ - __dna_writer.writeFloatBig(x23c_); - /* x240_ */ - __dna_writer.writeFloatBig(x240_); - /* x244_ */ - __dna_writer.writeFloatBig(x244_); - /* x248_ */ - __dna_writer.writeFloatBig(x248_); - /* x24c_aimThresholdDistance */ - __dna_writer.writeFloatBig(x24c_aimThresholdDistance); - /* x250_ */ - __dna_writer.writeFloatBig(x250_); - /* x254_ */ - __dna_writer.writeFloatBig(x254_); - /* x258_aimBoxWidth */ - __dna_writer.writeFloatBig(x258_aimBoxWidth); - /* x25c_aimBoxHeight */ - __dna_writer.writeFloatBig(x25c_aimBoxHeight); - /* x260_aimTargetTimer */ - __dna_writer.writeFloatBig(x260_aimTargetTimer); - /* x264_aimAssistHorizontalAngle */ - __dna_writer.writeFloatBig(x264_aimAssistHorizontalAngle); - /* x268_aimAssistVerticalAngle */ - __dna_writer.writeFloatBig(x268_aimAssistVerticalAngle); - /* x158_orbitMinDistance[0] */ - __dna_writer.writeFloatBig(x158_orbitMinDistance[0]); - /* x164_orbitNormalDistance[0] */ - __dna_writer.writeFloatBig(x164_orbitNormalDistance[0]); - /* x170_orbitMaxDistance[0] */ - __dna_writer.writeFloatBig(x170_orbitMaxDistance[0]); - /* x158_orbitMinDistance[1] */ - __dna_writer.writeFloatBig(x158_orbitMinDistance[1]); - /* x164_orbitNormalDistance[1] */ - __dna_writer.writeFloatBig(x164_orbitNormalDistance[1]); - /* x170_orbitMaxDistance[1] */ - __dna_writer.writeFloatBig(x170_orbitMaxDistance[1]); - /* x158_orbitMinDistance[2] */ - __dna_writer.writeFloatBig(x158_orbitMinDistance[2]); - /* x164_orbitNormalDistance[2] */ - __dna_writer.writeFloatBig(x164_orbitNormalDistance[2]); - /* x170_orbitMaxDistance[2] */ - __dna_writer.writeFloatBig(x170_orbitMaxDistance[2]); - /* x17c_ */ - __dna_writer.writeFloatBig(x17c_); - /* x180_orbitModeTimer */ - __dna_writer.writeFloatBig(x180_orbitModeTimer); - /* x184_orbitCameraSpeed */ - __dna_writer.writeFloatBig(x184_orbitCameraSpeed); - /* x188_orbitUpperAngle */ - __dna_writer.writeFloatBig(x188_orbitUpperAngle); - /* x18c_orbitLowerAngle */ - __dna_writer.writeFloatBig(x18c_orbitLowerAngle); - /* x190_orbitHorizAngle */ - __dna_writer.writeFloatBig(x190_orbitHorizAngle); - /* x194_ */ - __dna_writer.writeFloatBig(x194_); - /* x198_ */ - __dna_writer.writeFloatBig(x198_); - /* x19c_orbitMaxTargetDistance */ - __dna_writer.writeFloatBig(x19c_orbitMaxTargetDistance); - /* x1a0_orbitMaxLockDistance */ - __dna_writer.writeFloatBig(x1a0_orbitMaxLockDistance); - /* x1a4_orbitDistanceThreshold */ - __dna_writer.writeFloatBig(x1a4_orbitDistanceThreshold); - /* x1a8_orbitScreenBoxHalfExtentX[0] */ - __dna_writer.writeUint32Big(x1a8_orbitScreenBoxHalfExtentX[0]); - /* x1b0_orbitScreenBoxHalfExtentY[0] */ - __dna_writer.writeUint32Big(x1b0_orbitScreenBoxHalfExtentY[0]); - /* x1b8_orbitScreenBoxCenterX[0] */ - __dna_writer.writeUint32Big(x1b8_orbitScreenBoxCenterX[0]); - /* x1c0_orbitScreenBoxCenterY[0] */ - __dna_writer.writeUint32Big(x1c0_orbitScreenBoxCenterY[0]); - /* x1c8_orbitZoneIdealX[0] */ - __dna_writer.writeUint32Big(x1c8_orbitZoneIdealX[0]); - /* x1d0_orbitZoneIdealY[0] */ - __dna_writer.writeUint32Big(x1d0_orbitZoneIdealY[0]); - /* x1a8_orbitScreenBoxHalfExtentX[1] */ - __dna_writer.writeUint32Big(x1a8_orbitScreenBoxHalfExtentX[1]); - /* x1b0_orbitScreenBoxHalfExtentY[1] */ - __dna_writer.writeUint32Big(x1b0_orbitScreenBoxHalfExtentY[1]); - /* x1b8_orbitScreenBoxCenterX[1] */ - __dna_writer.writeUint32Big(x1b8_orbitScreenBoxCenterX[1]); - /* x1c0_orbitScreenBoxCenterY[1] */ - __dna_writer.writeUint32Big(x1c0_orbitScreenBoxCenterY[1]); - /* x1c8_orbitZoneIdealX[1] */ - __dna_writer.writeUint32Big(x1c8_orbitZoneIdealX[1]); - /* x1d0_orbitZoneIdealY[1] */ - __dna_writer.writeUint32Big(x1d0_orbitZoneIdealY[1]); - /* x1d8_orbitNearX */ - __dna_writer.writeFloatBig(x1d8_orbitNearX); - /* x1dc_orbitNearZ */ - __dna_writer.writeFloatBig(x1dc_orbitNearZ); - /* x1e0_ */ - __dna_writer.writeFloatBig(x1e0_); - /* x1e4_ */ - __dna_writer.writeFloatBig(x1e4_); - /* x1e8_orbitFixedOffsetZDiff */ - __dna_writer.writeFloatBig(x1e8_orbitFixedOffsetZDiff); - /* x1ec_orbitZRange */ - __dna_writer.writeFloatBig(x1ec_orbitZRange); - /* x1f0_ */ - __dna_writer.writeFloatBig(x1f0_); - /* x1f4_ */ - __dna_writer.writeFloatBig(x1f4_); - /* x1f8_ */ - __dna_writer.writeFloatBig(x1f8_); - /* x1fc_orbitPreventionTime */ - __dna_writer.writeFloatBig(x1fc_orbitPreventionTime); - /* x200_24_dashEnabled */ - __dna_writer.writeBool(x200_24_dashEnabled); - /* x200_25_dashOnButtonRelease */ - __dna_writer.writeBool(x200_25_dashOnButtonRelease); - /* x204_dashButtonHoldCancelTime */ - __dna_writer.writeFloatBig(x204_dashButtonHoldCancelTime); - /* x208_dashStrafeInputThreshold */ - __dna_writer.writeFloatBig(x208_dashStrafeInputThreshold); - /* x20c_sidewaysDoubleJumpImpulse */ - __dna_writer.writeFloatBig(x20c_sidewaysDoubleJumpImpulse); - /* x210_sidewaysVerticalDoubleJumpAccel */ - __dna_writer.writeFloatBig(x210_sidewaysVerticalDoubleJumpAccel); - /* x214_sidewaysHorizontalDoubleJumpAccel */ - __dna_writer.writeFloatBig(x214_sidewaysHorizontalDoubleJumpAccel); - /* x218_scanningRange */ - __dna_writer.writeFloatBig(x218_scanningRange); - /* x21c_24_scanRetention */ - __dna_writer.writeBool(x21c_24_scanRetention); - /* x21c_25_scanFreezesGame */ - __dna_writer.writeBool(x21c_25_scanFreezesGame); - /* x21c_26_orbitWhileScanning */ - __dna_writer.writeBool(x21c_26_orbitWhileScanning); - /* x220_scanMaxTargetDistance */ - __dna_writer.writeFloatBig(x220_scanMaxTargetDistance); - /* x224_scanMaxLockDistance */ - __dna_writer.writeFloatBig(x224_scanMaxLockDistance); - /* x2a0_orbitDistanceMax */ - __dna_writer.writeFloatBig(x2a0_orbitDistanceMax); - /* x2a4_grappleSwingLength */ - __dna_writer.writeFloatBig(x2a4_grappleSwingLength); - /* x2a8_grappleSwingPeriod */ - __dna_writer.writeFloatBig(x2a8_grappleSwingPeriod); - /* x2ac_grapplePullSpeedMin */ - __dna_writer.writeFloatBig(x2ac_grapplePullSpeedMin); - /* x2b0_grappleCameraSpeed */ - __dna_writer.writeFloatBig(x2b0_grappleCameraSpeed); - /* x2b4_maxGrappleLockedTurnAlignDistance */ - __dna_writer.writeFloatBig(x2b4_maxGrappleLockedTurnAlignDistance); - /* x2b8_grapplePullSpeedProportion */ - __dna_writer.writeFloatBig(x2b8_grapplePullSpeedProportion); - /* x2bc_grapplePullSpeedMax */ - __dna_writer.writeFloatBig(x2bc_grapplePullSpeedMax); - /* x2c0_grappleLookCenterSpeed */ - __dna_writer.writeFloatBig(x2c0_grappleLookCenterSpeed); - /* x2c4_maxGrappleTurnSpeed */ - __dna_writer.writeFloatBig(x2c4_maxGrappleTurnSpeed); - /* x2c8_grappleJumpForce */ - __dna_writer.writeFloatBig(x2c8_grappleJumpForce); - /* x2cc_grappleReleaseTime */ - __dna_writer.writeFloatBig(x2cc_grappleReleaseTime); - /* x2d0_grappleJumpMode */ - __dna_writer.writeUint32Big(x2d0_grappleJumpMode); - /* x2d4_orbitReleaseBreaksGrapple */ - __dna_writer.writeBool(x2d4_orbitReleaseBreaksGrapple); - /* x2d5_invertGrappleTurn */ - __dna_writer.writeBool(x2d5_invertGrappleTurn); - /* x2d8_grappleBeamSpeed */ - __dna_writer.writeFloatBig(x2d8_grappleBeamSpeed); - /* x2dc_grappleBeamXWaveAmplitude */ - __dna_writer.writeFloatBig(x2dc_grappleBeamXWaveAmplitude); - /* x2e0_grappleBeamZWaveAmplitude */ - __dna_writer.writeFloatBig(x2e0_grappleBeamZWaveAmplitude); - /* x2e4_grappleBeamAnglePhaseDelta */ - __dna_writer.writeFloatBig(x2e4_grappleBeamAnglePhaseDelta); - /* x26c_playerHeight */ - __dna_writer.writeFloatBig(x26c_playerHeight); - /* x270_playerXYHalfExtent */ - __dna_writer.writeFloatBig(x270_playerXYHalfExtent); - /* x274_stepUpHeight */ - __dna_writer.writeFloatBig(x274_stepUpHeight); - /* x278_stepDownHeight */ - __dna_writer.writeFloatBig(x278_stepDownHeight); - /* x27c_playerBallHalfExtent */ - __dna_writer.writeFloatBig(x27c_playerBallHalfExtent); - /* x280_ */ - __dna_writer.writeFloatBig(x280_firstPersonCameraSpeed); - /* x284_ */ - __dna_writer.writeFloatBig(x284_); - /* x288_jumpCameraPitchDownStart */ - __dna_writer.writeFloatBig(x288_jumpCameraPitchDownStart); - /* x28c_jumpCameraPitchDownFull */ - __dna_writer.writeFloatBig(x28c_jumpCameraPitchDownFull); - /* x290_jumpCameraPitchDownAngle */ - __dna_writer.writeFloatBig(x290_jumpCameraPitchDownAngle); - /* x294_fallCameraPitchDownStart */ - __dna_writer.writeFloatBig(x294_fallCameraPitchDownStart); - /* x298_fallCameraPitchDownFull */ - __dna_writer.writeFloatBig(x298_fallCameraPitchDownFull); - /* x29c_fallCameraPitchDownAngle */ - __dna_writer.writeFloatBig(x29c_fallCameraPitchDownAngle); - /* x2e8_ */ - __dna_writer.writeFloatBig(x2e8_); - /* x2ec_ */ - __dna_writer.writeFloatBig(x2ec_); - /* x2f0_ */ - __dna_writer.writeFloatBig(x2f0_); - /* x2f4_ */ - __dna_writer.writeBool(x2f4_); - /* x2f8_frozenTimeout */ - __dna_writer.writeFloatBig(x2f8_frozenTimeout); - /* x2fc_iceBreakJumpCount */ - __dna_writer.writeUint32Big(x2fc_iceBreakJumpCount); - /* x300_variaDamageReduction */ - __dna_writer.writeFloatBig(x300_variaDamageReduction); - /* x304_gravityDamageReduction */ - __dna_writer.writeFloatBig(x304_gravityDamageReduction); - /* x308_phazonDamageReduction */ - __dna_writer.writeFloatBig(x308_phazonDamageReduction); -} - -template <> -void CTweakPlayer::Enumerate(athena::io::YAMLDocReader& __dna_docin) { - /* x4_maxTranslationalAcceleration */ - size_t __x4_Count; - if (auto v = __dna_docin.enterSubVector("x4_maxTranslationalAcceleration", __x4_Count)) { - /* x4_maxTranslationalAcceleration[0] */ - x4_maxTranslationalAcceleration[0] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - /* x4_maxTranslationalAcceleration[1] */ - x4_maxTranslationalAcceleration[1] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - /* x4_maxTranslationalAcceleration[2] */ - x4_maxTranslationalAcceleration[2] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - /* x4_maxTranslationalAcceleration[3] */ - x4_maxTranslationalAcceleration[3] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - /* x4_maxTranslationalAcceleration[4] */ - x4_maxTranslationalAcceleration[4] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - /* x4_maxTranslationalAcceleration[5] */ - x4_maxTranslationalAcceleration[5] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - /* x4_maxTranslationalAcceleration[6] */ - x4_maxTranslationalAcceleration[6] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - /* x4_maxTranslationalAcceleration[7] */ - x4_maxTranslationalAcceleration[7] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - } - /* x24_maxRotationalAcceleration */ - size_t __x24_Count; - if (auto v = __dna_docin.enterSubVector("x24_maxRotationalAcceleration", __x24_Count)) { - /* x24_maxRotationalAcceleration[0] */ - x24_maxRotationalAcceleration[0] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - /* x24_maxRotationalAcceleration[1] */ - x24_maxRotationalAcceleration[1] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - /* x24_maxRotationalAcceleration[2] */ - x24_maxRotationalAcceleration[2] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - /* x24_maxRotationalAcceleration[3] */ - x24_maxRotationalAcceleration[3] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - /* x24_maxRotationalAcceleration[4] */ - x24_maxRotationalAcceleration[4] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - /* x24_maxRotationalAcceleration[5] */ - x24_maxRotationalAcceleration[5] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - /* x24_maxRotationalAcceleration[6] */ - x24_maxRotationalAcceleration[6] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - /* x24_maxRotationalAcceleration[7] */ - x24_maxRotationalAcceleration[7] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - } - /* x44_translationFriction */ - size_t __x44_Count; - if (auto v = __dna_docin.enterSubVector("x44_translationFriction", __x44_Count)) { - /* x44_translationFriction[0] */ - x44_translationFriction[0] = __dna_docin.readFloat("x44_translationFriction"); - /* x44_translationFriction[1] */ - x44_translationFriction[1] = __dna_docin.readFloat("x44_translationFriction"); - /* x44_translationFriction[2] */ - x44_translationFriction[2] = __dna_docin.readFloat("x44_translationFriction"); - /* x44_translationFriction[3] */ - x44_translationFriction[3] = __dna_docin.readFloat("x44_translationFriction"); - /* x44_translationFriction[4] */ - x44_translationFriction[4] = __dna_docin.readFloat("x44_translationFriction"); - /* x44_translationFriction[5] */ - x44_translationFriction[5] = __dna_docin.readFloat("x44_translationFriction"); - /* x44_translationFriction[6] */ - x44_translationFriction[6] = __dna_docin.readFloat("x44_translationFriction"); - /* x44_translationFriction[7] */ - x44_translationFriction[7] = __dna_docin.readFloat("x44_translationFriction"); - } - /* x64_rotationFriction */ - size_t __x64_Count; - if (auto v = __dna_docin.enterSubVector("x64_rotationFriction", __x64_Count)) { - /* x64_rotationFriction[0] */ - x64_rotationFriction[0] = __dna_docin.readFloat("x64_rotationFriction"); - /* x64_rotationFriction[1] */ - x64_rotationFriction[1] = __dna_docin.readFloat("x64_rotationFriction"); - /* x64_rotationFriction[2] */ - x64_rotationFriction[2] = __dna_docin.readFloat("x64_rotationFriction"); - /* x64_rotationFriction[3] */ - x64_rotationFriction[3] = __dna_docin.readFloat("x64_rotationFriction"); - /* x64_rotationFriction[4] */ - x64_rotationFriction[4] = __dna_docin.readFloat("x64_rotationFriction"); - /* x64_rotationFriction[5] */ - x64_rotationFriction[5] = __dna_docin.readFloat("x64_rotationFriction"); - /* x64_rotationFriction[6] */ - x64_rotationFriction[6] = __dna_docin.readFloat("x64_rotationFriction"); - /* x64_rotationFriction[7] */ - x64_rotationFriction[7] = __dna_docin.readFloat("x64_rotationFriction"); - } - /* x84_rotationMaxSpeed */ - size_t __x84_Count; - if (auto v = __dna_docin.enterSubVector("x84_rotationMaxSpeed", __x84_Count)) { - /* x84_rotationMaxSpeed[0] */ - x84_rotationMaxSpeed[0] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - /* x84_rotationMaxSpeed[1] */ - x84_rotationMaxSpeed[1] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - /* x84_rotationMaxSpeed[2] */ - x84_rotationMaxSpeed[2] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - /* x84_rotationMaxSpeed[3] */ - x84_rotationMaxSpeed[3] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - /* x84_rotationMaxSpeed[4] */ - x84_rotationMaxSpeed[4] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - /* x84_rotationMaxSpeed[5] */ - x84_rotationMaxSpeed[5] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - /* x84_rotationMaxSpeed[6] */ - x84_rotationMaxSpeed[6] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - /* x84_rotationMaxSpeed[7] */ - x84_rotationMaxSpeed[7] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - } - /* xa4_translationMaxSpeed */ - size_t __xa4_Count; - if (auto v = __dna_docin.enterSubVector("xa4_translationMaxSpeed", __xa4_Count)) { - /* xa4_translationMaxSpeed[0] */ - xa4_translationMaxSpeed[0] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - /* xa4_translationMaxSpeed[1] */ - xa4_translationMaxSpeed[1] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - /* xa4_translationMaxSpeed[2] */ - xa4_translationMaxSpeed[2] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - /* xa4_translationMaxSpeed[3] */ - xa4_translationMaxSpeed[3] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - /* xa4_translationMaxSpeed[4] */ - xa4_translationMaxSpeed[4] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - /* xa4_translationMaxSpeed[5] */ - xa4_translationMaxSpeed[5] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - /* xa4_translationMaxSpeed[6] */ - xa4_translationMaxSpeed[6] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - /* xa4_translationMaxSpeed[7] */ - xa4_translationMaxSpeed[7] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - } - /* xc4_normalGravAccel */ - xc4_normalGravAccel = __dna_docin.readFloat("xc4_normalGravAccel"); - /* xc8_fluidGravAccel */ - xc8_fluidGravAccel = __dna_docin.readFloat("xc8_fluidGravAccel"); - /* xcc_verticalJumpAccel */ - xcc_verticalJumpAccel = __dna_docin.readFloat("xcc_verticalJumpAccel"); - /* xd0_horizontalJumpAccel */ - xd0_horizontalJumpAccel = __dna_docin.readFloat("xd0_horizontalJumpAccel"); - /* xd4_verticalDoubleJumpAccel */ - xd4_verticalDoubleJumpAccel = __dna_docin.readFloat("xd4_verticalDoubleJumpAccel"); - /* xd8_horizontalDoubleJumpAccel */ - xd8_horizontalDoubleJumpAccel = __dna_docin.readFloat("xd8_horizontalDoubleJumpAccel"); - /* xdc_waterJumpFactor */ - xdc_waterJumpFactor = __dna_docin.readFloat("xdc_waterJumpFactor"); - /* xe0_waterBallJumpFactor */ - xe0_waterBallJumpFactor = __dna_docin.readFloat("xe0_waterBallJumpFactor"); - /* xe4_lavaJumpFactor */ - xe4_lavaJumpFactor = __dna_docin.readFloat("xe4_lavaJumpFactor"); - /* xe8_lavaBallJumpFactor */ - xe8_lavaBallJumpFactor = __dna_docin.readFloat("xe8_lavaBallJumpFactor"); - /* xec_phazonJumpFactor */ - xec_phazonJumpFactor = __dna_docin.readFloat("xec_phazonJumpFactor"); - /* xf0_phazonBallJumpFactor */ - xf0_phazonBallJumpFactor = __dna_docin.readFloat("xf0_phazonBallJumpFactor"); - /* xf4_allowedJumpTime */ - xf4_allowedJumpTime = __dna_docin.readFloat("xf4_allowedJumpTime"); - /* xf8_allowedDoubleJumpTime */ - xf8_allowedDoubleJumpTime = __dna_docin.readFloat("xf8_allowedDoubleJumpTime"); - /* xfc_minDoubleJumpWindow */ - xfc_minDoubleJumpWindow = __dna_docin.readFloat("xfc_minDoubleJumpWindow"); - /* x100_maxDoubleJumpWindow */ - x100_maxDoubleJumpWindow = __dna_docin.readFloat("x100_maxDoubleJumpWindow"); - /* x104_ */ - x104_ = __dna_docin.readFloat("x104_"); - /* x108_minJumpTime */ - x108_minJumpTime = __dna_docin.readFloat("x108_minJumpTime"); - /* x10c_minDoubleJumpTime */ - x10c_minDoubleJumpTime = __dna_docin.readFloat("x10c_minDoubleJumpTime"); - /* x110_allowedLedgeTime */ - x110_allowedLedgeTime = __dna_docin.readFloat("x110_allowedLedgeTime"); - /* x114_doubleJumpImpulse */ - x114_doubleJumpImpulse = __dna_docin.readFloat("x114_doubleJumpImpulse"); - /* x118_backwardsForceMultiplier */ - x118_backwardsForceMultiplier = __dna_docin.readFloat("x118_backwardsForceMultiplier"); - /* x11c_bombJumpRadius */ - x11c_bombJumpRadius = __dna_docin.readFloat("x11c_bombJumpRadius"); - /* x120_bombJumpHeight */ - x120_bombJumpHeight = __dna_docin.readFloat("x120_bombJumpHeight"); - /* x124_eyeOffset */ - x124_eyeOffset = __dna_docin.readFloat("x124_eyeOffset"); - /* x128_turnSpeedMultiplier */ - x128_turnSpeedMultiplier = __dna_docin.readFloat("x128_turnSpeedMultiplier"); - /* x12c_freeLookTurnSpeedMultiplier */ - x12c_freeLookTurnSpeedMultiplier = __dna_docin.readFloat("x12c_freeLookTurnSpeedMultiplier"); - /* x130_horizontalFreeLookAngleVel */ - x130_horizontalFreeLookAngleVel = __dna_docin.readFloat("x130_horizontalFreeLookAngleVel"); - /* x134_verticalFreeLookAngleVel */ - x134_verticalFreeLookAngleVel = __dna_docin.readFloat("x134_verticalFreeLookAngleVel"); - /* x138_freeLookSpeed */ - x138_freeLookSpeed = __dna_docin.readFloat("x138_freeLookSpeed"); - /* x13c_freeLookSnapSpeed */ - x13c_freeLookSnapSpeed = __dna_docin.readFloat("x13c_freeLookSnapSpeed"); - /* x140_ */ - x140_ = __dna_docin.readFloat("x140_"); - /* x144_freeLookCenteredThresholdAngle */ - x144_freeLookCenteredThresholdAngle = __dna_docin.readFloat("x144_freeLookCenteredThresholdAngle"); - /* x148_freeLookCenteredTime */ - x148_freeLookCenteredTime = __dna_docin.readFloat("x148_freeLookCenteredTime"); - /* x14c_freeLookDampenFactor */ - x14c_freeLookDampenFactor = __dna_docin.readFloat("x14c_freeLookDampenFactor"); - /* x150_leftDiv */ - x150_leftDiv = __dna_docin.readFloat("x150_leftDiv"); - /* x154_rightDiv */ - x154_rightDiv = __dna_docin.readFloat("x154_rightDiv"); - /* x228_24_freelookTurnsPlayer */ - x228_24_freelookTurnsPlayer = __dna_docin.readBool("x228_24_freelookTurnsPlayer"); - /* x228_25_ */ - x228_25_ = __dna_docin.readBool("x228_25_"); - /* x228_26_ */ - x228_26_ = __dna_docin.readBool("x228_26_"); - /* x228_27_moveDuringFreeLook */ - x228_27_moveDuringFreeLook = __dna_docin.readBool("x228_27_moveDuringFreeLook"); - /* x228_28_holdButtonsForFreeLook */ - x228_28_holdButtonsForFreeLook = __dna_docin.readBool("x228_28_holdButtonsForFreeLook"); - /* x228_29_twoButtonsForFreeLook */ - x228_29_twoButtonsForFreeLook = __dna_docin.readBool("x228_29_twoButtonsForFreeLook"); - /* x228_30_ */ - x228_30_ = __dna_docin.readBool("x228_30_"); - /* x228_31_ */ - x228_31_ = __dna_docin.readBool("x228_31_"); - /* x229_24_ */ - x229_24_ = __dna_docin.readBool("x229_24_"); - /* x229_25_aimWhenOrbitingPoint */ - x229_25_aimWhenOrbitingPoint = __dna_docin.readBool("x229_25_aimWhenOrbitingPoint"); - /* x229_26_stayInFreeLookWhileFiring */ - x229_26_stayInFreeLookWhileFiring = __dna_docin.readBool("x229_26_stayInFreeLookWhileFiring"); - /* x229_27_ */ - x229_27_ = __dna_docin.readBool("x229_27_"); - /* x229_28_ */ - x229_28_ = __dna_docin.readBool("x229_28_"); - /* x229_29_orbitFixedOffset */ - x229_29_orbitFixedOffset = __dna_docin.readBool("x229_29_orbitFixedOffset"); - /* x229_30_gunButtonTogglesHolster */ - x229_30_gunButtonTogglesHolster = __dna_docin.readBool("x229_30_gunButtonTogglesHolster"); - /* x229_31_gunNotFiringHolstersGun */ - x229_31_gunNotFiringHolstersGun = __dna_docin.readBool("x229_31_gunNotFiringHolstersGun"); - /* x22a_24_fallingDoubleJump */ - x22a_24_fallingDoubleJump = __dna_docin.readBool("x22a_24_fallingDoubleJump"); - /* x22a_25_impulseDoubleJump */ - x22a_25_impulseDoubleJump = __dna_docin.readBool("x22a_25_impulseDoubleJump"); - /* x22a_26_firingCancelsCameraPitch */ - x22a_26_firingCancelsCameraPitch = __dna_docin.readBool("x22a_26_firingCancelsCameraPitch"); - /* x22a_27_assistedAimingIgnoreHorizontal */ - x22a_27_assistedAimingIgnoreHorizontal = __dna_docin.readBool("x22a_27_assistedAimingIgnoreHorizontal"); - /* x22a_28_assistedAimingIgnoreVertical */ - x22a_28_assistedAimingIgnoreVertical = __dna_docin.readBool("x22a_28_assistedAimingIgnoreVertical"); - /* x22c_ */ - x22c_ = __dna_docin.readFloat("x22c_"); - /* x230_ */ - x230_ = __dna_docin.readFloat("x230_"); - /* x234_aimMaxDistance */ - x234_aimMaxDistance = __dna_docin.readFloat("x234_aimMaxDistance"); - /* x238_ */ - x238_ = __dna_docin.readFloat("x238_"); - /* x23c_ */ - x23c_ = __dna_docin.readFloat("x23c_"); - /* x240_ */ - x240_ = __dna_docin.readFloat("x240_"); - /* x244_ */ - x244_ = __dna_docin.readFloat("x244_"); - /* x248_ */ - x248_ = __dna_docin.readFloat("x248_"); - /* x24c_aimThresholdDistance */ - x24c_aimThresholdDistance = __dna_docin.readFloat("x24c_aimThresholdDistance"); - /* x250_ */ - x250_ = __dna_docin.readFloat("x250_"); - /* x254_ */ - x254_ = __dna_docin.readFloat("x254_"); - /* x258_aimBoxWidth */ - x258_aimBoxWidth = __dna_docin.readFloat("x258_aimBoxWidth"); - /* x25c_aimBoxHeight */ - x25c_aimBoxHeight = __dna_docin.readFloat("x25c_aimBoxHeight"); - /* x260_aimTargetTimer */ - x260_aimTargetTimer = __dna_docin.readFloat("x260_aimTargetTimer"); - /* x264_aimAssistHorizontalAngle */ - x264_aimAssistHorizontalAngle = __dna_docin.readFloat("x264_aimAssistHorizontalAngle"); - /* x268_aimAssistVerticalAngle */ - x268_aimAssistVerticalAngle = __dna_docin.readFloat("x268_aimAssistVerticalAngle"); - /* x158_orbitMinDistance */ - size_t __x158_Count; - if (auto v = __dna_docin.enterSubVector("x158_orbitMinDistance", __x158_Count)) { - /* x158_orbitMinDistance[0] */ - x158_orbitMinDistance[0] = __dna_docin.readFloat("x158_orbitMinDistance"); - /* x158_orbitMinDistance[1] */ - x158_orbitMinDistance[1] = __dna_docin.readFloat("x158_orbitMinDistance"); - /* x158_orbitMinDistance[2] */ - x158_orbitMinDistance[2] = __dna_docin.readFloat("x158_orbitMinDistance"); - } - /* x164_orbitNormalDistance */ - size_t __x164_Count; - if (auto v = __dna_docin.enterSubVector("x164_orbitNormalDistance", __x164_Count)) { - /* x164_orbitNormalDistance[0] */ - x164_orbitNormalDistance[0] = __dna_docin.readFloat("x164_orbitNormalDistance"); - /* x164_orbitNormalDistance[1] */ - x164_orbitNormalDistance[1] = __dna_docin.readFloat("x164_orbitNormalDistance"); - /* x164_orbitNormalDistance[2] */ - x164_orbitNormalDistance[2] = __dna_docin.readFloat("x164_orbitNormalDistance"); - } - /* x170_orbitMaxDistance */ - size_t __x170_Count; - if (auto v = __dna_docin.enterSubVector("x170_orbitMaxDistance", __x170_Count)) { - /* x170_orbitMaxDistance[0] */ - x170_orbitMaxDistance[0] = __dna_docin.readFloat("x170_orbitMaxDistance"); - /* x170_orbitMaxDistance[1] */ - x170_orbitMaxDistance[1] = __dna_docin.readFloat("x170_orbitMaxDistance"); - /* x170_orbitMaxDistance[2] */ - x170_orbitMaxDistance[2] = __dna_docin.readFloat("x170_orbitMaxDistance"); - } - /* x17c_ */ - x17c_ = __dna_docin.readFloat("x17c_"); - /* x180_orbitModeTimer */ - x180_orbitModeTimer = __dna_docin.readFloat("x180_orbitModeTimer"); - /* x184_orbitCameraSpeed */ - x184_orbitCameraSpeed = __dna_docin.readFloat("x184_orbitCameraSpeed"); - /* x188_orbitUpperAngle */ - x188_orbitUpperAngle = __dna_docin.readFloat("x188_orbitUpperAngle"); - /* x18c_orbitLowerAngle */ - x18c_orbitLowerAngle = __dna_docin.readFloat("x18c_orbitLowerAngle"); - /* x190_orbitHorizAngle */ - x190_orbitHorizAngle = __dna_docin.readFloat("x190_orbitHorizAngle"); - /* x194_ */ - x194_ = __dna_docin.readFloat("x194_"); - /* x198_ */ - x198_ = __dna_docin.readFloat("x198_"); - /* x19c_orbitMaxTargetDistance */ - x19c_orbitMaxTargetDistance = __dna_docin.readFloat("x19c_orbitMaxTargetDistance"); - /* x1a0_orbitMaxLockDistance */ - x1a0_orbitMaxLockDistance = __dna_docin.readFloat("x1a0_orbitMaxLockDistance"); - /* x1a4_orbitDistanceThreshold */ - x1a4_orbitDistanceThreshold = __dna_docin.readFloat("x1a4_orbitDistanceThreshold"); - /* x1a8_orbitScreenBoxHalfExtentX */ - size_t __x1a8_Count; - if (auto v = __dna_docin.enterSubVector("x1a8_orbitScreenBoxHalfExtentX", __x1a8_Count)) { - /* x1a8_orbitScreenBoxHalfExtentX[0] */ - x1a8_orbitScreenBoxHalfExtentX[0] = __dna_docin.readUint32("x1a8_orbitScreenBoxHalfExtentX"); - /* x1a8_orbitScreenBoxHalfExtentX[1] */ - x1a8_orbitScreenBoxHalfExtentX[1] = __dna_docin.readUint32("x1a8_orbitScreenBoxHalfExtentX"); - } - /* x1b0_orbitScreenBoxHalfExtentY */ - size_t __x1b0_Count; - if (auto v = __dna_docin.enterSubVector("x1b0_orbitScreenBoxHalfExtentY", __x1b0_Count)) { - /* x1b0_orbitScreenBoxHalfExtentY[0] */ - x1b0_orbitScreenBoxHalfExtentY[0] = __dna_docin.readUint32("x1b0_orbitScreenBoxHalfExtentY"); - /* x1b0_orbitScreenBoxHalfExtentY[1] */ - x1b0_orbitScreenBoxHalfExtentY[1] = __dna_docin.readUint32("x1b0_orbitScreenBoxHalfExtentY"); - } - /* x1b8_orbitScreenBoxCenterX */ - size_t __x1b8_Count; - if (auto v = __dna_docin.enterSubVector("x1b8_orbitScreenBoxCenterX", __x1b8_Count)) { - /* x1b8_orbitScreenBoxCenterX[0] */ - x1b8_orbitScreenBoxCenterX[0] = __dna_docin.readUint32("x1b8_orbitScreenBoxCenterX"); - /* x1b8_orbitScreenBoxCenterX[1] */ - x1b8_orbitScreenBoxCenterX[1] = __dna_docin.readUint32("x1b8_orbitScreenBoxCenterX"); - } - /* x1c0_orbitScreenBoxCenterY */ - size_t __x1c0_Count; - if (auto v = __dna_docin.enterSubVector("x1c0_orbitScreenBoxCenterY", __x1c0_Count)) { - /* x1c0_orbitScreenBoxCenterY[0] */ - x1c0_orbitScreenBoxCenterY[0] = __dna_docin.readUint32("x1c0_orbitScreenBoxCenterY"); - /* x1c0_orbitScreenBoxCenterY[1] */ - x1c0_orbitScreenBoxCenterY[1] = __dna_docin.readUint32("x1c0_orbitScreenBoxCenterY"); - } - /* x1c8_orbitZoneIdealX */ - size_t __x1c8_Count; - if (auto v = __dna_docin.enterSubVector("x1c8_orbitZoneIdealX", __x1c8_Count)) { - /* x1c8_orbitZoneIdealX[0] */ - x1c8_orbitZoneIdealX[0] = __dna_docin.readUint32("x1c8_orbitZoneIdealX"); - /* x1c8_orbitZoneIdealX[1] */ - x1c8_orbitZoneIdealX[1] = __dna_docin.readUint32("x1c8_orbitZoneIdealX"); - } - /* x1d0_orbitZoneIdealY */ - size_t __x1d0_Count; - if (auto v = __dna_docin.enterSubVector("x1d0_orbitZoneIdealY", __x1d0_Count)) { - /* x1d0_orbitZoneIdealY[0] */ - x1d0_orbitZoneIdealY[0] = __dna_docin.readUint32("x1d0_orbitZoneIdealY"); - /* x1d0_orbitZoneIdealY[1] */ - x1d0_orbitZoneIdealY[1] = __dna_docin.readUint32("x1d0_orbitZoneIdealY"); - } - /* x1d8_orbitNearX */ - x1d8_orbitNearX = __dna_docin.readFloat("x1d8_orbitNearX"); - /* x1dc_orbitNearZ */ - x1dc_orbitNearZ = __dna_docin.readFloat("x1dc_orbitNearZ"); - /* x1e0_ */ - x1e0_ = __dna_docin.readFloat("x1e0_"); - /* x1e4_ */ - x1e4_ = __dna_docin.readFloat("x1e4_"); - /* x1e8_orbitFixedOffsetZDiff */ - x1e8_orbitFixedOffsetZDiff = __dna_docin.readFloat("x1e8_orbitFixedOffsetZDiff"); - /* x1ec_orbitZRange */ - x1ec_orbitZRange = __dna_docin.readFloat("x1ec_orbitZRange"); - /* x1f0_ */ - x1f0_ = __dna_docin.readFloat("x1f0_"); - /* x1f4_ */ - x1f4_ = __dna_docin.readFloat("x1f4_"); - /* x1f8_ */ - x1f8_ = __dna_docin.readFloat("x1f8_"); - /* x1fc_orbitPreventionTime */ - x1fc_orbitPreventionTime = __dna_docin.readFloat("x1fc_orbitPreventionTime"); - /* x200_24_dashEnabled */ - x200_24_dashEnabled = __dna_docin.readBool("x200_24_dashEnabled"); - /* x200_25_dashOnButtonRelease */ - x200_25_dashOnButtonRelease = __dna_docin.readBool("x200_25_dashOnButtonRelease"); - /* x204_dashButtonHoldCancelTime */ - x204_dashButtonHoldCancelTime = __dna_docin.readFloat("x204_dashButtonHoldCancelTime"); - /* x208_dashStrafeInputThreshold */ - x208_dashStrafeInputThreshold = __dna_docin.readFloat("x208_dashStrafeInputThreshold"); - /* x20c_sidewaysDoubleJumpImpulse */ - x20c_sidewaysDoubleJumpImpulse = __dna_docin.readFloat("x20c_sidewaysDoubleJumpImpulse"); - /* x210_sidewaysVerticalDoubleJumpAccel */ - x210_sidewaysVerticalDoubleJumpAccel = __dna_docin.readFloat("x210_sidewaysVerticalDoubleJumpAccel"); - /* x214_sidewaysHorizontalDoubleJumpAccel */ - x214_sidewaysHorizontalDoubleJumpAccel = __dna_docin.readFloat("x214_sidewaysHorizontalDoubleJumpAccel"); - /* x218_scanningRange */ - x218_scanningRange = __dna_docin.readFloat("x218_scanningRange"); - /* x21c_24_scanRetention */ - x21c_24_scanRetention = __dna_docin.readBool("x21c_24_scanRetention"); - /* x21c_25_scanFreezesGame */ - x21c_25_scanFreezesGame = __dna_docin.readBool("x21c_25_scanFreezesGame"); - /* x21c_26_orbitWhileScanning */ - x21c_26_orbitWhileScanning = __dna_docin.readBool("x21c_26_orbitWhileScanning"); - /* x220_scanMaxTargetDistance */ - x220_scanMaxTargetDistance = __dna_docin.readFloat("x220_scanMaxTargetDistance"); - /* x224_scanMaxLockDistance */ - x224_scanMaxLockDistance = __dna_docin.readFloat("x224_scanMaxLockDistance"); - /* x2a0_orbitDistanceMax */ - x2a0_orbitDistanceMax = __dna_docin.readFloat("x2a0_orbitDistanceMax"); - /* x2a4_grappleSwingLength */ - x2a4_grappleSwingLength = __dna_docin.readFloat("x2a4_grappleSwingLength"); - /* x2a8_grappleSwingPeriod */ - x2a8_grappleSwingPeriod = __dna_docin.readFloat("x2a8_grappleSwingPeriod"); - /* x2ac_grapplePullSpeedMin */ - x2ac_grapplePullSpeedMin = __dna_docin.readFloat("x2ac_grapplePullSpeedMin"); - /* x2b0_grappleCameraSpeed */ - x2b0_grappleCameraSpeed = __dna_docin.readFloat("x2b0_grappleCameraSpeed"); - /* x2b4_maxGrappleLockedTurnAlignDistance */ - x2b4_maxGrappleLockedTurnAlignDistance = __dna_docin.readFloat("x2b4_maxGrappleLockedTurnAlignDistance"); - /* x2b8_grapplePullSpeedProportion */ - x2b8_grapplePullSpeedProportion = __dna_docin.readFloat("x2b8_grapplePullSpeedProportion"); - /* x2bc_grapplePullSpeedMax */ - x2bc_grapplePullSpeedMax = __dna_docin.readFloat("x2bc_grapplePullSpeedMax"); - /* x2c0_grappleLookCenterSpeed */ - x2c0_grappleLookCenterSpeed = __dna_docin.readFloat("x2c0_grappleLookCenterSpeed"); - /* x2c4_maxGrappleTurnSpeed */ - x2c4_maxGrappleTurnSpeed = __dna_docin.readFloat("x2c4_maxGrappleTurnSpeed"); - /* x2c8_grappleJumpForce */ - x2c8_grappleJumpForce = __dna_docin.readFloat("x2c8_grappleJumpForce"); - /* x2cc_grappleReleaseTime */ - x2cc_grappleReleaseTime = __dna_docin.readFloat("x2cc_grappleReleaseTime"); - /* x2d0_grappleJumpMode */ - x2d0_grappleJumpMode = __dna_docin.readUint32("x2d0_grappleJumpMode"); - /* x2d4_orbitReleaseBreaksGrapple */ - x2d4_orbitReleaseBreaksGrapple = __dna_docin.readBool("x2d4_orbitReleaseBreaksGrapple"); - /* x2d5_invertGrappleTurn */ - x2d5_invertGrappleTurn = __dna_docin.readBool("x2d5_invertGrappleTurn"); - /* x2d8_grappleBeamSpeed */ - x2d8_grappleBeamSpeed = __dna_docin.readFloat("x2d8_grappleBeamSpeed"); - /* x2dc_grappleBeamXWaveAmplitude */ - x2dc_grappleBeamXWaveAmplitude = __dna_docin.readFloat("x2dc_grappleBeamXWaveAmplitude"); - /* x2e0_grappleBeamZWaveAmplitude */ - x2e0_grappleBeamZWaveAmplitude = __dna_docin.readFloat("x2e0_grappleBeamZWaveAmplitude"); - /* x2e4_grappleBeamAnglePhaseDelta */ - x2e4_grappleBeamAnglePhaseDelta = __dna_docin.readFloat("x2e4_grappleBeamAnglePhaseDelta"); - /* x26c_playerHeight */ - x26c_playerHeight = __dna_docin.readFloat("x26c_playerHeight"); - /* x270_playerXYHalfExtent */ - x270_playerXYHalfExtent = __dna_docin.readFloat("x270_playerXYHalfExtent"); - /* x274_stepUpHeight */ - x274_stepUpHeight = __dna_docin.readFloat("x274_stepUpHeight"); - /* x278_stepDownHeight */ - x278_stepDownHeight = __dna_docin.readFloat("x278_stepDownHeight"); - /* x27c_playerBallHalfExtent */ - x27c_playerBallHalfExtent = __dna_docin.readFloat("x27c_playerBallHalfExtent"); - /* x280_ */ - x280_firstPersonCameraSpeed = __dna_docin.readFloat("x280_"); - /* x284_ */ - x284_ = __dna_docin.readFloat("x284_"); - /* x288_jumpCameraPitchDownStart */ - x288_jumpCameraPitchDownStart = __dna_docin.readFloat("x288_jumpCameraPitchDownStart"); - /* x28c_jumpCameraPitchDownFull */ - x28c_jumpCameraPitchDownFull = __dna_docin.readFloat("x28c_jumpCameraPitchDownFull"); - /* x290_jumpCameraPitchDownAngle */ - x290_jumpCameraPitchDownAngle = __dna_docin.readFloat("x290_jumpCameraPitchDownAngle"); - /* x294_fallCameraPitchDownStart */ - x294_fallCameraPitchDownStart = __dna_docin.readFloat("x294_fallCameraPitchDownStart"); - /* x298_fallCameraPitchDownFull */ - x298_fallCameraPitchDownFull = __dna_docin.readFloat("x298_fallCameraPitchDownFull"); - /* x29c_fallCameraPitchDownAngle */ - x29c_fallCameraPitchDownAngle = __dna_docin.readFloat("x29c_fallCameraPitchDownAngle"); - /* x2e8_ */ - x2e8_ = __dna_docin.readFloat("x2e8_"); - /* x2ec_ */ - x2ec_ = __dna_docin.readFloat("x2ec_"); - /* x2f0_ */ - x2f0_ = __dna_docin.readFloat("x2f0_"); - /* x2f4_ */ - x2f4_ = __dna_docin.readBool("x2f4_"); - /* x2f8_frozenTimeout */ - x2f8_frozenTimeout = __dna_docin.readFloat("x2f8_frozenTimeout"); - /* x2fc_iceBreakJumpCount */ - x2fc_iceBreakJumpCount = __dna_docin.readUint32("x2fc_iceBreakJumpCount"); - /* x300_variaDamageReduction */ - x300_variaDamageReduction = __dna_docin.readFloat("x300_variaDamageReduction"); - /* x304_gravityDamageReduction */ - x304_gravityDamageReduction = __dna_docin.readFloat("x304_gravityDamageReduction"); - /* x308_phazonDamageReduction */ - x308_phazonDamageReduction = __dna_docin.readFloat("x308_phazonDamageReduction"); -} - -template <> -void CTweakPlayer::Enumerate(athena::io::YAMLDocWriter& __dna_docout) { - /* x4_maxTranslationalAcceleration */ - if (auto v = __dna_docout.enterSubVector("x4_maxTranslationalAcceleration")) { - /* x4_maxTranslationalAcceleration[0] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[0]); - /* x4_maxTranslationalAcceleration[1] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[1]); - /* x4_maxTranslationalAcceleration[2] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[2]); - /* x4_maxTranslationalAcceleration[3] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[3]); - /* x4_maxTranslationalAcceleration[4] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[4]); - /* x4_maxTranslationalAcceleration[5] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[5]); - /* x4_maxTranslationalAcceleration[6] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[6]); - /* x4_maxTranslationalAcceleration[7] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[7]); - } - /* x24_maxRotationalAcceleration */ - if (auto v = __dna_docout.enterSubVector("x24_maxRotationalAcceleration")) { - /* x24_maxRotationalAcceleration[0] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[0]); - /* x24_maxRotationalAcceleration[1] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[1]); - /* x24_maxRotationalAcceleration[2] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[2]); - /* x24_maxRotationalAcceleration[3] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[3]); - /* x24_maxRotationalAcceleration[4] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[4]); - /* x24_maxRotationalAcceleration[5] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[5]); - /* x24_maxRotationalAcceleration[6] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[6]); - /* x24_maxRotationalAcceleration[7] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[7]); - } - /* x44_translationFriction */ - if (auto v = __dna_docout.enterSubVector("x44_translationFriction")) { - /* x44_translationFriction[0] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[0]); - /* x44_translationFriction[1] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[1]); - /* x44_translationFriction[2] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[2]); - /* x44_translationFriction[3] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[3]); - /* x44_translationFriction[4] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[4]); - /* x44_translationFriction[5] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[5]); - /* x44_translationFriction[6] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[6]); - /* x44_translationFriction[7] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[7]); - } - /* x64_rotationFriction */ - if (auto v = __dna_docout.enterSubVector("x64_rotationFriction")) { - /* x64_rotationFriction[0] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[0]); - /* x64_rotationFriction[1] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[1]); - /* x64_rotationFriction[2] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[2]); - /* x64_rotationFriction[3] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[3]); - /* x64_rotationFriction[4] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[4]); - /* x64_rotationFriction[5] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[5]); - /* x64_rotationFriction[6] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[6]); - /* x64_rotationFriction[7] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[7]); - } - /* x84_rotationMaxSpeed */ - if (auto v = __dna_docout.enterSubVector("x84_rotationMaxSpeed")) { - /* x84_rotationMaxSpeed[0] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[0]); - /* x84_rotationMaxSpeed[1] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[1]); - /* x84_rotationMaxSpeed[2] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[2]); - /* x84_rotationMaxSpeed[3] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[3]); - /* x84_rotationMaxSpeed[4] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[4]); - /* x84_rotationMaxSpeed[5] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[5]); - /* x84_rotationMaxSpeed[6] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[6]); - /* x84_rotationMaxSpeed[7] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[7]); - } - /* xa4_translationMaxSpeed */ - if (auto v = __dna_docout.enterSubVector("xa4_translationMaxSpeed")) { - /* xa4_translationMaxSpeed[0] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[0]); - /* xa4_translationMaxSpeed[1] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[1]); - /* xa4_translationMaxSpeed[2] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[2]); - /* xa4_translationMaxSpeed[3] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[3]); - /* xa4_translationMaxSpeed[4] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[4]); - /* xa4_translationMaxSpeed[5] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[5]); - /* xa4_translationMaxSpeed[6] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[6]); - /* xa4_translationMaxSpeed[7] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[7]); - } - /* xc4_normalGravAccel */ - __dna_docout.writeFloat("xc4_normalGravAccel", xc4_normalGravAccel); - /* xc8_fluidGravAccel */ - __dna_docout.writeFloat("xc8_fluidGravAccel", xc8_fluidGravAccel); - /* xcc_verticalJumpAccel */ - __dna_docout.writeFloat("xcc_verticalJumpAccel", xcc_verticalJumpAccel); - /* xd0_horizontalJumpAccel */ - __dna_docout.writeFloat("xd0_horizontalJumpAccel", xd0_horizontalJumpAccel); - /* xd4_verticalDoubleJumpAccel */ - __dna_docout.writeFloat("xd4_verticalDoubleJumpAccel", xd4_verticalDoubleJumpAccel); - /* xd8_horizontalDoubleJumpAccel */ - __dna_docout.writeFloat("xd8_horizontalDoubleJumpAccel", xd8_horizontalDoubleJumpAccel); - /* xdc_waterJumpFactor */ - __dna_docout.writeFloat("xdc_waterJumpFactor", xdc_waterJumpFactor); - /* xe0_waterBallJumpFactor */ - __dna_docout.writeFloat("xe0_waterBallJumpFactor", xe0_waterBallJumpFactor); - /* xe4_lavaJumpFactor */ - __dna_docout.writeFloat("xe4_lavaJumpFactor", xe4_lavaJumpFactor); - /* xe8_lavaBallJumpFactor */ - __dna_docout.writeFloat("xe8_lavaBallJumpFactor", xe8_lavaBallJumpFactor); - /* xec_phazonJumpFactor */ - __dna_docout.writeFloat("xec_phazonJumpFactor", xec_phazonJumpFactor); - /* xf0_phazonBallJumpFactor */ - __dna_docout.writeFloat("xf0_phazonBallJumpFactor", xf0_phazonBallJumpFactor); - /* xf4_allowedJumpTime */ - __dna_docout.writeFloat("xf4_allowedJumpTime", xf4_allowedJumpTime); - /* xf8_allowedDoubleJumpTime */ - __dna_docout.writeFloat("xf8_allowedDoubleJumpTime", xf8_allowedDoubleJumpTime); - /* xfc_minDoubleJumpWindow */ - __dna_docout.writeFloat("xfc_minDoubleJumpWindow", xfc_minDoubleJumpWindow); - /* x100_maxDoubleJumpWindow */ - __dna_docout.writeFloat("x100_maxDoubleJumpWindow", x100_maxDoubleJumpWindow); - /* x104_ */ - __dna_docout.writeFloat("x104_", x104_); - /* x108_minJumpTime */ - __dna_docout.writeFloat("x108_minJumpTime", x108_minJumpTime); - /* x10c_minDoubleJumpTime */ - __dna_docout.writeFloat("x10c_minDoubleJumpTime", x10c_minDoubleJumpTime); - /* x110_allowedLedgeTime */ - __dna_docout.writeFloat("x110_allowedLedgeTime", x110_allowedLedgeTime); - /* x114_doubleJumpImpulse */ - __dna_docout.writeFloat("x114_doubleJumpImpulse", x114_doubleJumpImpulse); - /* x118_backwardsForceMultiplier */ - __dna_docout.writeFloat("x118_backwardsForceMultiplier", x118_backwardsForceMultiplier); - /* x11c_bombJumpRadius */ - __dna_docout.writeFloat("x11c_bombJumpRadius", x11c_bombJumpRadius); - /* x120_bombJumpHeight */ - __dna_docout.writeFloat("x120_bombJumpHeight", x120_bombJumpHeight); - /* x124_eyeOffset */ - __dna_docout.writeFloat("x124_eyeOffset", x124_eyeOffset); - /* x128_turnSpeedMultiplier */ - __dna_docout.writeFloat("x128_turnSpeedMultiplier", x128_turnSpeedMultiplier); - /* x12c_freeLookTurnSpeedMultiplier */ - __dna_docout.writeFloat("x12c_freeLookTurnSpeedMultiplier", x12c_freeLookTurnSpeedMultiplier); - /* x130_horizontalFreeLookAngleVel */ - __dna_docout.writeFloat("x130_horizontalFreeLookAngleVel", x130_horizontalFreeLookAngleVel); - /* x134_verticalFreeLookAngleVel */ - __dna_docout.writeFloat("x134_verticalFreeLookAngleVel", x134_verticalFreeLookAngleVel); - /* x138_freeLookSpeed */ - __dna_docout.writeFloat("x138_freeLookSpeed", x138_freeLookSpeed); - /* x13c_freeLookSnapSpeed */ - __dna_docout.writeFloat("x13c_freeLookSnapSpeed", x13c_freeLookSnapSpeed); - /* x140_ */ - __dna_docout.writeFloat("x140_", x140_); - /* x144_freeLookCenteredThresholdAngle */ - __dna_docout.writeFloat("x144_freeLookCenteredThresholdAngle", x144_freeLookCenteredThresholdAngle); - /* x148_freeLookCenteredTime */ - __dna_docout.writeFloat("x148_freeLookCenteredTime", x148_freeLookCenteredTime); - /* x14c_freeLookDampenFactor */ - __dna_docout.writeFloat("x14c_freeLookDampenFactor", x14c_freeLookDampenFactor); - /* x150_leftDiv */ - __dna_docout.writeFloat("x150_leftDiv", x150_leftDiv); - /* x154_rightDiv */ - __dna_docout.writeFloat("x154_rightDiv", x154_rightDiv); - /* x228_24_freelookTurnsPlayer */ - __dna_docout.writeBool("x228_24_freelookTurnsPlayer", x228_24_freelookTurnsPlayer); - /* x228_25_ */ - __dna_docout.writeBool("x228_25_", x228_25_); - /* x228_26_ */ - __dna_docout.writeBool("x228_26_", x228_26_); - /* x228_27_moveDuringFreeLook */ - __dna_docout.writeBool("x228_27_moveDuringFreeLook", x228_27_moveDuringFreeLook); - /* x228_28_holdButtonsForFreeLook */ - __dna_docout.writeBool("x228_28_holdButtonsForFreeLook", x228_28_holdButtonsForFreeLook); - /* x228_29_twoButtonsForFreeLook */ - __dna_docout.writeBool("x228_29_twoButtonsForFreeLook", x228_29_twoButtonsForFreeLook); - /* x228_30_ */ - __dna_docout.writeBool("x228_30_", x228_30_); - /* x228_31_ */ - __dna_docout.writeBool("x228_31_", x228_31_); - /* x229_24_ */ - __dna_docout.writeBool("x229_24_", x229_24_); - /* x229_25_aimWhenOrbitingPoint */ - __dna_docout.writeBool("x229_25_aimWhenOrbitingPoint", x229_25_aimWhenOrbitingPoint); - /* x229_26_stayInFreeLookWhileFiring */ - __dna_docout.writeBool("x229_26_stayInFreeLookWhileFiring", x229_26_stayInFreeLookWhileFiring); - /* x229_27_ */ - __dna_docout.writeBool("x229_27_", x229_27_); - /* x229_28_ */ - __dna_docout.writeBool("x229_28_", x229_28_); - /* x229_29_orbitFixedOffset */ - __dna_docout.writeBool("x229_29_orbitFixedOffset", x229_29_orbitFixedOffset); - /* x229_30_gunButtonTogglesHolster */ - __dna_docout.writeBool("x229_30_gunButtonTogglesHolster", x229_30_gunButtonTogglesHolster); - /* x229_31_gunNotFiringHolstersGun */ - __dna_docout.writeBool("x229_31_gunNotFiringHolstersGun", x229_31_gunNotFiringHolstersGun); - /* x22a_24_fallingDoubleJump */ - __dna_docout.writeBool("x22a_24_fallingDoubleJump", x22a_24_fallingDoubleJump); - /* x22a_25_impulseDoubleJump */ - __dna_docout.writeBool("x22a_25_impulseDoubleJump", x22a_25_impulseDoubleJump); - /* x22a_26_firingCancelsCameraPitch */ - __dna_docout.writeBool("x22a_26_firingCancelsCameraPitch", x22a_26_firingCancelsCameraPitch); - /* x22a_27_assistedAimingIgnoreHorizontal */ - __dna_docout.writeBool("x22a_27_assistedAimingIgnoreHorizontal", x22a_27_assistedAimingIgnoreHorizontal); - /* x22a_28_assistedAimingIgnoreVertical */ - __dna_docout.writeBool("x22a_28_assistedAimingIgnoreVertical", x22a_28_assistedAimingIgnoreVertical); - /* x22c_ */ - __dna_docout.writeFloat("x22c_", x22c_); - /* x230_ */ - __dna_docout.writeFloat("x230_", x230_); - /* x234_aimMaxDistance */ - __dna_docout.writeFloat("x234_aimMaxDistance", x234_aimMaxDistance); - /* x238_ */ - __dna_docout.writeFloat("x238_", x238_); - /* x23c_ */ - __dna_docout.writeFloat("x23c_", x23c_); - /* x240_ */ - __dna_docout.writeFloat("x240_", x240_); - /* x244_ */ - __dna_docout.writeFloat("x244_", x244_); - /* x248_ */ - __dna_docout.writeFloat("x248_", x248_); - /* x24c_aimThresholdDistance */ - __dna_docout.writeFloat("x24c_aimThresholdDistance", x24c_aimThresholdDistance); - /* x250_ */ - __dna_docout.writeFloat("x250_", x250_); - /* x254_ */ - __dna_docout.writeFloat("x254_", x254_); - /* x258_aimBoxWidth */ - __dna_docout.writeFloat("x258_aimBoxWidth", x258_aimBoxWidth); - /* x25c_aimBoxHeight */ - __dna_docout.writeFloat("x25c_aimBoxHeight", x25c_aimBoxHeight); - /* x260_aimTargetTimer */ - __dna_docout.writeFloat("x260_aimTargetTimer", x260_aimTargetTimer); - /* x264_aimAssistHorizontalAngle */ - __dna_docout.writeFloat("x264_aimAssistHorizontalAngle", x264_aimAssistHorizontalAngle); - /* x268_aimAssistVerticalAngle */ - __dna_docout.writeFloat("x268_aimAssistVerticalAngle", x268_aimAssistVerticalAngle); - /* x158_orbitMinDistance */ - if (auto v = __dna_docout.enterSubVector("x158_orbitMinDistance")) { - /* x158_orbitMinDistance[0] */ - __dna_docout.writeFloat("x158_orbitMinDistance", x158_orbitMinDistance[0]); - /* x158_orbitMinDistance[1] */ - __dna_docout.writeFloat("x158_orbitMinDistance", x158_orbitMinDistance[1]); - /* x158_orbitMinDistance[2] */ - __dna_docout.writeFloat("x158_orbitMinDistance", x158_orbitMinDistance[2]); - } - /* x164_orbitNormalDistance */ - if (auto v = __dna_docout.enterSubVector("x164_orbitNormalDistance")) { - /* x164_orbitNormalDistance[0] */ - __dna_docout.writeFloat("x164_orbitNormalDistance", x164_orbitNormalDistance[0]); - /* x164_orbitNormalDistance[1] */ - __dna_docout.writeFloat("x164_orbitNormalDistance", x164_orbitNormalDistance[1]); - /* x164_orbitNormalDistance[2] */ - __dna_docout.writeFloat("x164_orbitNormalDistance", x164_orbitNormalDistance[2]); - } - /* x170_orbitMaxDistance */ - if (auto v = __dna_docout.enterSubVector("x170_orbitMaxDistance")) { - /* x170_orbitMaxDistance[0] */ - __dna_docout.writeFloat("x170_orbitMaxDistance", x170_orbitMaxDistance[0]); - /* x170_orbitMaxDistance[1] */ - __dna_docout.writeFloat("x170_orbitMaxDistance", x170_orbitMaxDistance[1]); - /* x170_orbitMaxDistance[2] */ - __dna_docout.writeFloat("x170_orbitMaxDistance", x170_orbitMaxDistance[2]); - } - /* x17c_ */ - __dna_docout.writeFloat("x17c_", x17c_); - /* x180_orbitModeTimer */ - __dna_docout.writeFloat("x180_orbitModeTimer", x180_orbitModeTimer); - /* x184_orbitCameraSpeed */ - __dna_docout.writeFloat("x184_orbitCameraSpeed", x184_orbitCameraSpeed); - /* x188_orbitUpperAngle */ - __dna_docout.writeFloat("x188_orbitUpperAngle", x188_orbitUpperAngle); - /* x18c_orbitLowerAngle */ - __dna_docout.writeFloat("x18c_orbitLowerAngle", x18c_orbitLowerAngle); - /* x190_orbitHorizAngle */ - __dna_docout.writeFloat("x190_orbitHorizAngle", x190_orbitHorizAngle); - /* x194_ */ - __dna_docout.writeFloat("x194_", x194_); - /* x198_ */ - __dna_docout.writeFloat("x198_", x198_); - /* x19c_orbitMaxTargetDistance */ - __dna_docout.writeFloat("x19c_orbitMaxTargetDistance", x19c_orbitMaxTargetDistance); - /* x1a0_orbitMaxLockDistance */ - __dna_docout.writeFloat("x1a0_orbitMaxLockDistance", x1a0_orbitMaxLockDistance); - /* x1a4_orbitDistanceThreshold */ - __dna_docout.writeFloat("x1a4_orbitDistanceThreshold", x1a4_orbitDistanceThreshold); - /* x1a8_orbitScreenBoxHalfExtentX */ - if (auto v = __dna_docout.enterSubVector("x1a8_orbitScreenBoxHalfExtentX")) { - /* x1a8_orbitScreenBoxHalfExtentX[0] */ - __dna_docout.writeUint32("x1a8_orbitScreenBoxHalfExtentX", x1a8_orbitScreenBoxHalfExtentX[0]); - /* x1a8_orbitScreenBoxHalfExtentX[1] */ - __dna_docout.writeUint32("x1a8_orbitScreenBoxHalfExtentX", x1a8_orbitScreenBoxHalfExtentX[1]); - } - /* x1b0_orbitScreenBoxHalfExtentY */ - if (auto v = __dna_docout.enterSubVector("x1b0_orbitScreenBoxHalfExtentY")) { - /* x1b0_orbitScreenBoxHalfExtentY[0] */ - __dna_docout.writeUint32("x1b0_orbitScreenBoxHalfExtentY", x1b0_orbitScreenBoxHalfExtentY[0]); - /* x1b0_orbitScreenBoxHalfExtentY[1] */ - __dna_docout.writeUint32("x1b0_orbitScreenBoxHalfExtentY", x1b0_orbitScreenBoxHalfExtentY[1]); - } - /* x1b8_orbitScreenBoxCenterX */ - if (auto v = __dna_docout.enterSubVector("x1b8_orbitScreenBoxCenterX")) { - /* x1b8_orbitScreenBoxCenterX[0] */ - __dna_docout.writeUint32("x1b8_orbitScreenBoxCenterX", x1b8_orbitScreenBoxCenterX[0]); - /* x1b8_orbitScreenBoxCenterX[1] */ - __dna_docout.writeUint32("x1b8_orbitScreenBoxCenterX", x1b8_orbitScreenBoxCenterX[1]); - } - /* x1c0_orbitScreenBoxCenterY */ - if (auto v = __dna_docout.enterSubVector("x1c0_orbitScreenBoxCenterY")) { - /* x1c0_orbitScreenBoxCenterY[0] */ - __dna_docout.writeUint32("x1c0_orbitScreenBoxCenterY", x1c0_orbitScreenBoxCenterY[0]); - /* x1c0_orbitScreenBoxCenterY[1] */ - __dna_docout.writeUint32("x1c0_orbitScreenBoxCenterY", x1c0_orbitScreenBoxCenterY[1]); - } - /* x1c8_orbitZoneIdealX */ - if (auto v = __dna_docout.enterSubVector("x1c8_orbitZoneIdealX")) { - /* x1c8_orbitZoneIdealX[0] */ - __dna_docout.writeUint32("x1c8_orbitZoneIdealX", x1c8_orbitZoneIdealX[0]); - /* x1c8_orbitZoneIdealX[1] */ - __dna_docout.writeUint32("x1c8_orbitZoneIdealX", x1c8_orbitZoneIdealX[1]); - } - /* x1d0_orbitZoneIdealY */ - if (auto v = __dna_docout.enterSubVector("x1d0_orbitZoneIdealY")) { - /* x1d0_orbitZoneIdealY[0] */ - __dna_docout.writeUint32("x1d0_orbitZoneIdealY", x1d0_orbitZoneIdealY[0]); - /* x1d0_orbitZoneIdealY[1] */ - __dna_docout.writeUint32("x1d0_orbitZoneIdealY", x1d0_orbitZoneIdealY[1]); - } - /* x1d8_orbitNearX */ - __dna_docout.writeFloat("x1d8_orbitNearX", x1d8_orbitNearX); - /* x1dc_orbitNearZ */ - __dna_docout.writeFloat("x1dc_orbitNearZ", x1dc_orbitNearZ); - /* x1e0_ */ - __dna_docout.writeFloat("x1e0_", x1e0_); - /* x1e4_ */ - __dna_docout.writeFloat("x1e4_", x1e4_); - /* x1e8_orbitFixedOffsetZDiff */ - __dna_docout.writeFloat("x1e8_orbitFixedOffsetZDiff", x1e8_orbitFixedOffsetZDiff); - /* x1ec_orbitZRange */ - __dna_docout.writeFloat("x1ec_orbitZRange", x1ec_orbitZRange); - /* x1f0_ */ - __dna_docout.writeFloat("x1f0_", x1f0_); - /* x1f4_ */ - __dna_docout.writeFloat("x1f4_", x1f4_); - /* x1f8_ */ - __dna_docout.writeFloat("x1f8_", x1f8_); - /* x1fc_orbitPreventionTime */ - __dna_docout.writeFloat("x1fc_orbitPreventionTime", x1fc_orbitPreventionTime); - /* x200_24_dashEnabled */ - __dna_docout.writeBool("x200_24_dashEnabled", x200_24_dashEnabled); - /* x200_25_dashOnButtonRelease */ - __dna_docout.writeBool("x200_25_dashOnButtonRelease", x200_25_dashOnButtonRelease); - /* x204_dashButtonHoldCancelTime */ - __dna_docout.writeFloat("x204_dashButtonHoldCancelTime", x204_dashButtonHoldCancelTime); - /* x208_dashStrafeInputThreshold */ - __dna_docout.writeFloat("x208_dashStrafeInputThreshold", x208_dashStrafeInputThreshold); - /* x20c_sidewaysDoubleJumpImpulse */ - __dna_docout.writeFloat("x20c_sidewaysDoubleJumpImpulse", x20c_sidewaysDoubleJumpImpulse); - /* x210_sidewaysVerticalDoubleJumpAccel */ - __dna_docout.writeFloat("x210_sidewaysVerticalDoubleJumpAccel", x210_sidewaysVerticalDoubleJumpAccel); - /* x214_sidewaysHorizontalDoubleJumpAccel */ - __dna_docout.writeFloat("x214_sidewaysHorizontalDoubleJumpAccel", x214_sidewaysHorizontalDoubleJumpAccel); - /* x218_scanningRange */ - __dna_docout.writeFloat("x218_scanningRange", x218_scanningRange); - /* x21c_24_scanRetention */ - __dna_docout.writeBool("x21c_24_scanRetention", x21c_24_scanRetention); - /* x21c_25_scanFreezesGame */ - __dna_docout.writeBool("x21c_25_scanFreezesGame", x21c_25_scanFreezesGame); - /* x21c_26_orbitWhileScanning */ - __dna_docout.writeBool("x21c_26_orbitWhileScanning", x21c_26_orbitWhileScanning); - /* x220_scanMaxTargetDistance */ - __dna_docout.writeFloat("x220_scanMaxTargetDistance", x220_scanMaxTargetDistance); - /* x224_scanMaxLockDistance */ - __dna_docout.writeFloat("x224_scanMaxLockDistance", x224_scanMaxLockDistance); - /* x2a0_orbitDistanceMax */ - __dna_docout.writeFloat("x2a0_orbitDistanceMax", x2a0_orbitDistanceMax); - /* x2a4_grappleSwingLength */ - __dna_docout.writeFloat("x2a4_grappleSwingLength", x2a4_grappleSwingLength); - /* x2a8_grappleSwingPeriod */ - __dna_docout.writeFloat("x2a8_grappleSwingPeriod", x2a8_grappleSwingPeriod); - /* x2ac_grapplePullSpeedMin */ - __dna_docout.writeFloat("x2ac_grapplePullSpeedMin", x2ac_grapplePullSpeedMin); - /* x2b0_grappleCameraSpeed */ - __dna_docout.writeFloat("x2b0_grappleCameraSpeed", x2b0_grappleCameraSpeed); - /* x2b4_maxGrappleLockedTurnAlignDistance */ - __dna_docout.writeFloat("x2b4_maxGrappleLockedTurnAlignDistance", x2b4_maxGrappleLockedTurnAlignDistance); - /* x2b8_grapplePullSpeedProportion */ - __dna_docout.writeFloat("x2b8_grapplePullSpeedProportion", x2b8_grapplePullSpeedProportion); - /* x2bc_grapplePullSpeedMax */ - __dna_docout.writeFloat("x2bc_grapplePullSpeedMax", x2bc_grapplePullSpeedMax); - /* x2c0_grappleLookCenterSpeed */ - __dna_docout.writeFloat("x2c0_grappleLookCenterSpeed", x2c0_grappleLookCenterSpeed); - /* x2c4_maxGrappleTurnSpeed */ - __dna_docout.writeFloat("x2c4_maxGrappleTurnSpeed", x2c4_maxGrappleTurnSpeed); - /* x2c8_grappleJumpForce */ - __dna_docout.writeFloat("x2c8_grappleJumpForce", x2c8_grappleJumpForce); - /* x2cc_grappleReleaseTime */ - __dna_docout.writeFloat("x2cc_grappleReleaseTime", x2cc_grappleReleaseTime); - /* x2d0_grappleJumpMode */ - __dna_docout.writeUint32("x2d0_grappleJumpMode", x2d0_grappleJumpMode); - /* x2d4_orbitReleaseBreaksGrapple */ - __dna_docout.writeBool("x2d4_orbitReleaseBreaksGrapple", x2d4_orbitReleaseBreaksGrapple); - /* x2d5_invertGrappleTurn */ - __dna_docout.writeBool("x2d5_invertGrappleTurn", x2d5_invertGrappleTurn); - /* x2d8_grappleBeamSpeed */ - __dna_docout.writeFloat("x2d8_grappleBeamSpeed", x2d8_grappleBeamSpeed); - /* x2dc_grappleBeamXWaveAmplitude */ - __dna_docout.writeFloat("x2dc_grappleBeamXWaveAmplitude", x2dc_grappleBeamXWaveAmplitude); - /* x2e0_grappleBeamZWaveAmplitude */ - __dna_docout.writeFloat("x2e0_grappleBeamZWaveAmplitude", x2e0_grappleBeamZWaveAmplitude); - /* x2e4_grappleBeamAnglePhaseDelta */ - __dna_docout.writeFloat("x2e4_grappleBeamAnglePhaseDelta", x2e4_grappleBeamAnglePhaseDelta); - /* x26c_playerHeight */ - __dna_docout.writeFloat("x26c_playerHeight", x26c_playerHeight); - /* x270_playerXYHalfExtent */ - __dna_docout.writeFloat("x270_playerXYHalfExtent", x270_playerXYHalfExtent); - /* x274_stepUpHeight */ - __dna_docout.writeFloat("x274_stepUpHeight", x274_stepUpHeight); - /* x278_stepDownHeight */ - __dna_docout.writeFloat("x278_stepDownHeight", x278_stepDownHeight); - /* x27c_playerBallHalfExtent */ - __dna_docout.writeFloat("x27c_playerBallHalfExtent", x27c_playerBallHalfExtent); - /* x280_ */ - __dna_docout.writeFloat("x280_", x280_firstPersonCameraSpeed); - /* x284_ */ - __dna_docout.writeFloat("x284_", x284_); - /* x288_jumpCameraPitchDownStart */ - __dna_docout.writeFloat("x288_jumpCameraPitchDownStart", x288_jumpCameraPitchDownStart); - /* x28c_jumpCameraPitchDownFull */ - __dna_docout.writeFloat("x28c_jumpCameraPitchDownFull", x28c_jumpCameraPitchDownFull); - /* x290_jumpCameraPitchDownAngle */ - __dna_docout.writeFloat("x290_jumpCameraPitchDownAngle", x290_jumpCameraPitchDownAngle); - /* x294_fallCameraPitchDownStart */ - __dna_docout.writeFloat("x294_fallCameraPitchDownStart", x294_fallCameraPitchDownStart); - /* x298_fallCameraPitchDownFull */ - __dna_docout.writeFloat("x298_fallCameraPitchDownFull", x298_fallCameraPitchDownFull); - /* x29c_fallCameraPitchDownAngle */ - __dna_docout.writeFloat("x29c_fallCameraPitchDownAngle", x29c_fallCameraPitchDownAngle); - /* x2e8_ */ - __dna_docout.writeFloat("x2e8_", x2e8_); - /* x2ec_ */ - __dna_docout.writeFloat("x2ec_", x2ec_); - /* x2f0_ */ - __dna_docout.writeFloat("x2f0_", x2f0_); - /* x2f4_ */ - __dna_docout.writeBool("x2f4_", x2f4_); - /* x2f8_frozenTimeout */ - __dna_docout.writeFloat("x2f8_frozenTimeout", x2f8_frozenTimeout); - /* x2fc_iceBreakJumpCount */ - __dna_docout.writeUint32("x2fc_iceBreakJumpCount", x2fc_iceBreakJumpCount); - /* x300_variaDamageReduction */ - __dna_docout.writeFloat("x300_variaDamageReduction", x300_variaDamageReduction); - /* x304_gravityDamageReduction */ - __dna_docout.writeFloat("x304_gravityDamageReduction", x304_gravityDamageReduction); - /* x308_phazonDamageReduction */ - __dna_docout.writeFloat("x308_phazonDamageReduction", x308_phazonDamageReduction); -} - -std::string_view CTweakPlayer::DNAType() { return "DataSpec::DNAMP1::CTweakPlayer"sv; } -template <> -void CTweakPlayer::Enumerate(size_t& __isz) { - __isz += 785; -} -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakPlayer.hpp b/DataSpec/DNAMP1/Tweaks/CTweakPlayer.hpp deleted file mode 100644 index e5983db64..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakPlayer.hpp +++ /dev/null @@ -1,179 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/Tweaks/ITweakPlayer.hpp" - -namespace hecl { -class CVar; -} - -namespace DataSpec::DNAMP1 { - -struct CTweakPlayer final : ITweakPlayer { - AT_DECL_EXPLICIT_DNA_YAML - Value x4_maxTranslationalAcceleration[8]; - Value x24_maxRotationalAcceleration[8]; - Value x44_translationFriction[8]; - Value x64_rotationFriction[8]; - Value x84_rotationMaxSpeed[8]; - Value xa4_translationMaxSpeed[8]; - Value xc4_normalGravAccel; - Value xc8_fluidGravAccel; - Value xcc_verticalJumpAccel; - Value xd0_horizontalJumpAccel; - Value xd4_verticalDoubleJumpAccel; - Value xd8_horizontalDoubleJumpAccel; - Value xdc_waterJumpFactor; - Value xe0_waterBallJumpFactor; - Value xe4_lavaJumpFactor; - Value xe8_lavaBallJumpFactor; - Value xec_phazonJumpFactor; - Value xf0_phazonBallJumpFactor; - Value xf4_allowedJumpTime; - Value xf8_allowedDoubleJumpTime; - Value xfc_minDoubleJumpWindow; - Value x100_maxDoubleJumpWindow; - Value x104_; - Value x108_minJumpTime; - Value x10c_minDoubleJumpTime; - Value x110_allowedLedgeTime; - Value x114_doubleJumpImpulse; - Value x118_backwardsForceMultiplier; - Value x11c_bombJumpRadius; - Value x120_bombJumpHeight; - Value x124_eyeOffset; - Value x128_turnSpeedMultiplier; - Value x12c_freeLookTurnSpeedMultiplier; - Value x130_horizontalFreeLookAngleVel; - Value x134_verticalFreeLookAngleVel; - Value x138_freeLookSpeed; - Value x13c_freeLookSnapSpeed; - Value x140_; - Value x144_freeLookCenteredThresholdAngle; - Value x148_freeLookCenteredTime; - Value x14c_freeLookDampenFactor; - Value x150_leftDiv; - Value x154_rightDiv; - Value x158_orbitMinDistance[3]; - Value x164_orbitNormalDistance[3]; - Value x170_orbitMaxDistance[3]; - Value x17c_; - Value x180_orbitModeTimer; - Value x184_orbitCameraSpeed; - Value x188_orbitUpperAngle; - Value x18c_orbitLowerAngle; - Value x190_orbitHorizAngle; - Value x194_; - Value x198_; - Value x19c_orbitMaxTargetDistance; - Value x1a0_orbitMaxLockDistance; - Value x1a4_orbitDistanceThreshold; - Value x1a8_orbitScreenBoxHalfExtentX[2]; - Value x1b0_orbitScreenBoxHalfExtentY[2]; - Value x1b8_orbitScreenBoxCenterX[2]; - Value x1c0_orbitScreenBoxCenterY[2]; - Value x1c8_orbitZoneIdealX[2]; - Value x1d0_orbitZoneIdealY[2]; - Value x1d8_orbitNearX; - Value x1dc_orbitNearZ; - Value x1e0_; - Value x1e4_; - Value x1e8_orbitFixedOffsetZDiff; - Value x1ec_orbitZRange; - Value x1f0_; - Value x1f4_; - Value x1f8_; - Value x1fc_orbitPreventionTime; - Value x200_24_dashEnabled : 1; - Value x200_25_dashOnButtonRelease : 1; - Value x204_dashButtonHoldCancelTime; - Value x208_dashStrafeInputThreshold; - Value x20c_sidewaysDoubleJumpImpulse; - Value x210_sidewaysVerticalDoubleJumpAccel; - Value x214_sidewaysHorizontalDoubleJumpAccel; - Value x218_scanningRange; - Value x21c_24_scanRetention : 1; - Value x21c_25_scanFreezesGame : 1; - Value x21c_26_orbitWhileScanning : 1; - Value x220_scanMaxTargetDistance; - Value x224_scanMaxLockDistance; - Value x228_24_freelookTurnsPlayer : 1; - Value x228_25_ : 1; - Value x228_26_ : 1; - Value x228_27_moveDuringFreeLook : 1; - Value x228_28_holdButtonsForFreeLook : 1; - Value x228_29_twoButtonsForFreeLook : 1; - Value x228_30_ : 1; - Value x228_31_ : 1; - Value x229_24_ : 1; - Value x229_25_aimWhenOrbitingPoint : 1; - Value x229_26_stayInFreeLookWhileFiring : 1; - Value x229_27_ : 1; - Value x229_28_ : 1; - Value x229_29_orbitFixedOffset : 1; - Value x229_30_gunButtonTogglesHolster : 1; - Value x229_31_gunNotFiringHolstersGun : 1; - Value x22a_24_fallingDoubleJump : 1; - Value x22a_25_impulseDoubleJump : 1; - Value x22a_26_firingCancelsCameraPitch : 1; - Value x22a_27_assistedAimingIgnoreHorizontal : 1; - Value x22a_28_assistedAimingIgnoreVertical : 1; - Value x22c_; - Value x230_; - Value x234_aimMaxDistance; - Value x238_; - Value x23c_; - Value x240_; - Value x244_; - Value x248_; - Value x24c_aimThresholdDistance; - Value x250_; - Value x254_; - Value x258_aimBoxWidth; - Value x25c_aimBoxHeight; - Value x260_aimTargetTimer; - Value x264_aimAssistHorizontalAngle; - Value x268_aimAssistVerticalAngle; - Value x26c_playerHeight; - Value x270_playerXYHalfExtent; - Value x274_stepUpHeight; - Value x278_stepDownHeight; - Value x27c_playerBallHalfExtent; - Value x280_firstPersonCameraSpeed; - Value x284_; - Value x288_jumpCameraPitchDownStart; - Value x28c_jumpCameraPitchDownFull; - Value x290_jumpCameraPitchDownAngle; - Value x294_fallCameraPitchDownStart; - Value x298_fallCameraPitchDownFull; - Value x29c_fallCameraPitchDownAngle; - Value x2a0_orbitDistanceMax; - Value x2a4_grappleSwingLength; - Value x2a8_grappleSwingPeriod; - Value x2ac_grapplePullSpeedMin; - Value x2b0_grappleCameraSpeed; - Value x2b4_maxGrappleLockedTurnAlignDistance; - Value x2b8_grapplePullSpeedProportion; - Value x2bc_grapplePullSpeedMax; - Value x2c0_grappleLookCenterSpeed; - Value x2c4_maxGrappleTurnSpeed; - Value x2c8_grappleJumpForce; - Value x2cc_grappleReleaseTime; - Value x2d0_grappleJumpMode; - Value x2d4_orbitReleaseBreaksGrapple; - Value x2d5_invertGrappleTurn; - Value x2d8_grappleBeamSpeed; - Value x2dc_grappleBeamXWaveAmplitude; - Value x2e0_grappleBeamZWaveAmplitude; - Value x2e4_grappleBeamAnglePhaseDelta; - Value x2e8_; - Value x2ec_; - Value x2f0_; - Value x2f4_; - Value x2f8_frozenTimeout; - Value x2fc_iceBreakJumpCount; - Value x300_variaDamageReduction; - Value x304_gravityDamageReduction; - Value x308_phazonDamageReduction; -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakPlayerControl.hpp b/DataSpec/DNAMP1/Tweaks/CTweakPlayerControl.hpp deleted file mode 100644 index 44968f908..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakPlayerControl.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "../../DNACommon/Tweaks/ITweakPlayerControl.hpp" - -namespace DataSpec::DNAMP1 { - -struct CTweakPlayerControl final : ITweakPlayerControl { - AT_DECL_DNA_YAML - Vector m_mappings; -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakPlayerGun.hpp b/DataSpec/DNAMP1/Tweaks/CTweakPlayerGun.hpp deleted file mode 100644 index 937fbde1d..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakPlayerGun.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "../../DNACommon/Tweaks/ITweakPlayerGun.hpp" - -namespace DataSpec::DNAMP1 { - -struct CTweakPlayerGun final : ITweakPlayerGun { - AT_DECL_DNA_YAML - Value x4_upLookAngle; - Value x8_downLookAngle; - Value xc_verticalSpread; - Value x10_horizontalSpread; - Value x14_highVerticalSpread; - Value x18_highHorizontalSpread; - Value x1c_lowVerticalSpread; - Value x20_lowHorizontalSpread; - Value x24_aimVerticalSpeed; - Value x28_aimHorizontalSpeed; - Value x2c_bombFuseTime; - Value x30_bombDropDelayTime; - Value x34_holoHoldTime; - Value x38_gunTransformTime; - Value x3c_gunHolsterTime; - Value x40_gunNotFiringTime; - Value x44_fixedVerticalAim; - Value x48_gunExtendDistance; - Value x4c_gunPosition; - Value x58_; - Value x64_grapplingArmPosition; - SShotParam x70_bomb; - SShotParam x8c_powerBomb; - SShotParam x1d4_missile; - SWeaponInfo xa8_beams[5]; - SComboShotParam x1f0_combos[5]; // Originally rstl::prereserved_vector - Value x280_ricochetData[6]; // Originally rstl::prereserved_vector, extended to 6 to capture -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakPlayerRes.hpp b/DataSpec/DNAMP1/Tweaks/CTweakPlayerRes.hpp deleted file mode 100644 index d784efd52..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakPlayerRes.hpp +++ /dev/null @@ -1,105 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/Tweaks/ITweakPlayerRes.hpp" - -namespace DataSpec::DNAMP1 { - -template -struct AT_SPECIALIZE_PARMS(true, false) CTweakPlayerRes final : ITweakPlayerRes { - AT_DECL_DNA_YAML - - String<-1> m_saveStationIcon; - String<-1> m_missileStationIcon; - String<-1> m_elevatorIcon; - - String<-1> m_minesBreakFirstTopIcon; - String<-1> m_minesBreakFirstBottomIcon; - String<-1> m_minesBreakSecondTopIcon; - String<-1> m_minesBreakSecondBottomIcon; - - String m_mapArrowDown; - String m_mapArrowUp; - - String<-1> m_lStickN; - String<-1> m_lStickU; - String<-1> m_lStickUL; - String<-1> m_lStickL; - String<-1> m_lStickDL; - String<-1> m_lStickD; - String<-1> m_lStickDR; - String<-1> m_lStickR; - String<-1> m_lStickUR; - - String<-1> m_cStickN; - String<-1> m_cStickU; - String<-1> m_cStickUL; - String<-1> m_cStickL; - String<-1> m_cStickDL; - String<-1> m_cStickD; - String<-1> m_cStickDR; - String<-1> m_cStickR; - String<-1> m_cStickUR; - - String<-1> m_lTriggerOut; - String<-1> m_lTriggerIn; - String<-1> m_rTriggerOut; - String<-1> m_rTriggerIn; - - String<-1> m_startButtonOut; - String<-1> m_startButtonIn; - String<-1> m_aButtonOut; - String<-1> m_aButtonIn; - String<-1> m_bButtonOut; - String<-1> m_bButtonIn; - String<-1> m_xButtonOut; - String<-1> m_xButtonIn; - String<-1> m_yButtonOut; - String<-1> m_yButtonIn; - - String<-1> m_ballTransitionsANCS; - String<-1> m_ballTransitionsPower; - String<-1> m_ballTransitionsIce; - String<-1> m_ballTransitionsWave; - String<-1> m_ballTransitionsPlasma; - String<-1> m_ballTransitionsPhazon; - - String<-1> m_cinePower; - String<-1> m_cineIce; - String<-1> m_cineWave; - String<-1> m_cinePlasma; - String<-1> m_cinePhazon; - - Value m_cinematicMoveOutofIntoPlayerDistance; - - std::string_view _GetSaveStationIcon() const override { return m_saveStationIcon; } - std::string_view _GetMissileStationIcon() const override { return m_missileStationIcon; } - std::string_view _GetElevatorIcon() const override { return m_elevatorIcon; } - - std::string_view _GetMinesBreakFirstTopIcon() const override { return m_minesBreakFirstTopIcon; } - std::string_view _GetMinesBreakFirstBottomIcon() const override { return m_minesBreakFirstBottomIcon; } - std::string_view _GetMinesBreakSecondTopIcon() const override { return m_minesBreakSecondTopIcon; } - std::string_view _GetMinesBreakSecondBottomIcon() const override { return m_minesBreakSecondBottomIcon; } - - std::string_view _GetLStick(size_t idx) const override { return (&m_lStickN)[idx]; } - std::string_view _GetCStick(size_t idx) const override { return (&m_cStickN)[idx]; } - - std::string_view _GetLTrigger(size_t idx) const override { return (&m_lTriggerOut)[idx]; } - std::string_view _GetRTrigger(size_t idx) const override { return (&m_rTriggerOut)[idx]; } - std::string_view _GetStartButton(size_t idx) const override { return (&m_startButtonOut)[idx]; } - std::string_view _GetAButton(size_t idx) const override { return (&m_aButtonOut)[idx]; } - std::string_view _GetBButton(size_t idx) const override { return (&m_bButtonOut)[idx]; } - std::string_view _GetXButton(size_t idx) const override { return (&m_xButtonOut)[idx]; } - std::string_view _GetYButton(size_t idx) const override { return (&m_yButtonOut)[idx]; } - - std::string_view _GetBallTransitionsANCS() const override { return m_ballTransitionsANCS; } - - std::string_view _GetBallTransitionBeamRes(size_t idx) const override { return (&m_ballTransitionsPower)[idx]; } - std::string_view _GetBeamCineModel(size_t idx) const override { return (&m_cinePower)[idx]; } - - float _GetCinematicMoveOutofIntoPlayerDistance() const override { return m_cinematicMoveOutofIntoPlayerDistance; } - - CTweakPlayerRes() = default; - CTweakPlayerRes(athena::io::IStreamReader& in) { read(in); } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakSlideShow.hpp b/DataSpec/DNAMP1/Tweaks/CTweakSlideShow.hpp deleted file mode 100644 index 40fa76a98..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakSlideShow.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "../../DNACommon/Tweaks/ITweakSlideShow.hpp" -#include "zeus/CColor.hpp" - -namespace DataSpec::DNAMP1 { - -struct CTweakSlideShow final : ITweakSlideShow { - AT_DECL_DNA_YAML - - String<-1> x4_pakName; - String<-1> x14_fontAssetName; - DNAColor x24_fontColor; - DNAColor x28_outlineColor; - Value x2c_scanPercentInterval; - Value x30_; - Value x34_; - Value x38_; - Value x3c_; - DNAColor x40_; - Value x44_; - Value x48_; - Value x4c_; - Value x50_; - Value x54_; - Value x58_; - - CTweakSlideShow() = default; - CTweakSlideShow(athena::io::IStreamReader& in) { read(in); } - - std::string_view GetFont() const override { return x14_fontAssetName; } - const zeus::CColor& GetFontColor() const override { return x24_fontColor; } - const zeus::CColor& GetOutlineColor() const override { return x28_outlineColor; } - float GetScanPercentInterval() const override { return x2c_scanPercentInterval; } - float GetX54() const override { return x54_; } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakTargeting.cpp b/DataSpec/DNAMP1/Tweaks/CTweakTargeting.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakTargeting.hpp b/DataSpec/DNAMP1/Tweaks/CTweakTargeting.hpp deleted file mode 100644 index fd3bafce8..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakTargeting.hpp +++ /dev/null @@ -1,303 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/Tweaks/ITweakTargeting.hpp" - -namespace DataSpec::DNAMP1 { -template -struct AT_SPECIALIZE_PARMS(true, false) CTweakTargeting final : public ITweakTargeting { - AT_DECL_DNA_YAML - Value x4_targetRadiusMode; - Value x8_currLockOnExitDuration; - Value xc_currLockOnEnterDuration; - Value x10_currLockOnSwitchDuration; - Value x14_lockConfirmScale; - Value x18_nextLockOnEnterDuration; - Value x1c_nextLockOnExitDuration; - Value x20_nextLockOnSwitchDuration; - Value x24_seekerScale; - Value x28_seekerAngleSpeed; - Value x2c_xrayRetAngleSpeed; - Value x30_; - Value x3c_; - Value x48_; - Value x4c_; - Value x50_orbitPointZOffset; - Value x54_orbitPointInTime; - Value x58_orbitPointOutTime; - Value x5c_; - Value x60_; - Value x6c_; - Value x78_; - Value x84_; - Value x90_; - Value x94_; - Value x98_; - Value x9c_; - Value xa0_; - Value xa4_; - Value xa8_; - Value xac_; - DNAColor xb0_thermalReticuleColor; - Value xb4_targetFlowerScale; - DNAColor xb8_targetFlowerColor; - Value xbc_missileBracketDuration; - Value xc0_missileBracketScaleStart; - Value xc4_missileBracketScaleEnd; - Value xc8_missileBracketScaleDuration; - DNAColor xcc_missileBracketColor; - Value xd0_LockonDuration; - Value xd4_innerBeamScale; - DNAColor xd8_innerBeamColorPower; - DNAColor xdc_innerBeamColorIce; - DNAColor xe0_innerBeamColorWave; - DNAColor xe4_innerBeamColorPlasma; - Value xe8_chargeGaugeOvershootOffset; - Value xec_chargeGaugeOvershootDuration; - Value xf0_outerBeamSquaresScale; - DNAColor xf4_outerBeamSquareColor; - Value xf8_outerBeamSquareAngleCount; - struct SSquareAngles : BigDNA { - AT_DECL_DNA - Value count; - Vector angles; - }; - Vector xf8_outerBeamSquareAngles; - Value x108_chargeGaugeAngleCount; - Vector x108_chargeGaugeAngles; - Value x118_chargeGaugeScale; - DNAColor x11c_chargeGaugeNonFullColor; - Value x120_chargeTickCount; - Value x124_chargeTickAnglePitch; - Value x128_lockFireScale; - Value x12c_lockFireDuration; - DNAColor x130_lockFireColor; - Value x134_lockDaggerScaleStart; - Value x138_lockDaggerScaleEnd; - DNAColor x13c_lockDaggerColor; - Value x140_lockDaggerAngle0; - Value x144_lockDaggerAngle1; - Value x148_lockDaggerAngle2; - DNAColor x14c_lockConfirmColor; - DNAColor x150_seekerColor; - Value x154_lockConfirmClampMin; - Value x158_lockConfirmClampMax; - Value x15c_targetFlowerClampMin; - Value x160_targetFlowerClampMax; - Value x164_seekerClampMin; - Value x168_seekerClampMax; - Value x16c_missileBracketClampMin; - Value x170_missileBracketClampMax; - Value x174_innerBeamClampMin; - Value x178_innerBeamClampMax; - Value x17c_chargeGaugeClampMin; - Value x180_chargeGaugeClampMax; - Value x184_lockFireClampMin; - Value x188_lockFireClampMax; - Value x18c_lockDaggerClampMin; - Value x190_lockDaggerClampMax; - Value x194_grappleSelectScale; - Value x198_grappleScale; - Value x19c_grappleClampMin; - Value x1a0_grappleClampMax; - DNAColor x1a4_grapplePointSelectColor; - DNAColor x1a8_grapplePointColor; - DNAColor x1ac_lockedGrapplePointSelectColor; - Value x1b0_grappleMinClampScale; - DNAColor x1b4_chargeGaugePulseColorHigh; - Value x1b8_fullChargeFadeDuration; - DNAColor x1bc_orbitPointColor; - DNAColor x1c0_crosshairsColor; - Value x1c4_crosshairsScaleDur; - Value x1c8_drawOrbitPoint; - DNAColor x1cc_chargeGaugePulseColorLow; - Value x1d0_chargeGaugePulsePeriod; - DNAColor x1d4_; - DNAColor x1d8_; - DNAColor x1dc_; - Value x1e0_; - Value x1e4_; - Value x1e8_; - Value x1ec_; - Value x1f0_; - Value x1f4_; - Value x1f8_; - Value x1fc_; - Value x200_; - Value x204_; - Value x208_; - Value x20c_reticuleClampMin; - Value x210_reticuleClampMax; - DNAColor x214_xrayRetRingColor; - Value x218_reticuleScale; - Value x21c_scanTargetClampMin; - Value x220_scanTargetClampMax; - Value x224_angularLagSpeed; - - // RS5 - Vector x218_; - Vector x21c_; - bool x224_ = true; - bool x225_ = false; - bool x226_ = true; - bool x227_ = true; - bool x22c_ = true; - bool x22d_ = false; - bool x22e_ = true; - bool x22f_ = true; - bool x234_ = true; - bool x235_ = false; - bool x236_ = true; - bool x237_ = true; - zeus::CVector3f x23c_ = zeus::skZero3f; - - float x2c8_ = 0.25f; - float x2cc_ = 0.35f; - zeus::CColor x2d0_ = (zeus::Comp32)0xb6e6ffff; - float x2d4_ = 0.39215687f; - zeus::CColor x2d8_ = (zeus::Comp32)0xa82a00ff; - float x2dc_ = 0.78431374f; - zeus::CVector3f x2e0_ = zeus::CVector3f(0.f, 0.f, 0.46f); - float x2ec_ = 0.25f; - float x2f0_ = 0.25f; - float x2f4_ = 120.f; - float x2f8_ = 0.25f; - float x2fc_ = 3.5f; - float x300_ = 0.35f; - zeus::CColor x304_ = (zeus::Comp32)0xa82a00ff; - float x308_ = 0.78431374f; - zeus::CColor x30c_ = (zeus::Comp32)0x89d6ffff; - float x310_ = 0.5019608f; - float x314_ = 11.25f; - float x318_ = 0.25f; - float x31c_ = 0.125f; - zeus::CColor x320_ = (zeus::Comp32)0xffca28ff; - float x324_ = 0.78431374f; - zeus::CColor x328_ = (zeus::Comp32)0x89d6ffff; - float x32c_ = 0.19607843f; - float x330_ = 0.f; - float x334_ = 0.25f; - float x338_ = 3.f; - float x33c_ = 0.25f; - float x340_ = 0.25f; - float x344_ = 0.25f; - float x348_ = 0.25f; - float x34c_ = 45.f; - float x350_ = 0.5f; - float x354_ = 0.65f; - float x358_ = 1.5f; - float x35c_ = 0.18f; - float x360_ = 0.15f; - float x364_ = 0.25f; - zeus::CColor x368_ = (zeus::Comp32)0x56c1fb9f; - zeus::CColor x36c_ = (zeus::Comp32)0x49c3f6a0; - zeus::CColor x370_ = (zeus::Comp32)0x49c3f631; - zeus::CColor x374_ = (zeus::Comp32)0xff8930ff; - zeus::CColor x378_ = (zeus::Comp32)0xff2f28ff; - zeus::CColor x37c_ = (zeus::Comp32)0x93e9ffff; - zeus::CColor x380_ = (zeus::Comp32)0xff6b60ff; - - CTweakTargeting() = default; - CTweakTargeting(athena::io::IStreamReader& r) { - this->read(r); - x124_chargeTickAnglePitch = -zeus::degToRad(x124_chargeTickAnglePitch); - x140_lockDaggerAngle0 = zeus::degToRad(x140_lockDaggerAngle0); - x144_lockDaggerAngle1 = zeus::degToRad(x144_lockDaggerAngle1); - x148_lockDaggerAngle2 = zeus::degToRad(x148_lockDaggerAngle2); - x208_ = zeus::degToRad(x208_); - for (int i = 0; i < 4; ++i) - for (float& f : xf8_outerBeamSquareAngles[i].floats) - f = zeus::degToRad(f); - for (int i = 0; i < 4; ++i) - x108_chargeGaugeAngles[i] = zeus::degToRad(x108_chargeGaugeAngles[i]); - } - - atUint32 GetTargetRadiusMode() const override { return x4_targetRadiusMode; } - float GetCurrLockOnExitDuration() const override { return x8_currLockOnExitDuration; } - float GetCurrLockOnEnterDuration() const override { return xc_currLockOnEnterDuration; } - float GetCurrLockOnSwitchDuration() const override { return x10_currLockOnSwitchDuration; } - float GetLockConfirmScale() const override { return x14_lockConfirmScale; } - float GetNextLockOnEnterDuration() const override { return x18_nextLockOnEnterDuration; } - float GetNextLockOnExitDuration() const override { return x1c_nextLockOnExitDuration; } - float GetNextLockOnSwitchDuration() const override { return x20_nextLockOnSwitchDuration; } - float GetSeekerScale() const override { return x24_seekerScale; } - float GetSeekerAngleSpeed() const override { return x28_seekerAngleSpeed; } - float GetXRayRetAngleSpeed() const override { return x2c_xrayRetAngleSpeed; } - float GetOrbitPointZOffset() const override { return x50_orbitPointZOffset; } - float GetOrbitPointInTime() const override { return x54_orbitPointInTime; } - float GetOrbitPointOutTime() const override { return x58_orbitPointOutTime; } - const zeus::CColor& GetThermalReticuleColor() const override { return xb0_thermalReticuleColor; } - float GetTargetFlowerScale() const override { return xb4_targetFlowerScale; } - const zeus::CColor& GetTargetFlowerColor() const override { return xb8_targetFlowerColor; } - float GetMissileBracketDuration() const override { return xbc_missileBracketDuration; } - float GetMissileBracketScaleStart() const override { return xc0_missileBracketScaleStart; } - float GetMissileBracketScaleEnd() const override { return xc4_missileBracketScaleEnd; } - float GetMissileBracketScaleDuration() const override { return xc8_missileBracketScaleDuration; } - const zeus::CColor& GetMissileBracketColor() const override { return xcc_missileBracketColor; } - float GetChargeGaugeOvershootOffset() const override { return xe8_chargeGaugeOvershootOffset; } - float GetChargeGaugeOvershootDuration() const override { return xec_chargeGaugeOvershootDuration; } - float GetOuterBeamSquaresScale() const override { return xf0_outerBeamSquaresScale; } - const zeus::CColor& GetOuterBeamSquareColor() const override { return xf4_outerBeamSquareColor; } - float GetLockonDuration() const override { return xd0_LockonDuration; } - float GetInnerBeamScale() const override { return xd4_innerBeamScale; } - const zeus::CColor& GetInnerBeamColorPower() const override { return xd8_innerBeamColorPower; } - const zeus::CColor& GetInnerBeamColorIce() const override { return xdc_innerBeamColorIce; } - const zeus::CColor& GetInnerBeamColorWave() const override { return xe0_innerBeamColorWave; } - const zeus::CColor& GetInnerBeamColorPlasma() const override { return xe4_innerBeamColorPlasma; } - const float* GetOuterBeamSquareAngles(int i) const override { return xf8_outerBeamSquareAngles[i].angles.data(); } - float GetChargeGaugeAngle(int i) const override { return x108_chargeGaugeAngles[i]; } - float GetChargeGaugeScale() const override { return x118_chargeGaugeScale; } - const zeus::CColor& GetChargeGaugeNonFullColor() const override { return x11c_chargeGaugeNonFullColor; } - atUint32 GetChargeTickCount() const override { return x120_chargeTickCount; } - float GetChargeTickAnglePitch() const override { return x124_chargeTickAnglePitch; } - float GetLockFireScale() const override { return x128_lockFireScale; } - float GetLockFireDuration() const override { return x12c_lockFireDuration; } - const zeus::CColor& GetLockFireColor() const override { return x130_lockFireColor; } - float GetLockDaggerScaleStart() const override { return x134_lockDaggerScaleStart; } - float GetLockDaggerScaleEnd() const override { return x138_lockDaggerScaleEnd; } - const zeus::CColor& GetLockDaggerColor() const override { return x13c_lockDaggerColor; } - float GetLockDaggerAngle0() const override { return x140_lockDaggerAngle0; } - float GetLockDaggerAngle1() const override { return x144_lockDaggerAngle1; } - float GetLockDaggerAngle2() const override { return x148_lockDaggerAngle2; } - const zeus::CColor& GetLockConfirmColor() const override { return x14c_lockConfirmColor; } - const zeus::CColor& GetSeekerColor() const override { return x150_seekerColor; } - float GetLockConfirmClampMin() const override { return x154_lockConfirmClampMin; } - float GetLockConfirmClampMax() const override { return x158_lockConfirmClampMax; } - float GetTargetFlowerClampMin() const override { return x15c_targetFlowerClampMin; } - float GetTargetFlowerClampMax() const override { return x160_targetFlowerClampMax; } - float GetSeekerClampMin() const override { return x164_seekerClampMin; } - float GetSeekerClampMax() const override { return x168_seekerClampMax; } - float GetMissileBracketClampMin() const override { return x16c_missileBracketClampMin; } - float GetMissileBracketClampMax() const override { return x170_missileBracketClampMax; } - float GetInnerBeamClampMin() const override { return x174_innerBeamClampMin; } - float GetInnerBeamClampMax() const override { return x178_innerBeamClampMax; } - float GetChargeGaugeClampMin() const override { return x17c_chargeGaugeClampMin; } - float GetChargeGaugeClampMax() const override { return x180_chargeGaugeClampMax; } - float GetLockFireClampMin() const override { return x184_lockFireClampMin; } - float GetLockFireClampMax() const override { return x188_lockFireClampMax; } - float GetLockDaggerClampMin() const override { return x18c_lockDaggerClampMin; } - float GetLockDaggerClampMax() const override { return x190_lockDaggerClampMax; } - float GetGrappleSelectScale() const override { return x194_grappleSelectScale; } - float GetGrappleScale() const override { return x198_grappleScale; } - float GetGrappleClampMin() const override { return x19c_grappleClampMin; } - float GetGrappleClampMax() const override { return x1a0_grappleClampMax; } - const zeus::CColor& GetGrapplePointSelectColor() const override { return x1a4_grapplePointSelectColor; } - const zeus::CColor& GetGrapplePointColor() const override { return x1a8_grapplePointColor; } - const zeus::CColor& GetLockedGrapplePointSelectColor() const override { return x1ac_lockedGrapplePointSelectColor; } - float GetGrappleMinClampScale() const override { return x1b0_grappleMinClampScale; } - const zeus::CColor& GetChargeGaugePulseColorHigh() const override { return x1b4_chargeGaugePulseColorHigh; } - float GetFullChargeFadeDuration() const override { return x1b8_fullChargeFadeDuration; } - const zeus::CColor& GetOrbitPointColor() const override { return x1bc_orbitPointColor; } - const zeus::CColor& GetCrosshairsColor() const override { return x1c0_crosshairsColor; } - float GetCrosshairsScaleDuration() const override { return x1c4_crosshairsScaleDur; } - bool DrawOrbitPoint() const override { return x1c8_drawOrbitPoint; } - const zeus::CColor& GetChargeGaugePulseColorLow() const override { return x1cc_chargeGaugePulseColorLow; } - float GetChargeGaugePulsePeriod() const override { return x1d0_chargeGaugePulsePeriod; } - float GetReticuleClampMin() const override { return x20c_reticuleClampMin; } - float GetReticuleClampMax() const override { return x210_reticuleClampMax; } - const zeus::CColor& GetXRayRetRingColor() const override { return x214_xrayRetRingColor; } - float GetReticuleScale() const override { return x218_reticuleScale; } - float GetScanTargetClampMin() const override { return x21c_scanTargetClampMin; } - float GetScanTargetClampMax() const override { return x220_scanTargetClampMax; } - float GetAngularLagSpeed() const override { return x224_angularLagSpeed; } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP2/AFSM.hpp b/DataSpec/DNAMP2/AFSM.hpp deleted file mode 100644 index 174b89611..000000000 --- a/DataSpec/DNAMP2/AFSM.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "../DNAMP1/AFSM.hpp" - -namespace DataSpec::DNAMP2 { -using AFSM = DNAMP1::AFSM; -} diff --git a/DataSpec/DNAMP2/AGSC.cpp b/DataSpec/DNAMP2/AGSC.cpp deleted file mode 100644 index a0c6496b6..000000000 --- a/DataSpec/DNAMP2/AGSC.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "AGSC.hpp" -#include "amuse/AudioGroup.hpp" -#include "amuse/AudioGroupData.hpp" - -namespace DataSpec::DNAMP2 { - -bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir) { - dir.makeDirChain(true); - - Header head; - head.read(rs); - - auto pool = rs.readUBytes(head.poolSz); - auto proj = rs.readUBytes(head.projSz); - auto sdir = rs.readUBytes(head.sdirSz); - auto samp = rs.readUBytes(head.sampSz); - - amuse::AudioGroupData data(proj.get(), head.projSz, pool.get(), head.poolSz, sdir.get(), head.sdirSz, samp.get(), - head.sampSz, amuse::GCNDataTag{}); - - /* Load into amuse representation */ - amuse::ProjectDatabase projDb; - projDb.setIdDatabases(); - amuse::AudioGroupDatabase group(data); - group.setGroupPath(dir.getAbsolutePath()); - - /* Extract samples */ - group.getSdir().extractAllCompressed(dir.getAbsolutePath(), data.getSamp()); - - /* Write out project/pool */ - { - auto projd = group.getProj().toYAML(); - athena::io::FileWriter fo(hecl::ProjectPath(dir, "!project.yaml").getAbsolutePath()); - if (fo.hasError()) - return false; - fo.writeUBytes(projd.data(), projd.size()); - } - - { - auto poold = group.getPool().toYAML(); - athena::io::FileWriter fo(hecl::ProjectPath(dir, "!pool.yaml").getAbsolutePath()); - if (fo.hasError()) - return false; - fo.writeUBytes(poold.data(), poold.size()); - } - - return true; -} - -bool AGSC::Cook(const hecl::ProjectPath& dir, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath()); - if (w.hasError()) - return false; - - amuse::ProjectDatabase projDb; - projDb.setIdDatabases(); - amuse::AudioGroupDatabase group(dir.getAbsolutePath()); - - auto proj = group.getProj().toGCNData(group.getPool(), group.getSdir()); - auto pool = group.getPool().toData(); - auto sdirSamp = group.getSdir().toGCNData(group); - - Header head; - head.groupName = dir.getLastComponent(); - for (const auto& p : group.getProj().sfxGroups()) - head.groupId = p.first.id; - head.poolSz = pool.size(); - head.projSz = proj.size(); - head.sdirSz = sdirSamp.first.size(); - head.sampSz = sdirSamp.second.size(); - head.write(w); - - w.writeUBytes(pool.data(), pool.size()); - w.writeUBytes(proj.data(), proj.size()); - w.writeUBytes(sdirSamp.first.data(), sdirSamp.first.size()); - w.writeUBytes(sdirSamp.second.data(), sdirSamp.second.size()); - - return true; -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/AGSC.hpp b/DataSpec/DNAMP2/AGSC.hpp deleted file mode 100644 index 215b44126..000000000 --- a/DataSpec/DNAMP2/AGSC.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { - -class AGSC { -public: - struct Header : BigDNA { - AT_DECL_DNA - Value unk; - String<-1> groupName; - Value groupId = -1; - Value poolSz = 0; - Value projSz = 0; - Value sdirSz = 0; - Value sampSz = 0; - }; - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/ANCS.cpp b/DataSpec/DNAMP2/ANCS.cpp deleted file mode 100644 index b03a7ec70..000000000 --- a/DataSpec/DNAMP2/ANCS.cpp +++ /dev/null @@ -1,545 +0,0 @@ -#include "ANCS.hpp" - -namespace DataSpec::DNAMP2 { - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(typename Read::StreamT& reader) { - idx = reader.readUint32Big(); - atUint16 sectionCount = reader.readUint16Big(); - name = reader.readString(); - cmdl.read(reader); - cskr.read(reader); - cinf.read(reader); - - atUint32 animationCount = reader.readUint32Big(); - reader.enumerate(animations, animationCount); - - pasDatabase.read(reader); - - atUint32 partCount = reader.readUint32Big(); - reader.enumerate(partResData.part, partCount); - - atUint32 swhcCount = reader.readUint32Big(); - reader.enumerate(partResData.swhc, swhcCount); - - atUint32 unkCount = reader.readUint32Big(); - reader.enumerate(partResData.unk, unkCount); - - atUint32 elscCount = reader.readUint32Big(); - reader.enumerate(partResData.elsc, elscCount); - - atUint32 spscCount = reader.readUint32Big(); - reader.enumerate(partResData.spsc, spscCount); - - atUint32 unkCount2 = reader.readUint32Big(); - if (unkCount2) - abort(); - reader.enumerate(partResData.unk2, unkCount2); - - unk1 = reader.readUint32Big(); - - animAABBs.clear(); - if (sectionCount > 1) { - atUint32 aabbCount = reader.readUint32Big(); - reader.enumerate(animAABBs, aabbCount); - } - - effects.clear(); - if (sectionCount > 2) { - atUint32 effectCount = reader.readUint32Big(); - reader.enumerate(effects, effectCount); - } - - if (sectionCount > 3) { - cmdlIce.read(reader); - cskrIce.read(reader); - } - - animIdxs.clear(); - if (sectionCount > 4) { - atUint32 aidxCount = reader.readUint32Big(); - reader.enumerateBig(animIdxs, aidxCount); - } - - extents.clear(); - if (sectionCount > 9) { - unk4 = reader.readUint32Big(); - unk5 = reader.readUByte(); - atUint32 extentsCount = reader.readUint32Big(); - reader.enumerate(extents, extentsCount); - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(idx); - - atUint16 sectionCount; - if (unk4 || unk5 || extents.size()) - sectionCount = 10; - else if (partResData.elsc.size()) - sectionCount = 6; - else if (animIdxs.size()) - sectionCount = 5; - else if (cmdlIce.isValid()) - sectionCount = 4; - else if (effects.size()) - sectionCount = 3; - else if (animAABBs.size()) - sectionCount = 2; - else - sectionCount = 1; - writer.writeUint16Big(sectionCount); - - writer.writeString(name); - cmdl.write(writer); - cskr.write(writer); - cinf.write(writer); - - writer.writeUint32Big(animations.size()); - writer.enumerate(animations); - - pasDatabase.write(writer); - - writer.writeUint32Big(partResData.part.size()); - writer.enumerate(partResData.part); - - writer.writeUint32Big(partResData.swhc.size()); - writer.enumerate(partResData.swhc); - - writer.writeUint32Big(partResData.unk.size()); - writer.enumerate(partResData.unk); - - writer.writeUint32Big(partResData.elsc.size()); - writer.enumerate(partResData.elsc); - - writer.writeUint32Big(partResData.spsc.size()); - writer.enumerate(partResData.spsc); - - writer.writeUint32Big(partResData.unk2.size()); - writer.enumerate(partResData.unk2); - - writer.writeUint32Big(unk1); - - if (sectionCount > 1) { - writer.writeUint32Big(animAABBs.size()); - writer.enumerate(animAABBs); - } - - if (sectionCount > 2) { - writer.writeUint32Big(effects.size()); - writer.enumerate(effects); - } - - if (sectionCount > 3) { - cmdlIce.write(writer); - cskrIce.write(writer); - } - - if (sectionCount > 4) { - writer.writeUint32Big(animIdxs.size()); - for (atUint32 idx : animIdxs) - writer.writeUint32Big(idx); - } - - if (sectionCount > 9) { - writer.writeUint32Big(unk4); - writer.writeUByte(unk5); - writer.writeUint32Big(extents.size()); - writer.enumerate(extents); - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(typename BinarySize::StreamT& s) { - atUint16 sectionCount; - if (unk4 || unk5 || extents.size()) - sectionCount = 10; - else if (partResData.elsc.size()) - sectionCount = 6; - else if (animIdxs.size()) - sectionCount = 5; - else if (cmdlIce.isValid()) - sectionCount = 4; - else if (effects.size()) - sectionCount = 3; - else if (animAABBs.size()) - sectionCount = 2; - else - sectionCount = 1; - - s += 6; - - s += name.size() + 1; - s += 12; - - s += 4; - for (const Animation& anim : animations) - anim.binarySize(s); - - pasDatabase.binarySize(s); - - s += 4; - for (const UniqueID32& id : partResData.part) - id.binarySize(s); - - s += 4; - for (const UniqueID32& id : partResData.swhc) - id.binarySize(s); - - s += 4; - for (const UniqueID32& id : partResData.unk) - id.binarySize(s); - - s += 4; - for (const UniqueID32& id : partResData.elsc) - id.binarySize(s); - - s += 4; - for (const UniqueID32& id : partResData.spsc) - id.binarySize(s); - - s += 4; - for (const UniqueID32& id : partResData.unk2) - id.binarySize(s); - - s += 4; - - if (sectionCount > 1) { - s += 4; - for (const MP1CharacterInfo::ActionAABB& aabb : animAABBs) - aabb.binarySize(s); - } - - if (sectionCount > 2) { - s += 4; - for (const Effect& e : effects) - e.binarySize(s); - } - - if (sectionCount > 3) - s += 8; - - if (sectionCount > 4) - s += 4 + animIdxs.size() * 4; - - if (sectionCount > 9) { - s += 9; - for (const Extents& e : extents) - e.binarySize(s); - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(typename ReadYaml::StreamT& reader) { - idx = reader.readUint32("idx"); - atUint16 sectionCount = reader.readUint16("sectionCount"); - name = reader.readString("name"); - - reader.enumerate("animations", animations); - - reader.enumerate("pasDatabase", pasDatabase); - - reader.enumerate("part", partResData.part); - - reader.enumerate("swhc", partResData.swhc); - - reader.enumerate("unk", partResData.unk); - - reader.enumerate("elsc", partResData.elsc); - - reader.enumerate("spsc", partResData.spsc); - - reader.enumerate("unk2", partResData.unk2); - - unk1 = reader.readUint32("unk1"); - - animAABBs.clear(); - if (sectionCount > 1) { - reader.enumerate("part", animAABBs); - } - - effects.clear(); - if (sectionCount > 2) { - reader.enumerate("effects", effects); - } - - if (sectionCount > 3) { - reader.enumerate("cmdlIce", cmdlIce); - } - - animIdxs.clear(); - if (sectionCount > 4) { - reader.enumerate("animIdxs", animIdxs); - } - - extents.clear(); - if (sectionCount > 9) { - unk4 = reader.readUint32("unk4"); - unk5 = reader.readUByte("unk5"); - reader.enumerate("extents", extents); - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(typename WriteYaml::StreamT& writer) { - writer.writeUint32("idx", idx); - - atUint16 sectionCount; - if (unk4 || unk5 || extents.size()) - sectionCount = 10; - else if (partResData.elsc.size()) - sectionCount = 6; - else if (animIdxs.size()) - sectionCount = 5; - else if (cmdlIce.isValid()) - sectionCount = 4; - else if (effects.size()) - sectionCount = 3; - else if (animAABBs.size()) - sectionCount = 2; - else - sectionCount = 1; - writer.writeUint16("sectionCount", sectionCount); - - writer.writeString("name", name); - writer.enumerate("cmdl", cmdl); - - writer.enumerate("animations", animations); - - writer.enumerate("pasDatabase", pasDatabase); - - writer.enumerate("part", partResData.part); - - writer.enumerate("swhc", partResData.swhc); - - writer.enumerate("unk", partResData.unk); - - writer.enumerate("elsc", partResData.elsc); - - writer.enumerate("spsc", partResData.spsc); - - writer.enumerate("unk2", partResData.unk2); - - writer.writeUint32("unk1", unk1); - - if (sectionCount > 1) { - writer.enumerate("animAABBs", animAABBs); - } - - if (sectionCount > 2) { - writer.enumerate("effects", effects); - } - - if (sectionCount > 3) { - writer.enumerate("cmdlIce", cmdlIce); - } - - if (sectionCount > 4) { - writer.enumerate("animIdxs", animIdxs); - } - - if (sectionCount > 9) { - writer.writeUint32("unk4", unk4); - writer.writeUByte("unk5", unk5); - writer.enumerate("extents", extents); - } -} - -std::string_view ANCS::CharacterSet::CharacterInfo::DNAType() { return "DNAMP2::ANCS::CharacterSet::CharacterInfo"sv; } - -template <> -void ANCS::AnimationSet::Enumerate(typename Read::StreamT& reader) { - atUint16 sectionCount = reader.readUint16Big(); - - atUint32 animationCount = reader.readUint32Big(); - reader.enumerate(animations, animationCount); - - atUint32 transitionCount = reader.readUint32Big(); - reader.enumerate(transitions, transitionCount); - defaultTransition.read(reader); - - additiveAnims.clear(); - if (sectionCount > 1) { - atUint32 additiveAnimCount = reader.readUint32Big(); - reader.enumerate(additiveAnims, additiveAnimCount); - additiveDefaultFadeInDur = reader.readFloatBig(); - additiveDefaultFadeOutDur = reader.readFloatBig(); - } - - halfTransitions.clear(); - if (sectionCount > 2) { - atUint32 halfTransitionCount = reader.readUint32Big(); - reader.enumerate(halfTransitions, halfTransitionCount); - } - - evnts.clear(); - if (sectionCount > 3) { - atUint32 evntsCount = reader.readUint32Big(); - reader.enumerate(evnts, evntsCount); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(typename Write::StreamT& writer) { - atUint16 sectionCount; - if (evnts.size()) - sectionCount = 4; - else if (halfTransitions.size()) - sectionCount = 3; - else if (additiveAnims.size()) - sectionCount = 2; - else - sectionCount = 1; - - writer.writeUint16Big(sectionCount); - - writer.writeUint32Big(animations.size()); - writer.enumerate(animations); - - writer.writeUint32Big(transitions.size()); - writer.enumerate(transitions); - defaultTransition.write(writer); - - if (sectionCount > 1) { - writer.writeUint32Big(additiveAnims.size()); - writer.enumerate(additiveAnims); - writer.writeFloatBig(additiveDefaultFadeInDur); - writer.writeFloatBig(additiveDefaultFadeOutDur); - } - - if (sectionCount > 2) { - writer.writeUint32Big(halfTransitions.size()); - writer.enumerate(halfTransitions); - } - - if (sectionCount > 3) { - writer.writeUint32Big(evnts.size()); - writer.enumerate(evnts); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(typename BinarySize::StreamT& s) { - atUint16 sectionCount; - if (evnts.size()) - sectionCount = 4; - else if (halfTransitions.size()) - sectionCount = 3; - else if (additiveAnims.size()) - sectionCount = 2; - else - sectionCount = 1; - - s += 6; - for (const MP1AnimationSet::Animation& anim : animations) - anim.binarySize(s); - - s += 4; - for (const MP1AnimationSet::Transition& trans : transitions) - trans.binarySize(s); - defaultTransition.binarySize(s); - - if (sectionCount > 1) { - s += 4; - for (const MP1AnimationSet::AdditiveAnimationInfo& aaInfo : additiveAnims) - aaInfo.binarySize(s); - s += 8; - } - - if (sectionCount > 2) { - s += 4; - for (const MP1AnimationSet::HalfTransition& ht : halfTransitions) - ht.binarySize(s); - } - - if (sectionCount > 3) { - s += 4; - for (const EVNT& evnt : evnts) - evnt.binarySize(s); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(typename ReadYaml::StreamT& reader) { - atUint16 sectionCount = reader.readUint16("sectionCount"); - - reader.enumerate("animations", animations); - - reader.enumerate("transitions", transitions); - reader.enumerate("defaultTransition", defaultTransition); - - additiveAnims.clear(); - if (sectionCount > 1) { - reader.enumerate("additiveAnims", additiveAnims); - additiveDefaultFadeInDur = reader.readFloat("additiveDefaultFadeInDur"); - additiveDefaultFadeOutDur = reader.readFloat("additiveDefaultFadeOutDur"); - } - - halfTransitions.clear(); - if (sectionCount > 2) { - reader.enumerate("halfTransitions", halfTransitions); - } - - evnts.clear(); - if (sectionCount > 3) { - reader.enumerate("evnts", evnts); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(typename WriteYaml::StreamT& writer) { - atUint16 sectionCount; - if (evnts.size()) - sectionCount = 4; - else if (halfTransitions.size()) - sectionCount = 3; - else if (additiveAnims.size()) - sectionCount = 2; - else - sectionCount = 1; - - writer.writeUint16("sectionCount", sectionCount); - - writer.enumerate("animations", animations); - - writer.enumerate("transitions", transitions); - writer.enumerate("defaultTransition", defaultTransition); - - if (sectionCount > 1) { - writer.enumerate("additiveAnims", additiveAnims); - writer.writeFloat("additiveDefaultFadeInDur", additiveDefaultFadeInDur); - writer.writeFloat("additiveDefaultFadeOutDur", additiveDefaultFadeOutDur); - } - - if (sectionCount > 2) { - writer.enumerate("halfTransitions", halfTransitions); - } - - if (sectionCount > 3) { - writer.enumerate("evnts", evnts); - } -} - -std::string_view ANCS::AnimationSet::DNAType() { return "DNAMP2::ANCS::AnimationSet"sv; } - -template -void ANCS::AnimationSet::EVNT::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"version"}, version, s); - DoSize(athena::io::PropId{"loopEventCount"}, loopEventCount, s); - Do(athena::io::PropId{"loopEvents"}, loopEvents, loopEventCount, s); - if (version == 2) { - DoSize(athena::io::PropId{"uevtEventCount"}, uevtEventCount, s); - Do(athena::io::PropId{"uevtEvents"}, uevtEvents, uevtEventCount, s); - } - DoSize(athena::io::PropId{"effectEventCount"}, effectEventCount, s); - Do(athena::io::PropId{"effectEvents"}, effectEvents, effectEventCount, s); - DoSize(athena::io::PropId{"sfxEventCount"}, sfxEventCount, s); - Do(athena::io::PropId{"sfxEvents"}, sfxEvents, sfxEventCount, s); -} - -AT_SPECIALIZE_DNA(ANCS::AnimationSet::EVNT) - -std::string_view ANCS::AnimationSet::EVNT::DNAType() { return "DNAMP2::ANCS::AnimationSet::EVNT"sv; } - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/ANCS.hpp b/DataSpec/DNAMP2/ANCS.hpp deleted file mode 100644 index 35c15309f..000000000 --- a/DataSpec/DNAMP2/ANCS.hpp +++ /dev/null @@ -1,227 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ANCS.hpp" -#include "CMDLMaterials.hpp" -#include "CINF.hpp" -#include "CSKR.hpp" -#include "ANIM.hpp" -#include "../DNAMP1/ANCS.hpp" - -namespace DataSpec::DNAMP2 { - -struct ANCS : BigDNA { - using CINFType = CINF; - using CSKRType = CSKR; - using ANIMType = ANIM; - - AT_DECL_DNA_YAML - Value version; - - struct CharacterSet : BigDNA { - AT_DECL_DNA_YAML - Value version; - Value characterCount; - struct CharacterInfo : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - using MP1CharacterInfo = DNAMP1::ANCS::CharacterSet::CharacterInfo; - - atUint32 idx; - std::string name; - UniqueID32 cmdl; - UniqueID32 cskr; - UniqueID32 cinf; - - struct Animation : BigDNA { - AT_DECL_DNA_YAML - Value animIdx; - String<-1> strA; - }; - std::vector animations; - - MP1CharacterInfo::PASDatabase pasDatabase; - struct ParticleResData { - std::vector part; - std::vector swhc; - std::vector unk; - std::vector elsc; - std::vector spsc; - std::vector unk2; - } partResData; - - atUint32 unk1 = 0; - - std::vector animAABBs; - - struct Effect : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value compCount; - struct EffectComponent : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - DNAFourCC type; - UniqueID32 id; - Value unkMP2; - Value unk1; - Value unk2; - Value unk3; - }; - Vector comps; - }; - std::vector effects; - - UniqueID32 cmdlIce; - UniqueID32 cskrIce; - - std::vector animIdxs; - - atUint32 unk4; - atUint8 unk5; - - struct Extents : BigDNA { - AT_DECL_DNA_YAML - Value animIdx; - Value aabb[2]; - }; - std::vector extents; - }; - Vector characters; - } characterSet; - - struct AnimationSet : BigDNA { - AT_DECL_DNA_YAML - Delete expl; - - using MP1AnimationSet = DNAMP1::ANCS::AnimationSet; - - std::vector animations; - - std::vector transitions; - MP1AnimationSet::MetaTransFactory defaultTransition; - - std::vector additiveAnims; - - float additiveDefaultFadeInDur = 0.0; - float additiveDefaultFadeOutDur = 0.0; - - std::vector halfTransitions; - - struct EVNT : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - atUint32 version; - - struct EventBase : BigDNA { - AT_DECL_DNA_YAML - Value unk0; - String<-1> name; - Value type; - Value startTime; - Value unk1; - Value idx; - Value unk2; - Value unk3; - Value unk4; - Value unk5; - }; - - struct LoopEvent : EventBase { - AT_DECL_DNA_YAML - Value flag; - }; - Value loopEventCount; - Vector loopEvents; - - struct UEVTEvent : EventBase { - AT_DECL_DNA_YAML - Value uevtType; - String<-1> boneName; - }; - Value uevtEventCount; - Vector uevtEvents; - - struct EffectEvent : EventBase { - AT_DECL_DNA_YAML - Value frameCount; - DNAFourCC effectType; - UniqueID32 effectId; - Value boneId; - Value scale; - Value parentMode; - }; - Value effectEventCount; - Vector effectEvents; - - struct SFXEvent : EventBase { - AT_DECL_DNA_YAML - Value soundId; - Value smallNum; - Value bigNum; - Value sfxUnk1; - Value sfxUnk2; - Value sfxUnk3; - Value sfxUnk4; - }; - Value sfxEventCount; - Vector sfxEvents; - }; - std::vector evnts; - } animationSet; - - void getCharacterResInfo(std::vector>& out) const { - out.clear(); - out.reserve(characterSet.characters.size()); - for (const CharacterSet::CharacterInfo& ci : characterSet.characters) { - out.emplace_back(); - DNAANCS::CharacterResInfo& chOut = out.back(); - chOut.name = ci.name; - chOut.cmdl = ci.cmdl; - chOut.cskr = ci.cskr; - chOut.cinf = ci.cinf; - - if (ci.cmdlIce.isValid()) - chOut.overlays.emplace_back("ICE", std::make_pair(ci.cmdlIce, ci.cskrIce)); - } - } - - void getAnimationResInfo(PAKRouter* pakRouter, - std::map>& out) const { - out.clear(); - for (const DNAMP1::ANCS::AnimationSet::Animation& ai : animationSet.animations) - ai.metaAnim.m_anim->gatherPrimitives(nullptr, out); - for (const DNAMP1::ANCS::AnimationSet::Transition& ti : animationSet.transitions) - if (ti.metaTrans.m_trans) - ti.metaTrans.m_trans->gatherPrimitives(nullptr, out); - if (animationSet.defaultTransition.m_trans) - animationSet.defaultTransition.m_trans->gatherPrimitives(nullptr, out); - } - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged) { - hecl::ProjectPath yamlPath = outPath.getWithExtension(".yaml", true); - hecl::ProjectPath::Type yamlType = yamlPath.getPathType(); - hecl::ProjectPath blendPath = outPath.getWithExtension(".blend", true); - hecl::ProjectPath::Type blendType = blendPath.getPathType(); - - if (force || yamlType == hecl::ProjectPath::Type::None || blendType == hecl::ProjectPath::Type::None) { - ANCS ancs; - ancs.read(rs); - - if (force || yamlType == hecl::ProjectPath::Type::None) { - athena::io::FileWriter writer(yamlPath.getAbsolutePath()); - athena::io::ToYAMLStream(ancs, writer); - } - - if (force || blendType == hecl::ProjectPath::Type::None) { - DNAANCS::ReadANCSToBlender, ANCS, MaterialSet, DNACMDL::SurfaceHeader_2, 4>( - btok, ancs, blendPath, pakRouter, entry, dataSpec, fileChanged, force); - } - } - - return true; - } -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/ANIM.cpp b/DataSpec/DNAMP2/ANIM.cpp deleted file mode 100644 index e1aeda1cf..000000000 --- a/DataSpec/DNAMP2/ANIM.cpp +++ /dev/null @@ -1,577 +0,0 @@ -#include "ANIM.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP2 { - -using ANIMOutStream = hecl::blender::ANIMOutStream; - -void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter& rig) const { - os.format(FMT_STRING("act.hecl_fps = round({})\n" - "act.hecl_looping = {}\n"), - (1.0f / mainInterval), looping ? "True" : "False"); - - auto kit = chanKeys.begin(); - - std::vector fixedRotKeys; - std::vector fixedTransKeys; - - for (const std::pair>& bone : bones) { - const std::string* bName = rig.getCINF().getBoneNameFromId(bone.first); - if (!bName) { - if (std::get<0>(bone.second)) - ++kit; - if (std::get<1>(bone.second)) - ++kit; - if (std::get<2>(bone.second)) - ++kit; - continue; - } - - os.format(FMT_STRING("bone_string = '{}'\n"), *bName); - os << "action_group = act.groups.new(bone_string)\n" - "\n"; - - if (std::get<0>(bone.second)) - os << "rotCurves = []\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=0, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=1, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=2, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=3, " - "action_group=bone_string))\n" - "\n"; - - if (std::get<1>(bone.second)) - os << "transCurves = []\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=0, " - "action_group=bone_string))\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=1, " - "action_group=bone_string))\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=2, " - "action_group=bone_string))\n" - "\n"; - - if (std::get<2>(bone.second)) - os << "scaleCurves = []\n" - "scaleCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].scale', index=0, " - "action_group=bone_string))\n" - "scaleCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].scale', index=1, " - "action_group=bone_string))\n" - "scaleCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].scale', index=2, " - "action_group=bone_string))\n" - "\n"; - - ANIMOutStream ao = os.beginANIMCurve(); - if (std::get<0>(bone.second)) { - const std::vector& rotKeys = *kit++; - fixedRotKeys.clear(); - fixedRotKeys.resize(rotKeys.size()); - - for (int c = 0; c < 4; ++c) { - size_t idx = 0; - for (const DNAANIM::Value& val : rotKeys) - fixedRotKeys[idx++][c] = val.simd[c]; - } - - for (zeus::CQuaternion& rot : fixedRotKeys) - rot = rig.invertRotation(bone.first, rot); - - for (int c = 0; c < 4; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Rotate, c, rotKeys.size()); - for (const zeus::CQuaternion& val : fixedRotKeys) - ao.write(*frameit++, val[c]); - } - } - - if (std::get<1>(bone.second)) { - const std::vector& transKeys = *kit++; - fixedTransKeys.clear(); - fixedTransKeys.resize(transKeys.size()); - - for (int c = 0; c < 3; ++c) { - size_t idx = 0; - for (const DNAANIM::Value& val : transKeys) - fixedTransKeys[idx++][c] = val.simd[c]; - } - - for (zeus::CVector3f& t : fixedTransKeys) - t = rig.invertPosition(bone.first, t, true); - - for (int c = 0; c < 3; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Translate, c, fixedTransKeys.size()); - for (const zeus::CVector3f& val : fixedTransKeys) - ao.write(*frameit++, val[c]); - } - } - - if (std::get<2>(bone.second)) { - const std::vector& scaleKeys = *kit++; - for (int c = 0; c < 3; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Scale, c, scaleKeys.size()); - for (const DNAANIM::Value& val : scaleKeys) - ao.write(*frameit++, val.simd[c]); - } - } - } -} - -template <> -void ANIM::Enumerate(typename Read::StreamT& reader) { - atUint32 version = reader.readUint32Big(); - switch (version) { - case 0: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case 2: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - default: - Log.report(logvisor::Fatal, FMT_STRING("unrecognized ANIM version")); - break; - } -} - -template <> -void ANIM::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(m_anim->m_version); - m_anim->write(writer); -} - -template <> -void ANIM::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - m_anim->binarySize(s); -} - -std::string_view ANIM::ANIM0::DNAType() { return "ANIM0"sv; } - -template <> -void ANIM::ANIM0::Enumerate(typename Read::StreamT& reader) { - Header head; - head.read(reader); - mainInterval = head.interval; - - frames.clear(); - frames.reserve(head.keyCount); - for (size_t k = 0; k < head.keyCount; ++k) - frames.push_back(k); - - std::map boneMap; - for (size_t b = 0; b < head.boneSlotCount; ++b) { - atUint8 idx = reader.readUByte(); - if (idx == 0xff) - continue; - boneMap[idx] = b; - } - - atUint32 boneCount = reader.readUint32Big(); - bones.clear(); - bones.reserve(boneCount); - for (size_t b = 0; b < boneCount; ++b) { - bones.emplace_back(boneMap[b], std::make_tuple(false, false, false)); - atUint8 idx = reader.readUByte(); - if (idx != 0xff) - std::get<0>(bones.back().second) = true; - } - - boneCount = reader.readUint32Big(); - for (size_t b = 0; b < boneCount; ++b) { - atUint8 idx = reader.readUByte(); - if (idx != 0xff) - std::get<1>(bones[b].second) = true; - } - - boneCount = reader.readUint32Big(); - for (size_t b = 0; b < boneCount; ++b) { - atUint8 idx = reader.readUByte(); - if (idx != 0xff) - std::get<2>(bones[b].second) = true; - } - - channels.clear(); - chanKeys.clear(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Rotation; - chanKeys.emplace_back(); - } - if (std::get<1>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Translation; - chanKeys.emplace_back(); - } - if (std::get<2>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Scale; - chanKeys.emplace_back(); - } - } - - reader.readUint32Big(); - auto kit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++kit; - if (std::get<1>(bone.second)) - ++kit; - if (std::get<2>(bone.second)) { - std::vector& keys = *kit++; - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec3fBig()); - } - } - - reader.readUint32Big(); - kit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - std::vector& keys = *kit++; - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec4fBig()); - } - if (std::get<1>(bone.second)) - ++kit; - if (std::get<2>(bone.second)) - ++kit; - } - - reader.readUint32Big(); - kit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++kit; - if (std::get<1>(bone.second)) { - std::vector& keys = *kit++; - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec3fBig()); - } - if (std::get<2>(bone.second)) - ++kit; - } -} - -template <> -void ANIM::ANIM0::Enumerate(typename Write::StreamT& writer) { - Header head; - head.unk0 = 0; - head.unk1 = 0; - head.unk2 = 0; - head.keyCount = frames.size(); - head.duration = head.keyCount * mainInterval; - head.interval = mainInterval; - - atUint32 maxId = 0; - for (const std::pair>& bone : bones) - maxId = std::max(maxId, bone.first); - head.boneSlotCount = maxId + 1; - head.write(writer); - - for (size_t s = 0; s < head.boneSlotCount; ++s) { - size_t boneIdx = 0; - bool found = false; - for (const std::pair>& bone : bones) { - if (s == bone.first) { - writer.writeUByte(boneIdx); - found = true; - break; - } - ++boneIdx; - } - if (!found) - writer.writeUByte(0xff); - } - - writer.writeUint32Big(bones.size()); - size_t boneIdx = 0; - size_t rotKeyCount = 0; - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - writer.writeUByte(boneIdx); - ++rotKeyCount; - } else - writer.writeUByte(0xff); - ++boneIdx; - } - - writer.writeUint32Big(bones.size()); - boneIdx = 0; - size_t transKeyCount = 0; - for (const std::pair>& bone : bones) { - if (std::get<1>(bone.second)) { - writer.writeUByte(boneIdx); - ++transKeyCount; - } else - writer.writeUByte(0xff); - ++boneIdx; - } - - writer.writeUint32Big(bones.size()); - boneIdx = 0; - size_t scaleKeyCount = 0; - for (const std::pair>& bone : bones) { - if (std::get<2>(bone.second)) { - writer.writeUByte(boneIdx); - ++scaleKeyCount; - } else - writer.writeUByte(0xff); - ++boneIdx; - } - - writer.writeUint32Big(scaleKeyCount * head.keyCount); - auto cit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++cit; - if (std::get<1>(bone.second)) - ++cit; - if (std::get<2>(bone.second)) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec3fBig(atVec3f{(*kit++).simd}); - } - } - - writer.writeUint32Big(rotKeyCount * head.keyCount); - cit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec4fBig(atVec4f{(*kit++).simd}); - } - if (std::get<1>(bone.second)) - ++cit; - if (std::get<2>(bone.second)) - ++cit; - } - - writer.writeUint32Big(transKeyCount * head.keyCount); - cit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++cit; - if (std::get<1>(bone.second)) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec3fBig(atVec3f{(*kit++).simd}); - } - if (std::get<2>(bone.second)) - ++cit; - } -} - -template <> -void ANIM::ANIM0::Enumerate(typename BinarySize::StreamT& s) { - Header head; - - atUint32 maxId = 0; - for (const std::pair>& bone : bones) - maxId = std::max(maxId, bone.first); - - head.binarySize(s); - s += maxId + 1; - s += bones.size() * 3 + 12; - - s += 12; - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - s += head.keyCount * 16; - if (std::get<1>(bone.second)) - s += head.keyCount * 12; - if (std::get<2>(bone.second)) - s += head.keyCount * 12; - } -} - -std::string_view ANIM::ANIM2::DNAType() { return "ANIM2"sv; } - -template <> -void ANIM::ANIM2::Enumerate(typename Read::StreamT& reader) { - Header head; - head.read(reader); - mainInterval = head.interval; - looping = bool(head.looping); - - WordBitmap keyBmp; - keyBmp.read(reader, head.keyBitmapBitCount); - frames.clear(); - atUint32 frameAccum = 0; - for (bool bit : keyBmp) { - if (bit) - frames.push_back(frameAccum); - ++frameAccum; - } - reader.seek(4); - - bones.clear(); - bones.reserve(head.boneChannelCount); - channels.clear(); - channels.reserve(head.boneChannelCount); - atUint16 keyframeCount = 0; - for (size_t b = 0; b < head.boneChannelCount; ++b) { - ChannelDesc desc; - desc.read(reader); - bones.emplace_back(desc.id, std::make_tuple(desc.keyCount1 != 0, desc.keyCount2 != 0, desc.keyCount3 != 0)); - - if (desc.keyCount1) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Rotation; - chan.i[0] = desc.initRX; - chan.q[0] = desc.qRX; - chan.i[1] = desc.initRY; - chan.q[1] = desc.qRY; - chan.i[2] = desc.initRZ; - chan.q[2] = desc.qRZ; - } - keyframeCount = std::max(keyframeCount, desc.keyCount1); - - if (desc.keyCount2) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Translation; - chan.i[0] = desc.initTX; - chan.q[0] = desc.qTX; - chan.i[1] = desc.initTY; - chan.q[1] = desc.qTY; - chan.i[2] = desc.initTZ; - chan.q[2] = desc.qTZ; - } - keyframeCount = std::max(keyframeCount, desc.keyCount2); - - if (desc.keyCount3) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Scale; - chan.i[0] = desc.initSX; - chan.q[0] = desc.qSX; - chan.i[1] = desc.initSY; - chan.q[1] = desc.qSY; - chan.i[2] = desc.initSZ; - chan.q[2] = desc.qSZ; - } - keyframeCount = std::max(keyframeCount, desc.keyCount3); - } - - size_t bsSize = DNAANIM::ComputeBitstreamSize(keyframeCount, channels); - std::unique_ptr bsData = reader.readUBytes(bsSize); - DNAANIM::BitstreamReader bsReader; - chanKeys = bsReader.read(bsData.get(), keyframeCount, channels, head.rotDiv, head.translationMult, head.scaleMult); -} - -template <> -void ANIM::ANIM2::Enumerate(typename Write::StreamT& writer) { - /* TODO: conform to MP1 ANIM3 */ - Header head; - head.unk1 = 1; - head.looping = looping; - head.interval = mainInterval; - head.rootBoneId = 0; - head.scaleMult = 0.f; - - WordBitmap keyBmp; - size_t frameCount = 0; - for (atUint32 frame : frames) { - while (keyBmp.getBit(frame)) - ++frame; - keyBmp.setBit(frame); - frameCount = frame + 1; - } - head.keyBitmapBitCount = keyBmp.getBitCount(); - head.duration = frameCount * mainInterval; - head.boneChannelCount = bones.size(); - - size_t keyframeCount = frames.size(); - std::vector qChannels = channels; - DNAANIM::BitstreamWriter bsWriter; - size_t bsSize; - std::unique_ptr bsData = - bsWriter.write(chanKeys, keyframeCount, qChannels, m_version == 3 ? 0x7fffff : 0x7fff, head.rotDiv, - head.translationMult, head.scaleMult, bsSize); - - /* TODO: Figure out proper scratch size computation */ - head.scratchSize = keyframeCount * channels.size() * 16; - - head.write(writer); - keyBmp.write(writer); - writer.writeUint32Big(head.boneChannelCount); - auto cit = qChannels.begin(); - for (const std::pair>& bone : bones) { - ChannelDesc desc; - if (std::get<0>(bone.second)) { - DNAANIM::Channel& chan = *cit++; - desc.keyCount1 = keyframeCount; - desc.initRX = chan.i[0]; - desc.qRX = chan.q[0]; - desc.initRY = chan.i[1]; - desc.qRY = chan.q[1]; - desc.initRZ = chan.i[2]; - desc.qRZ = chan.q[2]; - } - if (std::get<1>(bone.second)) { - DNAANIM::Channel& chan = *cit++; - desc.keyCount2 = keyframeCount; - desc.initTX = chan.i[0]; - desc.qTX = chan.q[0]; - desc.initTY = chan.i[1]; - desc.qTY = chan.q[1]; - desc.initTZ = chan.i[2]; - desc.qTZ = chan.q[2]; - } - if (std::get<2>(bone.second)) { - DNAANIM::Channel& chan = *cit++; - desc.keyCount3 = keyframeCount; - desc.initSX = chan.i[0]; - desc.qSX = chan.q[0]; - desc.initSY = chan.i[1]; - desc.qSY = chan.q[1]; - desc.initSZ = chan.i[2]; - desc.qSZ = chan.q[2]; - } - } - - writer.writeUBytes(bsData.get(), bsSize); -} - -template <> -void ANIM::ANIM2::Enumerate(typename BinarySize::StreamT& s) { - Header head; - - WordBitmap keyBmp; - for (atUint32 frame : frames) { - while (keyBmp.getBit(frame)) - ++frame; - keyBmp.setBit(frame); - } - - head.binarySize(s); - keyBmp.binarySize(s); - s += 4; - for (const std::pair>& bone : bones) { - s += 7; - if (std::get<0>(bone.second)) - s += 9; - if (std::get<1>(bone.second)) - s += 9; - if (std::get<2>(bone.second)) - s += 9; - } - - s += DNAANIM::ComputeBitstreamSize(frames.size(), channels); -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/ANIM.hpp b/DataSpec/DNAMP2/ANIM.hpp deleted file mode 100644 index df52dd46b..000000000 --- a/DataSpec/DNAMP2/ANIM.hpp +++ /dev/null @@ -1,173 +0,0 @@ -#pragma once - -#include "DNAMP2.hpp" -#include "DataSpec/DNACommon/ANIM.hpp" -#include "DataSpec/DNACommon/RigInverter.hpp" -#include "CINF.hpp" -#include "DataSpec/DNACommon/ANCS.hpp" - -namespace DataSpec::DNAMP2 { - -struct ANIM : BigDNA { - AT_DECL_EXPLICIT_DNA - - struct IANIM : BigDNAV { - Delete expl; - atUint32 m_version; - IANIM(atUint32 version) : m_version(version) {} - - std::vector>> bones; - std::vector frames; - std::vector channels; - std::vector> chanKeys; - float mainInterval = 0.0; - bool looping = false; - - void sendANIMToBlender(hecl::blender::PyOutStream&, const DNAANIM::RigInverter& rig) const; - }; - - struct ANIM0 : IANIM { - AT_DECL_EXPLICIT_DNAV - ANIM0() : IANIM(0) {} - - struct Header : BigDNA { - AT_DECL_DNA - Value duration; - Value unk0; - Value interval; - Value unk1; - Value keyCount; - Value unk2; - Value boneSlotCount; - }; - }; - - struct ANIM2 : IANIM { - AT_DECL_EXPLICIT_DNAV - ANIM2() : IANIM(2) {} - - struct Header : BigDNA { - AT_DECL_DNA - Value scratchSize; - Value unk1; - Value duration; - Value interval; - Value rootBoneId = 3; - Value looping = 0; - Value rotDiv; - Value translationMult; - Value scaleMult; - Value boneChannelCount; - Value unk3 = 1; - Value keyBitmapBitCount; - }; - - struct ChannelDesc : BigDNA { - Delete expl; - Value id = 0; - Value keyCount1 = 0; - Value initRX = 0; - Value qRX = 0; - Value initRY = 0; - Value qRY = 0; - Value initRZ = 0; - Value qRZ = 0; - Value keyCount2 = 0; - Value initTX = 0; - Value qTX = 0; - Value initTY = 0; - Value qTY = 0; - Value initTZ = 0; - Value qTZ = 0; - Value keyCount3 = 0; - Value initSX = 0; - Value qSX = 0; - Value initSY = 0; - Value qSY = 0; - Value initSZ = 0; - Value qSZ = 0; - - void read(athena::io::IStreamReader& reader) { - id = reader.readUByte(); - keyCount1 = reader.readUint16Big(); - if (keyCount1) { - initRX = reader.readInt16Big(); - qRX = reader.readUByte(); - initRY = reader.readInt16Big(); - qRY = reader.readUByte(); - initRZ = reader.readInt16Big(); - qRZ = reader.readUByte(); - } - keyCount2 = reader.readUint16Big(); - if (keyCount2) { - initTX = reader.readInt16Big(); - qTX = reader.readUByte(); - initTY = reader.readInt16Big(); - qTY = reader.readUByte(); - initTZ = reader.readInt16Big(); - qTZ = reader.readUByte(); - } - keyCount3 = reader.readUint16Big(); - if (keyCount3) { - initSX = reader.readInt16Big(); - qSX = reader.readUByte(); - initSY = reader.readInt16Big(); - qSY = reader.readUByte(); - initSZ = reader.readInt16Big(); - qSZ = reader.readUByte(); - } - } - void write(athena::io::IStreamWriter& writer) const { - writer.writeUByte(id); - writer.writeUint16Big(keyCount1); - if (keyCount1) { - writer.writeInt16Big(initRX); - writer.writeUByte(qRX); - writer.writeInt16Big(initRY); - writer.writeUByte(qRY); - writer.writeInt16Big(initRZ); - writer.writeUByte(qRZ); - } - writer.writeUint16Big(keyCount2); - if (keyCount2) { - writer.writeInt16Big(initTX); - writer.writeUByte(qTX); - writer.writeInt16Big(initTY); - writer.writeUByte(qTY); - writer.writeInt16Big(initTZ); - writer.writeUByte(qTZ); - } - writer.writeUint16Big(keyCount3); - if (keyCount3) { - writer.writeInt16Big(initSX); - writer.writeUByte(qSX); - writer.writeInt16Big(initSY); - writer.writeUByte(qSY); - writer.writeInt16Big(initSZ); - writer.writeUByte(qSZ); - } - } - size_t binarySize(size_t __isz) const { - __isz += 7; - if (keyCount1) - __isz += 9; - if (keyCount2) - __isz += 9; - if (keyCount3) - __isz += 9; - return __isz; - } - }; - }; - - std::unique_ptr m_anim; - - void sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter& rig, bool) const { - m_anim->sendANIMToBlender(os, rig); - } - - void extractEVNT(const DNAANCS::AnimationResInfo& animInfo, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, bool force) const {} -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/CINF.cpp b/DataSpec/DNAMP2/CINF.cpp deleted file mode 100644 index da6af3935..000000000 --- a/DataSpec/DNAMP2/CINF.cpp +++ /dev/null @@ -1,227 +0,0 @@ -#include "CINF.hpp" -#include "hecl/Blender/Connection.hpp" -#include "DataSpec/DNAMP3/DNAMP3.hpp" - -namespace DataSpec::DNAMP2 { - -atUint32 CINF::getInternalBoneIdxFromId(atUint32 id) const { - atUint32 idx = 0; - for (const Bone& b : bones) { - if (b.id == id) - return idx; - ++idx; - } - return -1; -} - -atUint32 CINF::getBoneIdxFromId(atUint32 id) const { - atUint32 idx = 0; - for (atUint32 bid : boneIds) { - if (bid == id) - return idx; - ++idx; - } - return 0; -} - -const std::string* CINF::getBoneNameFromId(atUint32 id) const { - for (const Name& name : names) - if (id == name.boneId) - return &name.name; - return nullptr; -} - -void CINF::sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const { - for (atUint32 bid : boneIds) { - for (const Name& name : names) { - if (name.boneId == bid) { - os.format(FMT_STRING("obj.vertex_groups.new(name='{}')\n"), name.name); - break; - } - } - } -} - -template -void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const typename PAKBridge::PAKType::IDType& cinfId) const { - DNAANIM::RigInverter inverter(*this); - - os.format(FMT_STRING("arm = bpy.data.armatures.new('CINF_{}')\n" - "arm_obj = bpy.data.objects.new(arm.name, arm)\n" - "bpy.context.scene.collection.objects.link(arm_obj)\n" - "bpy.context.view_layer.objects.active = arm_obj\n" - "bpy.ops.object.mode_set(mode='EDIT')\n" - "arm_bone_table = {{}}\n"), - cinfId); - - for (const DNAANIM::RigInverter::Bone& bone : inverter.getBones()) { - zeus::simd_floats originF(bone.m_origBone.origin.simd); - zeus::simd_floats tailF(bone.m_tail.mSimd); - os.format(FMT_STRING("bone = arm.edit_bones.new('{}')\n" - "bone.head = ({},{},{})\n" - "bone.tail = ({},{},{})\n" - "bone.use_inherit_scale = False\n" - "arm_bone_table[{}] = bone\n"), - *getBoneNameFromId(bone.m_origBone.id), originF[0], originF[1], originF[2], tailF[0], tailF[1], tailF[2], - bone.m_origBone.id); - } - - if constexpr (std::is_same_v) { - if (bones.size()) { - atUint32 nullId = bones[0].parentId; - for (const Bone& bone : bones) - if (bone.parentId != nullId) - os.format(FMT_STRING("arm_bone_table[{}].parent = arm_bone_table[{}]\n"), bone.id, bone.parentId); - } - } else { - for (const Bone& bone : bones) - if (bone.parentId != 97) - os.format(FMT_STRING("arm_bone_table[{}].parent = arm_bone_table[{}]\n"), bone.id, bone.parentId); - } - - os << "bpy.ops.object.mode_set(mode='OBJECT')\n"; - - for (const DNAANIM::RigInverter::Bone& bone : inverter.getBones()) - os.format(FMT_STRING("arm_obj.pose.bones['{}'].rotation_mode = 'QUATERNION'\n"), - *getBoneNameFromId(bone.m_origBone.id)); -} -template void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& cinfId) const; -template void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, - const UniqueID64& cinfId) const; - -template -std::string CINF::GetCINFArmatureName(const UniqueID& cinfId) { - return fmt::format(FMT_STRING("CINF_{}"), cinfId); -} -template std::string CINF::GetCINFArmatureName(const UniqueID32& cinfId); -template std::string CINF::GetCINFArmatureName(const UniqueID64& cinfId); - -int CINF::RecursiveAddArmatureBone(const Armature& armature, const BlenderBone* bone, int parent, int& curId, - std::unordered_map& idMap, - std::map& nameMap) { - int selId; - auto search = idMap.find(bone->name); - if (search == idMap.end()) { - selId = curId++; - idMap.emplace(std::make_pair(bone->name, selId)); - } else - selId = search->second; - - bones.emplace_back(); - Bone& boneOut = bones.back(); - nameMap[bone->name] = selId; - boneOut.id = selId; - boneOut.parentId = parent; - boneOut.origin = bone->origin; - boneOut.linkedCount = bone->children.size() + 1; - boneOut.linked.reserve(boneOut.linkedCount); - - const BlenderBone* child; - boneOut.linked.push_back(parent); - for (size_t i = 0; (child = armature.getChild(bone, i)); ++i) - boneOut.linked.push_back(RecursiveAddArmatureBone(armature, child, boneOut.id, curId, idMap, nameMap)); - - return boneOut.id; -} - -CINF::CINF(const Armature& armature, std::unordered_map& idMap) { - idMap.reserve(armature.bones.size()); - bones.reserve(armature.bones.size()); - - std::map nameMap; - - const BlenderBone* bone = armature.getRoot(); - if (bone) { - if (bone->children.size()) { - int curId = 4; - const BlenderBone* child; - for (size_t i = 0; (child = armature.getChild(bone, i)); ++i) - RecursiveAddArmatureBone(armature, child, 3, curId, idMap, nameMap); - } - - bones.emplace_back(); - Bone& boneOut = bones.back(); - nameMap[bone->name] = 3; - boneOut.id = 3; - boneOut.parentId = 2; - boneOut.origin = bone->origin; - idMap.emplace(std::make_pair(bone->name, 3)); - - if (bone->children.size()) { - boneOut.linkedCount = 2; - boneOut.linked = {2, 4}; - } else { - boneOut.linkedCount = 1; - boneOut.linked = {2}; - } - } - - boneCount = bones.size(); - - names.reserve(nameMap.size()); - nameCount = nameMap.size(); - for (const auto& name : nameMap) { - names.emplace_back(); - Name& nameOut = names.back(); - nameOut.name = name.first; - nameOut.boneId = name.second; - } - - boneIdCount = boneCount; - boneIds.reserve(boneIdCount); - for (auto it = bones.crbegin(); it != bones.crend(); ++it) - boneIds.push_back(it->id); -} - -template -bool CINF::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKBridge::PAKType::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged) { - if (!force && outPath.isFile()) - return true; - - auto& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Armature)) - return false; - auto os = conn.beginPythonOut(true); - - os.format(FMT_STRING("import bpy\n" - "from mathutils import Vector\n" - "bpy.context.scene.name = 'CINF_{}'\n" - "bpy.context.scene.hecl_arm_obj = bpy.context.scene.name\n" - "\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n"), - entry.id); - - CINF cinf; - cinf.read(rs); - cinf.sendCINFToBlender(os, entry.id); - os.centerView(); - os.close(); - return conn.saveBlend(); -} - -template bool CINF::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKBridge::PAKType::Entry& entry, - bool force, hecl::blender::Token& btok, - std::function fileChanged); -template bool CINF::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, - const typename DNAMP3::PAKBridge::PAKType::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged); - -bool CINF::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, - const hecl::blender::Armature& armature) { - std::unordered_map boneIdMap; - CINF cinf(armature, boneIdMap); - - /* Write out CINF resource */ - athena::io::TransactionalFileWriter w(outPath.getAbsolutePath()); - cinf.write(w); - return true; -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/CINF.hpp b/DataSpec/DNAMP2/CINF.hpp deleted file mode 100644 index 6ef77a0f9..000000000 --- a/DataSpec/DNAMP2/CINF.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/RigInverter.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { - -struct CINF : BigDNA { - AT_DECL_DNA - Value boneCount; - struct Bone : BigDNA { - AT_DECL_DNA - Value id; - Value parentId; - Value origin; - Value q1; - Value q2; - Value linkedCount; - Vector linked; - }; - Vector bones; - - Value boneIdCount; - Vector boneIds; - - Value nameCount; - struct Name : BigDNA { - AT_DECL_DNA - String<-1> name; - Value boneId; - }; - Vector names; - - atUint32 getInternalBoneIdxFromId(atUint32 id) const; - atUint32 getBoneIdxFromId(atUint32 id) const; - const std::string* getBoneNameFromId(atUint32 id) const; - void sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const; - template - void sendCINFToBlender(hecl::blender::PyOutStream& os, const typename PAKBridge::PAKType::IDType& cinfId) const; - template - static std::string GetCINFArmatureName(const UniqueID& cinfId); - - CINF() = default; - using Armature = hecl::blender::Armature; - using BlenderBone = hecl::blender::Bone; - - int RecursiveAddArmatureBone(const Armature& armature, const BlenderBone* bone, int parent, int& curId, - std::unordered_map& idMap, std::map& nameMap); - - CINF(const Armature& armature, std::unordered_map& idMap); - - template - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKBridge::PAKType::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged); - - static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, - const hecl::blender::Armature& armature); -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/CMDL.cpp b/DataSpec/DNAMP2/CMDL.cpp deleted file mode 100644 index 4243b67ea..000000000 --- a/DataSpec/DNAMP2/CMDL.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "CMDL.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP2 { - -bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool, hecl::blender::Token& btok, - std::function) { - /* Check for RigPair */ - CINF cinf; - CSKR cskr; - using RigPair = std::pair, std::pair>; - RigPair loadRp = {}; - if (const typename CharacterAssociations::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id)) { - pakRouter.lookupAndReadDNA(rp->cskr, cskr); - pakRouter.lookupAndReadDNA(rp->cinf, cinf); - loadRp.first = {rp->cskr, &cskr}; - loadRp.second = {rp->cinf, &cinf}; - } - - /* Do extract */ - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh)) - return false; - DNACMDL::ReadCMDLToBlender, MaterialSet, RigPair, DNACMDL::SurfaceHeader_2, 4>( - conn, rs, pakRouter, entry, dataSpec, loadRp); - return conn.saveBlend(); -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/CMDL.hpp b/DataSpec/DNAMP2/CMDL.hpp deleted file mode 100644 index a2a0e14fc..000000000 --- a/DataSpec/DNAMP2/CMDL.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/CMDL.hpp" -#include "CMDLMaterials.hpp" -#include "DNAMP2.hpp" -#include "CINF.hpp" -#include "CSKR.hpp" - -namespace DataSpec::DNAMP2 { - -struct CMDL { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool, - hecl::blender::Token& btok, std::function); -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/CMDLMaterials.hpp b/DataSpec/DNAMP2/CMDLMaterials.hpp deleted file mode 100644 index 503d91761..000000000 --- a/DataSpec/DNAMP2/CMDLMaterials.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/GX.hpp" -#include "../DNAMP1/CMDLMaterials.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { - -/* Structurally identical to DNAMP1::MaterialSet except unk0 and unk1 fields */ -struct MaterialSet : BigDNA { - static constexpr bool OneSection() { return false; } - - AT_DECL_DNA - DNAMP1::MaterialSet::MaterialSetHead head; - - struct Material : BigDNA { - AT_DECL_DNA - using Flags = DNAMP1::MaterialSet::Material::Flags; - Flags flags; - const Flags& getFlags() const { return flags; } - - Value textureCount; - Vector textureIdxs; - using VAFlags = DNAMP1::MaterialSet::Material::VAFlags; - DNAMP1::MaterialSet::Material::VAFlags vaFlags; - const VAFlags& getVAFlags() const { return vaFlags; } - Value unk0; /* MP2 only */ - Value unk1; /* MP2 only */ - Value uniqueIdx; - - Vector konstCount; - Vector konstColors; - - using BlendFactor = GX::BlendFactor; - Value blendDstFac; - Value blendSrcFac; - Vector indTexSlot; - - Value colorChannelCount; - Vector colorChannels; - - Value tevStageCount; - Vector tevStages; - Vector tevStageTexInfo; - - Value tcgCount; - Vector tcgs; - - Value uvAnimsSize; - Value uvAnimsCount; - Vector uvAnims; - }; - Vector materials; - - static void RegisterMaterialProps(hecl::blender::PyOutStream& out) { - DNAMP1::MaterialSet::RegisterMaterialProps(out); - } - static void ConstructMaterial(hecl::blender::PyOutStream& out, const MaterialSet::Material& material, - unsigned groupIdx, unsigned matIdx); - - void readToBlender(hecl::blender::PyOutStream& os, const PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, unsigned setIdx) { - DNACMDL::ReadMaterialSetToBlender_1_2(os, *this, pakRouter, entry, setIdx); - } - - void ensureTexturesExtracted(PAKRouter& pakRouter) const { head.ensureTexturesExtracted(pakRouter); } -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/CMakeLists.txt b/DataSpec/DNAMP2/CMakeLists.txt deleted file mode 100644 index aeb467160..000000000 --- a/DataSpec/DNAMP2/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -make_dnalist(MLVL - ANIM - AGSC - ANCS - CMDLMaterials - CINF - CSKR - MREA - PTLA - SAVW - DeafBabe) -set(DNAMP2_SOURCES - DNAMP2.hpp DNAMP2.cpp - DeafBabe.cpp - PAK.cpp - ANIM.cpp - AGSC.cpp - CINF.cpp - CSKR.cpp - CMDL.cpp - ANCS.cpp - CMDL.hpp - MREA.cpp - MAPA.hpp - MAPU.hpp - PATH.hpp - AFSM.hpp - STRG.hpp STRG.cpp) - -dataspec_add_list(DNAMP2 DNAMP2_SOURCES) diff --git a/DataSpec/DNAMP2/CSKR.cpp b/DataSpec/DNAMP2/CSKR.cpp deleted file mode 100644 index 16ab4f450..000000000 --- a/DataSpec/DNAMP2/CSKR.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "CSKR.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP2 { - -void CSKR::weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atUint32 idx) const { - atUint32 accum = 0; - for (const SkinningRule& rule : skinningRules) { - if (idx >= accum && idx < accum + rule.vertCount) - for (const SkinningRule::Weight& weight : rule.weights) - os.format(FMT_STRING("vert[dvert_lay][{}] = {}\n"), cinf.getBoneIdxFromId(weight.boneId), weight.weight); - accum += rule.vertCount; - } -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/CSKR.hpp b/DataSpec/DNAMP2/CSKR.hpp deleted file mode 100644 index a46ccdda7..000000000 --- a/DataSpec/DNAMP2/CSKR.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "CINF.hpp" -#include "../DNAMP1/CSKR.hpp" - -namespace DataSpec::DNAMP2 { - -struct CSKR : DNAMP1::CSKR { - Delete expl; - - const atInt16* getMatrixBank(size_t) const { return nullptr; } - - void weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atUint32 idx) const; -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/DNAMP2.cpp b/DataSpec/DNAMP2/DNAMP2.cpp deleted file mode 100644 index d58c5057b..000000000 --- a/DataSpec/DNAMP2/DNAMP2.cpp +++ /dev/null @@ -1,291 +0,0 @@ -#define NOD_ATHENA 1 -#include "DNAMP2.hpp" -#include "STRG.hpp" -#include "MLVL.hpp" -#include "CMDL.hpp" -#include "ANCS.hpp" -#include "CINF.hpp" -#include "MREA.hpp" -#include "MAPA.hpp" -#include "MAPU.hpp" -#include "PATH.hpp" -#include "AFSM.hpp" -#include "SAVW.hpp" -#include "AGSC.hpp" -#include "../DNAMP1/HINT.hpp" -#include "../DNAMP1/CSNG.hpp" -#include "DataSpec/DNACommon/FSM2.hpp" -#include "DataSpec/DNACommon/TXTR.hpp" -#include "DataSpec/DNACommon/FONT.hpp" -#include "DataSpec/DNACommon/DGRP.hpp" -#include "DataSpec/DNACommon/ATBL.hpp" -#include "Runtime/GCNTypes.hpp" - -namespace DataSpec::DNAMP2 { -logvisor::Module Log("DataSpec::DNAMP2"); - -static bool GetNoShare(std::string_view name) { - std::string lowerName(name); - std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower); - if (lowerName.compare(0, 7, "metroid") == 0) - return false; - if (lowerName.compare(0, 8, "frontend") == 0) - return false; - return true; -} - -PAKBridge::PAKBridge(const nod::Node& node, bool doExtract) -: m_node(node), m_pak(true, GetNoShare(node.getName())), m_doExtract(doExtract) { - nod::AthenaPartReadStream rs(node.beginReadStream()); - m_pak.read(rs); - - /* Append Level String */ - for (const auto& entry : m_pak.m_entries) { - const DNAMP2::PAK::Entry& e = entry.second; - if (e.type == FOURCC('MLVL')) { - PAKEntryReadStream rs = e.beginReadStream(m_node); - MLVL mlvl; - mlvl.read(rs); - const DNAMP2::PAK::Entry* nameEnt = m_pak.lookupEntry(mlvl.worldNameId); - if (nameEnt) { - PAKEntryReadStream rs = nameEnt->beginReadStream(m_node); - STRG mlvlName; - mlvlName.read(rs); - if (m_levelString.size()) - m_levelString += ", "; - m_levelString += mlvlName.getUTF8(FOURCC('ENGL'), 0); - } - } - } -} - -static std::string LayerName(std::string_view name) { - std::string ret(name); - for (auto& ch : ret) - if (ch == '/' || ch == '\\') - ch = '-'; - return ret; -} - -void PAKBridge::build() { - /* First pass: build per-area/per-layer dependency map */ - for (const auto& entry : m_pak.m_entries) { - const DNAMP2::PAK::Entry& e = entry.second; - if (e.type == FOURCC('MLVL')) { - Level& level = m_levelDeps[e.id]; - - MLVL mlvl; - { - PAKEntryReadStream rs = e.beginReadStream(m_node); - mlvl.read(rs); - } - std::string catalogueName; - level.name = m_pak.bestEntryName(m_node, e, catalogueName); - level.areas.reserve(mlvl.areaCount); - unsigned layerIdx = 0; - - /* Make MAPW available to lookup MAPAs */ - const DNAMP2::PAK::Entry* worldMapEnt = m_pak.lookupEntry(mlvl.worldMap); - std::vector mapw; - if (worldMapEnt) { - PAKEntryReadStream rs = worldMapEnt->beginReadStream(m_node); - rs.seek(8, athena::SeekOrigin::Current); - atUint32 areaCount = rs.readUint32Big(); - mapw.reserve(areaCount); - for (atUint32 i = 0; i < areaCount; ++i) - mapw.emplace_back(rs); - } - - /* Index areas */ - unsigned ai = 0; - for (const MLVL::Area& area : mlvl.areas) { - Level::Area& areaDeps = level.areas[area.areaMREAId]; - MLVL::LayerFlags& layerFlags = mlvl.layerFlags[ai]; - const DNAMP2::PAK::Entry* areaNameEnt = m_pak.lookupEntry(area.areaNameId); - if (areaNameEnt) { - STRG areaName; - { - PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node); - areaName.read(rs); - } - areaDeps.name = areaName.getUTF8(FOURCC('ENGL'), 0); - areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name); - } - if (areaDeps.name.empty()) { - areaDeps.name = area.internalAreaName; - if (areaDeps.name.empty()) { - areaDeps.name = "MREA_" + area.areaMREAId.toString(); - } - } - std::string num = fmt::format(FMT_STRING("{:02d} "), ai); - areaDeps.name = num + areaDeps.name; - - areaDeps.layers.reserve(area.depLayerCount - 1); - unsigned r = 0; - for (unsigned l = 1; l < area.depLayerCount; ++l) { - areaDeps.layers.emplace_back(); - Level::Area::Layer& layer = areaDeps.layers.back(); - layer.name = LayerName(mlvl.layerNames[layerIdx++]); - layer.active = layerFlags.flags >> (l - 1) & 0x1; - layer.name = hecl::StringUtils::TrimWhitespace(layer.name); - num = fmt::format(FMT_STRING("{:02d} "), l - 1); - layer.name = num + layer.name; - - layer.resources.reserve(area.depLayers[l] - r); - for (; r < area.depLayers[l]; ++r) - layer.resources.emplace(area.deps[r].id); - } - areaDeps.resources.reserve(area.depCount - r + 2); - for (; r < area.depCount; ++r) - areaDeps.resources.emplace(area.deps[r].id); - areaDeps.resources.emplace(area.areaMREAId); - if (mapw.size() > ai) - areaDeps.resources.emplace(mapw[ai]); - ++ai; - } - } - } - - /* Second pass: cross-compare uniqueness */ - for (auto& entry : m_pak.m_entries) { - entry.second.unique.checkEntry(*this, entry.second); - } -} - -void PAKBridge::addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const { - for (const auto& entry : m_pak.m_entries) { - if (entry.second.type == FOURCC('ANCS')) { - PAKEntryReadStream rs = entry.second.beginReadStream(m_node); - ANCS ancs; - ancs.read(rs); - for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters) { - charAssoc.m_cmdlRigs[ci.cmdl] = {ci.cskr, ci.cinf}; - charAssoc.m_cskrToCharacter[ci.cskr] = - std::make_pair(entry.second.id, fmt::format(FMT_STRING("{}_{}.CSKR"), ci.name, ci.cskr)); - if (ci.cmdlIce.isValid()) { - charAssoc.m_cmdlRigs[ci.cmdlIce] = {ci.cskrIce, ci.cinf}; - charAssoc.m_cskrToCharacter[ci.cskrIce] = - std::make_pair(entry.second.id, fmt::format(FMT_STRING("{}.ICE_{}.CSKR"), ci.name, ci.cskrIce)); - } - } - } - } -} - -void PAKBridge::addPATHToMREA(PAKRouter& pakRouter, - std::unordered_map& pathToMrea) const { - for (const auto& [id, entry] : m_pak.m_entries) { - if (entry.type == FOURCC('MREA')) { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - UniqueID32 pathID = MREA::GetPATHId(rs); - if (pathID.isValid()) - pathToMrea[pathID] = id; - } - } -} - -static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}}; - -void PAKBridge::addMAPATransforms(PAKRouter& pakRouter, - std::unordered_map& addTo, - std::unordered_map& pathOverrides) const { - for (const auto& entry : m_pak.m_entries) { - if (entry.second.type == FOURCC('MLVL')) { - MLVL mlvl; - { - PAKEntryReadStream rs = entry.second.beginReadStream(m_node); - mlvl.read(rs); - } - hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath(); - - if (mlvl.worldNameId.isValid()) - pathOverrides[mlvl.worldNameId] = - hecl::ProjectPath(mlvlDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), mlvl.worldNameId)); - - for (const MLVL::Area& area : mlvl.areas) { - { - /* Get PATH transform */ - const nod::Node* areaNode; - const PAK::Entry* areaEntry = pakRouter.lookupEntry(area.areaMREAId, &areaNode); - PAKEntryReadStream rs = areaEntry->beginReadStream(*areaNode); - UniqueID32 pathId = MREA::GetPATHId(rs); - if (pathId.isValid()) - addTo[pathId] = zeus::CMatrix4f(area.transformMtx[0], area.transformMtx[1], area.transformMtx[2], BottomRow) - .transposed(); - } - hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath(); - if (area.areaNameId.isValid()) - pathOverrides[area.areaNameId] = - hecl::ProjectPath(areaDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), area.areaNameId)); - } - - if (mlvl.worldMap.isValid()) { - const nod::Node* mapNode; - const DNAMP2::PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode); - if (mapEntry) { - PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode); - u32 magic = rs.readUint32Big(); - if (magic == 0xDEADF00D) { - rs.readUint32Big(); - u32 count = rs.readUint32Big(); - for (u32 i = 0; i < count && i < mlvl.areas.size(); ++i) { - MLVL::Area& areaData = mlvl.areas[i]; - UniqueID32 mapaId; - mapaId.read(rs); - addTo[mapaId] = zeus::CMatrix4f(areaData.transformMtx[0], areaData.transformMtx[1], - areaData.transformMtx[2], BottomRow) - .transposed(); - } - } - } - } - } - } -} - -ResExtractor PAKBridge::LookupExtractor(const nod::Node& pakNode, const DNAMP2::PAK& pak, - const DNAMP2::PAK::Entry& entry) { - switch (entry.type.toUint32()) { - case SBIG('HINT'): - return {DNAMP1::HINT::Extract, {".yaml"}}; - case SBIG('STRG'): - return {STRG::Extract, {".yaml"}}; - case SBIG('TXTR'): - return {TXTR::Extract, {".png"}}; - case SBIG('AFSM'): - return {AFSM::Extract, {".yaml"}}; - case SBIG('SAVW'): - return {SAVWCommon::ExtractSAVW, {".yaml"}}; - case SBIG('CMDL'): - return {CMDL::Extract, {".blend"}, 1}; - case SBIG('CINF'): - return {CINF::Extract, {".blend"}, 1}; - case SBIG('ANCS'): - return {ANCS::Extract, {".yaml", ".blend"}, 2}; - case SBIG('MLVL'): - return {MLVL::Extract, {".yaml", ".blend"}, 3}; - case SBIG('MREA'): - return {MREA::Extract, {".blend"}, 4}; - case SBIG('MAPA'): - return {MAPA::Extract, {".blend"}, 4}; - case SBIG('MAPU'): - return {MAPU::Extract, {".blend"}, 5}; - case SBIG('PATH'): - return {PATH::Extract, {".blend"}, 5}; - case SBIG('FSM2'): - return {DNAFSM2::ExtractFSM2, {".yaml"}}; - case SBIG('FONT'): - return {DNAFont::ExtractFONT, {".yaml"}}; - case SBIG('DGRP'): - return {DNADGRP::ExtractDGRP, {".yaml"}}; - case SBIG('AGSC'): - return {AGSC::Extract, {}}; - case SBIG('CSNG'): - return {DNAMP1::CSNG::Extract, {".mid", ".yaml"}}; - case SBIG('ATBL'): - return {DNAAudio::ATBL::Extract, {".yaml"}}; - } - return {}; -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/DNAMP2.hpp b/DataSpec/DNAMP2/DNAMP2.hpp deleted file mode 100644 index 8958ac5c8..000000000 --- a/DataSpec/DNAMP2/DNAMP2.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "PAK.hpp" - -namespace DataSpec::DNAMP2 { - -extern logvisor::Module Log; - -/* MP2-specific, one-shot PAK traversal/extraction class */ -class PAKBridge { - const nod::Node& m_node; - DNAMP2::PAK m_pak; - -public: - bool m_doExtract; - using Level = DataSpec::Level; - std::unordered_map m_levelDeps; - std::string m_levelString; - - PAKBridge(const nod::Node& node, bool doExtract = true); - void build(); - static ResExtractor LookupExtractor(const nod::Node& pakNode, const DNAMP2::PAK& pak, - const DNAMP2::PAK::Entry& entry); - std::string_view getName() const { return m_node.getName(); } - std::string_view getLevelString() const { return m_levelString; } - - using PAKType = DNAMP2::PAK; - const PAKType& getPAK() const { return m_pak; } - const nod::Node& getNode() const { return m_node; } - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const; - - void addPATHToMREA(PAKRouter& pakRouter, std::unordered_map& pathToMrea) const; - - void addMAPATransforms(PAKRouter& pakRouter, std::unordered_map& addTo, - std::unordered_map& pathOverrides) const; -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/DeafBabe.cpp b/DataSpec/DNAMP2/DeafBabe.cpp deleted file mode 100644 index 00d0fd5b1..000000000 --- a/DataSpec/DNAMP2/DeafBabe.cpp +++ /dev/null @@ -1,275 +0,0 @@ -#include "DeafBabe.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP2 { - -void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os) { - os << "TYPE_COLORS = {'NoSFX':(0.0, 0.0, 0.0),\n" - " 'Stone':(1.0, 0.43, 0.15),\n" - " 'Metal':(0.5, 0.5, 0.5),\n" - " 'Grass':(0.0, 0.42, 0.01)," - " 'Ice':(0.0, 0.1, 0.1),\n" - " 'Metal Grating':(0.09, 0.09, 0.09),\n" - " 'Phazon':(0.24, 0.0, 0.21),\n" - " 'Dirt':(0.1, 0.07, 0.05),\n" - " 'Stone':(0.12, 0.12, 0.12),\n" - " 'SP Metal':(0.41, 0.44, 0.5),\n" - " 'Snow':(0.9, 1.0, 1.0),\n" - " 'Fabric':(0.27, 0.34, 0.39),\n" - " 'Moth/Seed Organics':(0.0, 0.02, 0.05),\n" - " 'Glass':(0.27, 0.38, 0.9),\n" - " 'Shield':(1.0, 0.6, 0.0),\n" - " 'Web':(1.0, 1.0, 0.28),\n" - " 'Sand':(0.53, 0.44, 0.21),\n" - " 'Wood':(0.30, 0.15, 0.03),\n" - " 'Organic':(0.19, 0.45, 0.2),\n" - " 'Rubber':(0.09, 0.02, 0.01)}\n" - "\n" - "# Diffuse Color Maker\n" - "from mathutils import Color\n" - "def make_color(index, mat_type, name):\n" - " new_mat = bpy.data.materials.new(name)\n" - " if mat_type in TYPE_COLORS:\n" - " new_mat.diffuse_color = TYPE_COLORS[mat_type] + (1.0,)\n" - " else:\n" - " col = Color()\n" - " col.hsv = ((index / 6.0) % 1.0, 1.0-((index // 6) / 6.0), 1)\n" - " new_mat.diffuse_color = tuple(col) + (1.0,)\n" - " return new_mat\n" - "\n" - "bpy.types.Material.retro_unknown = bpy.props.BoolProperty(description='Retro: Unknown (U)')\n" - "bpy.types.Material.retro_surface_stone = bpy.props.BoolProperty(description='Retro Surface: Stone')\n" - "bpy.types.Material.retro_surface_metal = bpy.props.BoolProperty(description='Retro Surface: Metal')\n" - "bpy.types.Material.retro_surface_grass = bpy.props.BoolProperty(description='Retro Surface: Grass')\n" - "bpy.types.Material.retro_surface_ice = bpy.props.BoolProperty(description='Retro Surface: Ice')\n" - "bpy.types.Material.retro_pillar = bpy.props.BoolProperty(description='Retro Pillar (I)')\n" - "bpy.types.Material.retro_surface_metal_grating = bpy.props.BoolProperty(description='Retro Surface: Metal " - "Grating')\n" - "bpy.types.Material.retro_surface_phazon = bpy.props.BoolProperty(description='Retro Surface: Phazon')\n" - "bpy.types.Material.retro_surface_dirt = bpy.props.BoolProperty(description='Retro Surface: Rock')\n" - "bpy.types.Material.retro_surface_sp_metal = bpy.props.BoolProperty(description='Retro Surface: Lava')\n" - "bpy.types.Material.retro_surface_snow = bpy.props.BoolProperty(description='Retro Surface: Snow')\n" - "bpy.types.Material.retro_surface_fabric = bpy.props.BoolProperty(description='Retro Surface: fabric')\n" - "bpy.types.Material.retro_half_pipe = bpy.props.BoolProperty(description='Retro: Half Pipe (H)')\n" - "bpy.types.Material.retro_unused3 = bpy.props.BoolProperty(description='Retro: Unused 3 (U)')\n" - "bpy.types.Material.retro_unused4 = bpy.props.BoolProperty(description='Retro: Unused 4 (U)')\n" - "bpy.types.Material.retro_surface_mud = bpy.props.BoolProperty(description='Retro Surface: Mud')\n" - "bpy.types.Material.retro_surface_glass = bpy.props.BoolProperty(description='Retro Surface: Glass')\n" - "bpy.types.Material.retro_surface_shield = bpy.props.BoolProperty(description='Retro Surface: Shield')\n" - "bpy.types.Material.retro_surface_sand = bpy.props.BoolProperty(description='Retro Surface: Sand')\n" - "bpy.types.Material.retro_surface_moth_or_seed_organics = bpy.props.BoolProperty(description='Retro Surface: " - "Moth/Seed Organics')\n" - "bpy.types.Material.retro_surface_web = bpy.props.BoolProperty(description='Retro Surface: Web')\n" - "bpy.types.Material.retro_projectile_passthrough = bpy.props.BoolProperty(description='Retro: Projectile " - "Passthrough (P)')\n" - "bpy.types.Material.retro_camera_passthrough = bpy.props.BoolProperty(description='Retro: Camera Passthrough " - "(O)')\n" - "bpy.types.Material.retro_surface_wood = bpy.props.BoolProperty(description='Retro Surface: Wood')\n" - "bpy.types.Material.retro_surface_organic = bpy.props.BoolProperty(description='Retro Surface: Organic')\n" - "bpy.types.Material.retro_surface_rubber = bpy.props.BoolProperty(description='Retro Surface: Rubber')\n" - "bpy.types.Material.retro_see_through = bpy.props.BoolProperty(description='Retro: See Through (T)')\n" - "bpy.types.Material.retro_scan_passthrough = bpy.props.BoolProperty(description='Retro: Scan Passthrough " - "(S)')\n" - "bpy.types.Material.retro_ai_passthrough = bpy.props.BoolProperty(description='Retro: AI Passthrough (A)')\n" - "bpy.types.Material.retro_ceiling = bpy.props.BoolProperty(description='Retro: Ceiling (C)')\n" - "bpy.types.Material.retro_wall = bpy.props.BoolProperty(description='Retro: Wall (W)')\n" - "bpy.types.Material.retro_floor = bpy.props.BoolProperty(description='Retro: Floor (F)')\n" - "bpy.types.Material.retro_ai_block = bpy.props.BoolProperty(description='Retro: AI Block (B)')\n" - "bpy.types.Material.retro_jump_not_allowed = bpy.props.BoolProperty(description='Retro: Jump Not Allowed " - "(J)')\n" - "bpy.types.Material.retro_spider_ball = bpy.props.BoolProperty(description='Retro: Spider Ball (D)')\n" - "bpy.types.Material.retro_screw_attack_wall_jump = bpy.props.BoolProperty(description='Retro: Screw Attack " - "Wall Jump (R)')\n" - "\n" - "material_dict = {}\n" - "material_index = []\n" - "def get_type_id(data):\n" - "\n" - " ret = 0\n" - " for i in range(1, 26):\n" - " if i == 5 or i == 13 or i == 14 or i == 15 or i == 20 or i == 21 or i == 24:\n" - " continue\n" - " if ((data >> i) & 1):\n" - " ret = i\n" - " return ret\n" - "\n" - "def select_material(data):\n" - "\n" - " type_id = get_type_id(data)\n" - " mat_type = str(type_id)\n" - " if type_id == 0:\n" - " mat_type = 'NoSFX'\n" - " if type_id == 1:\n" - " mat_type = 'Stone'\n" - " elif type_id == 2:\n" - " mat_type = 'Metal'\n" - " elif type_id == 3:\n" - " mat_type = 'Grass'\n" - " elif type_id == 4:\n" - " mat_type = 'Ice'\n" - " elif type_id == 6:\n" - " mat_type = 'Metal Grating'\n" - " elif type_id == 7:\n" - " mat_type = 'Phazon'\n" - " elif type_id == 8:\n" - " mat_type = 'Dirt'\n" - " elif type_id == 9:\n" - " mat_type = 'SP Metal'\n" - " elif type_id == 10:\n" - " mat_type = 'Glass'\n" - " elif type_id == 11:\n" - " mat_type = 'Snow'\n" - " elif type_id == 12:\n" - " mat_type = 'Fabric'\n" - " elif type_id == 16:\n" - " mat_type = 'Shield'\n" - " elif type_id == 17:\n" - " mat_type = 'Sand'\n" - " elif type_id == 18:\n" - " mat_type = 'Moth/Seed Organics'\n" - " elif type_id == 19:\n" - " mat_type = 'Web'\n" - " elif type_id == 22:\n" - " mat_type = 'Wood'\n" - " elif type_id == 23:\n" - " mat_type = 'Organic'\n" - " elif type_id == 25:\n" - " mat_type = 'Rubber'\n" - "\n" - " mat_flags = ''\n" - " if ((data >> 0) & 1):\n" - " mat_flags += 'U'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 5) & 1):\n" - " mat_flags += 'I'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 13) & 1):\n" - " mat_flags += 'H'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 14) & 1):\n" - " mat_flags += 'U'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 15) & 1):\n" - " mat_flags += 'U'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 20) & 1):\n" - " mat_flags += 'P'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 21) & 1):\n" - " mat_flags += 'O'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 26) & 1):\n" - " mat_flags += 'T'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 27) & 1):\n" - " mat_flags += 'S'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 28) & 1):\n" - " mat_flags += 'A'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 29) & 1):\n" - " mat_flags += 'C'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 30) & 1):\n" - " mat_flags += 'W'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 31) & 1):\n" - " mat_flags += 'F'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 48) & 1):\n" - " mat_flags += 'B'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 58) & 1):\n" - " mat_flags += 'J'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 61) & 1):\n" - " mat_flags += 'D'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 62) & 1):\n" - " mat_flags += 'R'\n" - " else:\n" - " mat_flags += 'x'\n" - "\n" - " if len(mat_flags) > 0:\n" - " mat_flags = ' ' + mat_flags\n" - "\n" - " mat_name = mat_type + mat_flags\n" - "\n" - " if mat_name in material_index:\n" - " return material_index.index(mat_name)\n" - " elif mat_name in material_dict:\n" - " material_index.append(mat_name)\n" - " return len(material_index)-1\n" - " else:\n" - " mat = make_color(len(material_dict), mat_type, mat_name)\n" - " mat.retro_unknown = ((data >> 0) & 1)\n" - " mat.retro_surface_stone = ((data >> 1) & 1)\n" - " mat.retro_surface_metal = ((data >> 2) & 1)\n" - " mat.retro_surface_grass = ((data >> 3) & 1) \n" - " mat.retro_surface_ice = ((data >> 4) & 1)\n" - " mat.retro_pillar = ((data >> 5) & 1)\n" - " mat.retro_surface_metal_grating = ((data >> 6) & 1)\n" - " mat.retro_surface_phazon = ((data >> 7) & 1)\n" - " mat.retro_surface_dirt = ((data >> 8) & 1)\n" - " mat.retro_surface_sp_metal = ((data >> 9) & 1)\n" - " mat.retro_surface_glass = ((data >> 10) & 1)\n" - " mat.retro_surface_snow = ((data >> 11) & 1)\n" - " mat.retro_surface_fabric = ((data >> 12) & 1)\n" - " mat.retro_half_pipe = ((data >> 13) & 1)\n" - " mat.retro_unused3 = ((data >> 14) & 1)\n" - " mat.retro_unused4 = ((data >> 15) & 1)\n" - " mat.retro_surface_shield = ((data >> 16) & 1)\n" - " mat.retro_surface_sand = ((data >> 17) & 1)\n" - " mat.retro_surface_moth_or_seed_organics = ((data >> 18) & 1)\n" - " mat.retro_surface_web = ((data >> 19) & 1)\n" - " mat.retro_projectile_passthrough = ((data >> 20) & 1)\n" - " mat.retro_camera_passthrough = ((data >> 21) & 1)\n" - " mat.retro_surface_wood = ((data >> 22) & 1)\n" - " mat.retro_surface_organic = ((data >> 23) & 1)\n" - " mat.retro_surface_rubber = ((data >> 25) & 1)\n" - " mat.retro_see_through = ((data >> 26) & 1)\n" - " mat.retro_scan_passthrough = ((data >> 27) & 1)\n" - " mat.retro_ai_passthrough = ((data >> 28) & 1)\n" - " mat.retro_ceiling = ((data >> 29) & 1)\n" - " mat.retro_wall= ((data >> 30) & 1)\n" - " mat.retro_floor = ((data >> 31) & 1)\n" - " mat.retro_ai_block = ((data >> 48) & 1)\n" - " mat.retro_jump_not_allowed = ((data >> 58) & 1)\n" - " mat.retro_spider_ball = ((data >> 61) & 1)\n" - " mat.retro_screw_attack_wall_jump = ((data >> 62) & 1)\n" - " material_dict[mat_name] = mat\n" - " material_index.append(mat_name)\n" - " return len(material_index)-1\n" - "\n" - "\n"; -} - -void DeafBabe::insertNoClimb(hecl::blender::PyOutStream& os) const { - for (atInt16 edgeIdx : noClimbEdges) { - if (edgeIdx == -1) - continue; - const Edge& edge = edgeVertConnections[edgeIdx]; - os.format(FMT_STRING("edge = col_bm.edges.get((col_bm.verts[{}], col_bm.verts[{}]))\n" - "if edge:\n" - " edge.seam = True\n"), - edge.verts[0], edge.verts[1]); - } -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/DeafBabe.hpp b/DataSpec/DNAMP2/DeafBabe.hpp deleted file mode 100644 index 5ebbf267a..000000000 --- a/DataSpec/DNAMP2/DeafBabe.hpp +++ /dev/null @@ -1,245 +0,0 @@ -#pragma once - -#include "../DNAMP1/DeafBabe.hpp" - -namespace DataSpec::DNAMP2 { - -struct DeafBabe : BigDNA { - AT_DECL_DNA - using BspNodeType = DataSpec::BspNodeType; - - struct Material : BigDNA { - AT_DECL_DNA - Value material = 0; - bool unknown() const { return material & 1; } - void setUnknown(bool v) { - material &= ~1; - material |= atUint64(v); - } - bool surfaceStone() const { return (material >> 1ull) & 1; } - void setSurfaceStone(bool v) { - material &= ~(1ull << 1ull); - material |= (atUint64(v) << 1ull); - } - bool surfaceMetal() const { return (material >> 2) & 1; } - void setSurfaceMetal(bool v) { - material &= ~(1ull << 2ull); - material |= (atUint64(v) << 2ull); - } - bool surfaceGrass() const { return (material >> 3) & 1; } - void setSurfaceGrass(bool v) { - material &= ~(1ull << 3ull); - material |= (atUint64(v) << 3ull); - } - bool surfaceIce() const { return (material >> 4ull) & 1; } - void setSurfaceIce(bool v) { - material &= ~(1ull << 4ull); - material |= (atUint64(v) << 4ull); - } - bool pillar() const { return (material >> 5ull) & 1; } - void setPillar(bool v) { - material &= ~(1ull << 5ull); - material |= (atUint64(v) << 5ull); - } - bool surfaceMetalGrating() const { return (material >> 6ull) & 1; } - void setSurfaceMetalGrating(bool v) { - material &= ~(1ull << 6ull); - material |= (atUint64(v) << 6ull); - } - bool surfacePhazon() const { return (material >> 7ull) & 1; } - void setSurfacePhazon(bool v) { - material &= ~(1ull << 7ull); - material |= (atUint64(v) << 7ull); - } - bool surfaceDirt() const { return (material >> 8ull) & 1; } - void setSurfaceDirt(bool v) { - material &= ~(1ull << 8); - material |= (atUint64(v) << 8ull); - } - bool surfaceSPMetal() const { return (material >> 9ull) & 1; } - void setSurfaceSPMetal(bool v) { - material &= ~(1ull << 9ull); - material |= (atUint64(v) << 9ull); - } - bool surfaceGlass() const { return (material >> 10ull) & 1; } - void setSurfaceGlass(bool v) { - material &= ~(1ull << 10ull); - material |= (atUint64(v) << 10ull); - } - bool surfaceSnow() const { return (material >> 11ull) & 1; } - void setSurfaceSnow(bool v) { - material &= ~(1ull << 11ull); - material |= (atUint64(v) << 11ull); - } - bool surfaceFabric() const { return (material >> 12ull) & 1; } - void setSurfaceFabric(bool v) { - material &= ~(1ull << 12ull); - material |= (atUint64(v) << 12ull); - } - bool halfPipe() const { return (material >> 13ull) & 1; } - void setHalfPipe(bool v) { - material &= ~(1ull << 13ull); - material |= (atUint64(v) << 13ull); - } - bool unused3() const { return (material >> 14ull) & 1; } - void setUnused3(bool v) { - material &= ~(1ull << 14ull); - material |= (atUint64(v) << 14ull); - } - bool unused4() const { return (material >> 15ull) & 1; } - void setUnused4(bool v) { - material &= ~(1ull << 15ull); - material |= (atUint64(v) << 15ull); - } - bool surfaceShield() const { return (material >> 16ull) & 1; } - void setSurfaceShield(bool v) { - material &= ~(1ull << 16); - material |= (atUint64(v) << 16ull); - } - bool surfaceSand() const { return (material >> 17ull) & 1; } - void setSurfaceSand(bool v) { - material &= ~(1ull << 17ull); - material |= (atUint64(v) << 17ull); - } - bool surfaceMothOrSeedOrganics() const { return (material >> 18) & 1; } - void setSurfaceMothOrSeedOrganics(bool v) { - material &= ~(1ull << 18); - material |= (atUint64(v) << 18ull); - } - bool surfaceWeb() const { return (material >> 19ull) & 1; } - void setSurfaceWeb(bool v) { - material &= ~(1ull << 19ull); - material |= (atUint64(v) << 19ull); - } - bool projectilePassthrough() const { return (material >> 20ull) & 1; } - void setProjectilePassthrough(bool v) { - material &= ~(1ull << 20ull); - material |= (atUint64(v) << 20ull); - } - bool cameraPassthrough() const { return (material >> 21ull) & 1; } - void setCameraPassthrough(bool v) { - material &= ~(1ull << 21ull); - material |= (atUint64(v) << 21ull); - } - bool surfaceWood() const { return (material >> 22ull) & 1; } - void setSurfaceWood(bool v) { - material &= ~(1ull << 22ull); - material |= (atUint64(v) << 22ull); - } - bool surfaceOrganic() const { return (material >> 23ull) & 1; } - void setSurfaceOrganic(bool v) { - material &= ~(1ull << 23ull); - material |= (atUint64(v) << 23ull); - } - bool flipFace() const { return (material >> 24ull) & 1; } - void setFlipFace(bool v) { - material &= ~(1ull << 24ull); - material |= (atUint64(v) << 24ull); - } - bool surfaceRubber() const { return (material >> 25) & 1; } - void setSurfaceRubber(bool v) { - material &= ~(1ull << 25ull); - material |= (atUint64(v) << 25ull); - } - bool seeThrough() const { return (material >> 26ull) & 1; } - void setSeeThrough(bool v) { - material &= ~(1ull << 26ull); - material |= (atUint64(v) << 26ull); - } - bool scanPassthrough() const { return (material >> 27ull) & 1; } - void setScanPassthrough(bool v) { - material &= ~(1ull << 27ull); - material |= (atUint64(v) << 27ull); - } - bool aiPassthrough() const { return (material >> 28) & 1; } - void setAiPassthrough(bool v) { - material &= ~(1ull << 28ull); - material |= (atUint64(v) << 28ull); - } - bool ceiling() const { return (material >> 29ull) & 1; } - void setCeiling(bool v) { - material &= ~(1ull << 29ull); - material |= (atUint64(v) << 29ull); - } - bool wall() const { return (material >> 30ull) & 1; } - void setWall(bool v) { - material &= ~(1ull << 30ull); - material |= (atUint64(v) << 30ull); - } - bool floor() const { return (material >> 31ull) & 1; } - void setFloor(bool v) { - material &= ~(1ull << 31ull); - material |= (atUint64(v) << 31ull); - } - bool aiBlock() const { return (material >> 48ull) & 1; } - void setAiBlock(bool v) { - material &= ~(1ull << 48ull); - material |= (atUint64(v) << 48ull); - } - bool jumpNotAllowed() const { return (material >> 58ull) & 1; } - void setJumpNotAllowed(bool v) { - material &= ~(1ull << 58ull); - material |= (atUint64(v) << 58ull); - } - bool spiderBall() const { return (material >> 61ull) & 1; } - void setSpiderBall(bool v) { - material &= ~(1ull << 61ull); - material |= (atUint64(v) << 61ull); - } - bool screwAttackWallJump() const { return (material >> 62ull) & 1; } - void setScrewAttackWallJump(bool v) { - material &= ~(1ull << 62ull); - material |= (atUint64(v) << 62ull); - } - - /* Dummies for MP1*/ - bool surfaceLava() const { return false; } - void setSurfaceLava(bool v) {} - bool surfaceMudSlow() const { return false; } - void setSurfaceMudSlow(bool v) {} - bool surfaceMud() const { return false; } - void setSurfaceMud(bool v) {} - bool surfaceStoneRock() const { return false; } - void setSurfaceLavaStone(bool v) {} - bool solid() const { return false; } - void setSolid(bool v) {} - bool noPlatformCollision() const { return false; } - void setNoPlatformCollision(bool v) {} - bool noEdgeCollision() const { return false; } - void setNoEdgeCollision(bool v) {} - }; - - using Edge = DNAMP1::DeafBabe::Edge; - using Triangle = DNAMP1::DeafBabe::Triangle; - - Value unk1; - Value length; - Value magic; - Value version; - Value aabb[2]; - Value rootNodeType; - Value bspSize; - Buffer bspTree; - Value materialCount; - Vector materials; - Value vertMatsCount; - Vector vertMats; - Value edgeMatsCount; - Vector edgeMats; - Value triMatsCount; - Vector triMats; - Value edgeVertsCount; - Vector edgeVertConnections; - Value triangleEdgesCount; - Vector triangleEdgeConnections; - Value noClimbEdgeCount; - Vector noClimbEdges; - Value vertCount; - Vector verts; - - static void BlenderInit(hecl::blender::PyOutStream& os); - void insertNoClimb(hecl::blender::PyOutStream& os) const; - void sendToBlender(hecl::blender::PyOutStream& os) const { DeafBabeSendToBlender(os, *this); } -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/MAPA.hpp b/DataSpec/DNAMP2/MAPA.hpp deleted file mode 100644 index 2805e89b5..000000000 --- a/DataSpec/DNAMP2/MAPA.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MAPA.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { -struct MAPA : DNAMAPA::MAPA { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged) { - MAPA mapa; - mapa.read(rs); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); - } - - static bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out) { - return DNAMAPA::Cook(mapa, out); - } - - static uint32_t Version() { return 3; } - using Header = DNAMAPA::MAPA::HeaderMP2; - using MappableObject = DNAMAPA::MAPA::MappableObjectMP1_2; -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/MAPU.hpp b/DataSpec/DNAMP2/MAPU.hpp deleted file mode 100644 index a68b500ad..000000000 --- a/DataSpec/DNAMP2/MAPU.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MAPU.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { - -struct MAPU : DNAMAPU::MAPU { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged) { - MAPU mapu; - mapu.read(rs); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMAPU::ReadMAPUToBlender(conn, mapu, outPath, pakRouter, entry, force); - } -}; -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/MLVL.hpp b/DataSpec/DNAMP2/MLVL.hpp deleted file mode 100644 index 273a5fc84..000000000 --- a/DataSpec/DNAMP2/MLVL.hpp +++ /dev/null @@ -1,98 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MLVL.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { - -struct MLVL : BigDNA { - AT_DECL_DNA_YAML - Value magic; - Value version; - UniqueID32 worldNameId; - UniqueID32 darkWorldNameId; - Value unk; - UniqueID32 saveWorldId; - UniqueID32 worldSkyboxId; - - Value areaCount; - struct Area : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 areaNameId; - Value transformMtx[3]; - Value aabb[2]; - UniqueID32 areaMREAId; - Value areaId; - - Value attachedAreaCount; - Vector attachedAreas; - Value padding; - - Value depCount; - struct Dependency : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 id; - DNAFourCC type; - }; - Vector deps; - - Value depLayerCount; - Vector depLayers; - - Value dockCount; - struct Dock : BigDNA { - AT_DECL_DNA_YAML - Value endpointCount; - struct Endpoint : BigDNA { - AT_DECL_DNA_YAML - Value areaIdx; - Value dockIdx; - }; - Vector endpoints; - - Value planeVertCount; - Vector planeVerts; - }; - Vector docks; - - Value relCount; - Vector, AT_DNA_COUNT(relCount)> relFilenames; - Value relOffsetCount; - Vector relOffsets; - - String<-1> internalAreaName; - }; - Vector areas; - - UniqueID32 worldMap; - Value unknown2; - Value unknown3; - - Value layerFlagCount; - struct LayerFlags : BigDNA { - AT_DECL_DNA_YAML - Value layerCount; - Value flags; - }; - Vector layerFlags; - - Value layerNameCount; - Vector, AT_DNA_COUNT(layerNameCount)> layerNames; - - Value layerNameOffsetCount; - Vector layerNameOffsets; - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged) { - MLVL mlvl; - mlvl.read(rs); - athena::io::FileWriter writer(outPath.getWithExtension(".yaml", true).getAbsolutePath()); - athena::io::ToYAMLStream(mlvl, writer); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged); - } -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/MREA.cpp b/DataSpec/DNAMP2/MREA.cpp deleted file mode 100644 index 7996f6a4a..000000000 --- a/DataSpec/DNAMP2/MREA.cpp +++ /dev/null @@ -1,347 +0,0 @@ -#include -#include -#include "MREA.hpp" -#include "../DNAMP1/MREA.hpp" -#include "DataSpec/DNACommon/EGMC.hpp" -#include "DeafBabe.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec { -extern hecl::Database::DataSpecEntry SpecEntMP2ORIG; - -namespace DNAMP2 { - -void MREA::StreamReader::nextBlock() { - if (m_nextBlk >= m_blkCount) - Log.report(logvisor::Fatal, FMT_STRING("MREA stream overrun")); - - BlockInfo& info = m_blockInfos[m_nextBlk++]; - - /* Reallocate read buffer if needed */ - if (info.bufSize > m_compBufSz) { - m_compBufSz = info.bufSize; - m_compBuf.reset(new atUint8[m_compBufSz]); - } - - /* Reallocate decompress buffer if needed */ - if (info.decompSize > m_decompBufSz) { - m_decompBufSz = info.decompSize; - m_decompBuf.reset(new atUint8[m_decompBufSz]); - } - - if (info.compSize == 0) { - /* Read uncompressed block */ - m_source.readUBytesToBuf(m_decompBuf.get(), info.decompSize); - } else { - /* Read compressed segments */ - atUint32 blockStart = ROUND_UP_32(info.compSize) - info.compSize; - m_source.seek(blockStart); - atUint32 rem = info.decompSize; - atUint8* bufCur = m_decompBuf.get(); - while (rem) { - atInt16 chunkSz = m_source.readInt16Big(); - if (chunkSz < 0) { - chunkSz = -chunkSz; - m_source.readUBytesToBuf(bufCur, chunkSz); - bufCur += chunkSz; - rem -= chunkSz; - } else { - m_source.readUBytesToBuf(m_compBuf.get(), chunkSz); - size_t dsz; - lzokay::decompress(m_compBuf.get(), chunkSz, bufCur, rem, dsz); - bufCur += dsz; - rem -= dsz; - } - } - } - - m_posInBlk = 0; - m_blkSz = info.decompSize; -} - -MREA::StreamReader::StreamReader(athena::io::IStreamReader& source, atUint32 blkCount) -: m_compBufSz(0x4120) -, m_compBuf(new atUint8[0x4120]) -, m_decompBufSz(0x4120) -, m_decompBuf(new atUint8[0x4120]) -, m_source(source) -, m_blkCount(blkCount) { - m_blockInfos.reserve(blkCount); - for (atUint32 i = 0; i < blkCount; ++i) { - BlockInfo& info = m_blockInfos.emplace_back(); - info.read(source); - m_totalDecompLen += info.decompSize; - } - source.seekAlign32(); - m_blkBase = source.position(); - nextBlock(); -} - -void MREA::StreamReader::seek(atInt64 diff, athena::SeekOrigin whence) { - atUint64 target = diff; - if (whence == athena::SeekOrigin::Current) { - target = m_pos + diff; - } else if (whence == athena::SeekOrigin::End) { - target = m_totalDecompLen - diff; - } - - if (target >= m_totalDecompLen) - Log.report(logvisor::Fatal, FMT_STRING("MREA stream seek overrun")); - - /* Determine which block contains position */ - atUint32 dAccum = 0; - atUint32 cAccum = 0; - atUint32 bIdx = 0; - for (BlockInfo& info : m_blockInfos) { - atUint32 newAccum = dAccum + info.decompSize; - if (newAccum > target) - break; - dAccum = newAccum; - if (info.compSize) - cAccum += ROUND_UP_32(info.compSize); - else - cAccum += info.decompSize; - ++bIdx; - } - - /* Seek source if needed */ - if (bIdx != m_nextBlk - 1) { - m_source.seek(m_blkBase + cAccum, athena::SeekOrigin::Begin); - m_nextBlk = bIdx; - nextBlock(); - } - - m_pos = target; - m_posInBlk = target - dAccum; -} - -void MREA::StreamReader::seekToSection(atUint32 sec, const std::vector& secSizes) { - /* Determine which block contains section */ - atUint32 sAccum = 0; - atUint32 dAccum = 0; - atUint32 cAccum = 0; - atUint32 bIdx = 0; - for (BlockInfo& info : m_blockInfos) { - atUint32 newSAccum = sAccum + info.secCount; - if (newSAccum > sec) - break; - sAccum = newSAccum; - dAccum += info.decompSize; - if (info.compSize) - cAccum += ROUND_UP_32(info.compSize); - else - cAccum += info.decompSize; - ++bIdx; - } - - /* Seek source if needed */ - if (bIdx != m_nextBlk - 1) { - m_source.seek(m_blkBase + cAccum, athena::SeekOrigin::Begin); - m_nextBlk = bIdx; - nextBlock(); - } - - /* Seek within block */ - atUint32 target = dAccum; - while (sAccum != sec) - target += secSizes[sAccum++]; - - m_pos = target; - m_posInBlk = target - dAccum; -} - -atUint64 MREA::StreamReader::readUBytesToBuf(void* buf, atUint64 len) { - atUint8* bufCur = reinterpret_cast(buf); - atUint64 rem = len; - while (rem) { - atUint64 lRem = rem; - atUint64 blkRem = m_blkSz - m_posInBlk; - if (lRem > blkRem) - lRem = blkRem; - memcpy(bufCur, &m_decompBuf[m_posInBlk], lRem); - bufCur += lRem; - rem -= lRem; - m_posInBlk += lRem; - m_pos += lRem; - if (rem) - nextBlock(); - } - return len; -} - -void MREA::StreamReader::writeDecompInfos(athena::io::IStreamWriter& writer) const { - for (const BlockInfo& info : m_blockInfos) { - BlockInfo modInfo = info; - modInfo.compSize = 0; - modInfo.write(writer); - } -} - -bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool force, - hecl::blender::Token& btok, std::function) { - using RigPair = std::pair, std::pair>; - RigPair dummy = {}; - - if (!force && outPath.isFile()) - return true; - - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* MREA decompression stream */ - StreamReader drs(rs, head.compressedBlockCount); - hecl::ProjectPath decompPath = outPath.getCookedPath(SpecEntMP2ORIG).getWithExtension(".decomp"); - decompPath.makeDirChain(false); - athena::io::FileWriter mreaDecompOut(decompPath.getAbsolutePath()); - head.write(mreaDecompOut); - mreaDecompOut.seekAlign32(); - drs.writeDecompInfos(mreaDecompOut); - mreaDecompOut.seekAlign32(); - atUint64 decompLen = drs.length(); - mreaDecompOut.writeBytes(drs.readBytes(decompLen).get(), decompLen); - mreaDecompOut.close(); - drs.seek(0, athena::SeekOrigin::Begin); - - /* Start up blender connection */ - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Area)) - return false; - - /* Calculate offset to EGMC section */ - atUint64 egmcOffset = 0; - for (unsigned i = 0; i < head.egmcSecIdx; i++) - egmcOffset += head.secSizes[i]; - - /* Load EGMC if possible so we can assign meshes to scanIds */ - drs.seek(egmcOffset, athena::SeekOrigin::Begin); - UniqueID32 egmcId(drs); - DNACommon::EGMC egmc; - pakRouter.lookupAndReadDNA(egmcId, egmc); - - drs.seek(0, athena::SeekOrigin::Begin); - - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os.format(FMT_STRING("import bpy\n" - "import bmesh\n" - "from mathutils import Vector\n" - "\n" - "bpy.context.scene.name = '{}'\n"), - pakRouter.getBestEntryName(entry, false)); - DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath()); - MaterialSet::RegisterMaterialProps(os); - os << "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "bpy.types.Light.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n" - "bpy.types.Light.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n" - "bpy.types.Object.retro_disable_enviro_visor = bpy.props.BoolProperty(name='Retro: Disable in Combat/Scan " - "Visor')\n" - "bpy.types.Object.retro_disable_thermal_visor = bpy.props.BoolProperty(name='Retro: Disable in Thermal " - "Visor')\n" - "bpy.types.Object.retro_disable_xray_visor = bpy.props.BoolProperty(name='Retro: Disable in X-Ray Visor')\n" - "bpy.types.Object.retro_thermal_level = bpy.props.EnumProperty(items=[('COOL', 'Cool', 'Cool Temperature')," - "('HOT', 'Hot', 'Hot Temperature')," - "('WARM', 'Warm', 'Warm Temperature')]," - "name='Retro: Thermal Visor Level')\n" - "\n"; - - /* One shared material set for all meshes */ - os << "# Materials\n" - "materials = []\n" - "\n"; - MaterialSet matSet; - atUint64 secStart = drs.position(); - matSet.read(drs); - matSet.readToBlender(os, pakRouter, entry, 0); - drs.seek(secStart + head.secSizes[0], athena::SeekOrigin::Begin); - std::vector vertAttribs; - DNACMDL::GetVertexAttributes(matSet, vertAttribs); - - /* Read meshes */ - atUint32 curSec = 1; - for (atUint32 m = 0; m < head.meshCount; ++m) { - MeshHeader mHeader; - secStart = drs.position(); - mHeader.read(drs); - drs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - curSec += DNACMDL::ReadGeomSectionsToBlender, MaterialSet, RigPair, DNACMDL::SurfaceHeader_2>( - os, drs, pakRouter, entry, dummy, true, true, vertAttribs, m, head.secCount, 0, &head.secSizes[curSec]); - os.format(FMT_STRING("obj.retro_disable_enviro_visor = {}\n" - "obj.retro_disable_thermal_visor = {}\n" - "obj.retro_disable_xray_visor = {}\n" - "obj.retro_thermal_level = '{}'\n"), - mHeader.visorFlags.disableEnviro() ? "True" : "False", - mHeader.visorFlags.disableThermal() ? "True" : "False", - mHeader.visorFlags.disableXray() ? "True" : "False", mHeader.visorFlags.thermalLevelStr()); - - /* Seek through AROT-relation sections */ - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - } - - /* Skip AROT */ - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - - /* Skip BVH */ - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - - /* Skip Bitmap */ - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - - /* Skip SCLY (for now) */ - for (atUint32 l = 0; l < head.sclyLayerCount; ++l) { - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - } - - /* Skip SCGN (for now) */ - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - - /* Read collision meshes */ - DeafBabe collision; - secStart = drs.position(); - collision.read(drs); - DeafBabe::BlenderInit(os); - collision.sendToBlender(os); - drs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Skip unknown section */ - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - - /* Read BABEDEAD Lights as Cycles emissives */ - secStart = drs.position(); - DNAMP1::MREA::ReadBabeDeadToBlender_1_2(os, drs); - drs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Origins to center of mass */ - os << "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = False\n" - "bpy.ops.object.select_by_type(type='MESH')\n" - "bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')\n" - "bpy.ops.object.select_all(action='DESELECT')\n" - "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = True\n"; - - os.centerView(); - os.close(); - return conn.saveBlend(); -} - -UniqueID32 MREA::GetPATHId(PAKEntryReadStream& rs) { - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* MREA decompression stream */ - StreamReader drs(rs, head.compressedBlockCount); - - /* Skip to PATH */ - drs.seekToSection(head.pathSecIdx, head.secSizes); - return {drs}; -} - -} // namespace DNAMP2 -} // namespace DataSpec diff --git a/DataSpec/DNAMP2/MREA.hpp b/DataSpec/DNAMP2/MREA.hpp deleted file mode 100644 index 088f47c0e..000000000 --- a/DataSpec/DNAMP2/MREA.hpp +++ /dev/null @@ -1,129 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "CMDLMaterials.hpp" -#include "CSKR.hpp" - -namespace DataSpec::DNAMP2 { - -struct MREA { - class StreamReader : public athena::io::IStreamReader { - protected: - struct BlockInfo : BigDNA { - AT_DECL_DNA - Value bufSize; - Value decompSize; - Value compSize; - Value secCount; - }; - std::vector m_blockInfos; - - size_t m_compBufSz; - std::unique_ptr m_compBuf; - size_t m_decompBufSz; - std::unique_ptr m_decompBuf; - athena::io::IStreamReader& m_source; - atUint64 m_blkBase; - atUint32 m_blkCount; - atUint32 m_totalDecompLen = 0; - atUint32 m_pos = 0; - - atUint32 m_nextBlk = 0; - atUint32 m_posInBlk = 0; - atUint32 m_blkSz = 0; - void nextBlock(); - - StreamReader(athena::io::IStreamReader& source) - : m_compBufSz(0x4120) - , m_compBuf(new atUint8[0x4120]) - , m_decompBufSz(0x4120) - , m_decompBuf(new atUint8[0x4120]) - , m_source(source) {} /* Empty constructor for inheriting */ - - public: - StreamReader(athena::io::IStreamReader& source, atUint32 blkCount); - void seek(atInt64 diff, athena::SeekOrigin whence) override; - void seekToSection(atUint32 sec, const std::vector& secSizes); - atUint64 position() const override { return m_pos; } - atUint64 length() const override { return m_totalDecompLen; } - atUint64 readUBytesToBuf(void* buf, atUint64 len) override; - void writeDecompInfos(athena::io::IStreamWriter& writer) const; - }; - - struct Header : BigDNA { - AT_DECL_DNA - Value magic; - Value version; - Value localToWorldMtx[3]; - Value meshCount; - Value sclyLayerCount; - Value secCount; - Value geomSecIdx; - Value sclySecIdx; - Value scgnSecIdx; - Value collisionSecIdx; - Value unkSecIdx; - Value lightSecIdx; - Value emptySecIdx; - Value pathSecIdx; - Value unk2SecIdx; - Value unk3SecIdx; - Value egmcSecIdx; - Value compressedBlockCount; - Seek<12, athena::SeekOrigin::Current> align1; - Vector secSizes; - }; - - struct MeshHeader : BigDNA { - AT_DECL_DNA - struct VisorFlags : BigDNA { - AT_DECL_DNA - Value flags; - enum class ThermalLevel { Cool, Hot, Warm }; - static const char* GetThermalLevelStr(ThermalLevel t) { - switch (t) { - case ThermalLevel::Cool: - return "COOL"; - case ThermalLevel::Hot: - return "HOT"; - case ThermalLevel::Warm: - return "WARM"; - default: - break; - } - return nullptr; - } - bool disableEnviro() const { return flags >> 1 & 0x1; } - void setDisableEnviro(bool v) { - flags &= ~0x2; - flags |= v << 1; - } - bool disableThermal() const { return flags >> 2 & 0x1; } - void setDisableThermal(bool v) { - flags &= ~0x4; - flags |= v << 2; - } - bool disableXray() const { return flags >> 3 & 0x1; } - void setDisableXray(bool v) { - flags &= ~0x8; - flags |= v << 3; - } - ThermalLevel thermalLevel() const { return ThermalLevel(flags >> 4 & 0x3); } - void setThermalLevel(ThermalLevel v) { - flags &= ~0x30; - flags |= atUint32(v) << 4; - } - const char* thermalLevelStr() const { return GetThermalLevelStr(thermalLevel()); } - } visorFlags; - Value xfMtx[3]; - Value aabb[2]; - }; - - static UniqueID32 GetPATHId(PAKEntryReadStream& rs); - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool, - hecl::blender::Token& btok, std::function); -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/PAK.cpp b/DataSpec/DNAMP2/PAK.cpp deleted file mode 100644 index b7352cadc..000000000 --- a/DataSpec/DNAMP2/PAK.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "PAK.hpp" -#include "AGSC.hpp" - -namespace DataSpec::DNAMP2 { - -std::string PAK::bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const { - std::unordered_map::const_iterator search; - if (entry.type == FOURCC('AGSC') && (search = m_entries.find(entry.id)) != m_entries.cend()) { - /* Use internal AGSC name for entry */ - auto rs = search->second.beginReadStream(pakNode); - AGSC::Header header; - header.read(rs); - catalogueName = header.groupName; - return fmt::format(FMT_STRING("{}_{}"), header.groupName, entry.id); - } - - return DNAMP1::PAK::bestEntryName(pakNode, entry, catalogueName); -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/PAK.hpp b/DataSpec/DNAMP2/PAK.hpp deleted file mode 100644 index c2c145d41..000000000 --- a/DataSpec/DNAMP2/PAK.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "../DNAMP1/PAK.hpp" - -namespace DataSpec::DNAMP2 { - -/* Same PAK format as MP1 */ -struct PAK : DNAMP1::PAK { - using DNAMP1::PAK::PAK; - std::string bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const; -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/PATH.hpp b/DataSpec/DNAMP2/PATH.hpp deleted file mode 100644 index 676f4479d..000000000 --- a/DataSpec/DNAMP2/PATH.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include "DataSpec/DNACommon/PATH.hpp" - -namespace DataSpec::DNAMP2 { -using PATH = DNAPATH::PATH; -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/PTLA.hpp b/DataSpec/DNAMP2/PTLA.hpp deleted file mode 100644 index fad338ea3..000000000 --- a/DataSpec/DNAMP2/PTLA.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace DataSpec::DNAMP2 { -struct PTLA : BigDNA { - AT_DECL_DNA - Value magic; - struct UnknownStruct1 : BigDNA { - AT_DECL_DNA - Value count; - struct Entry : BigDNA { - AT_DECL_DNA - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - }; - Vector entries; - Value unknown1; - Value unknown2[2]; - }; - Value count1; - Vector entries1; - - struct UnknownStruct2 : BigDNA { - AT_DECL_DNA - Value count; - struct Entry : BigDNA { - AT_DECL_DNA - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - }; - Vector entries; - Value unknown; - }; - Value count2; - Vector entries2; - - Value shortCount1; - Vector shorts1; - - Value shortCount2; - Vector shorts2; - - struct UnknownStruct3 : BigDNA { - AT_DECL_DNA - Value unknown1[2]; - Value unknown2; - Value unknown3; - Value unknown4; - }; - Value count3; - Vector entries3; -}; -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/SAVW.hpp b/DataSpec/DNAMP2/SAVW.hpp deleted file mode 100644 index e0eea6563..000000000 --- a/DataSpec/DNAMP2/SAVW.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../DNAMP1/SAVW.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { -struct SAVW : DNAMP1::SAVW { - AT_DECL_DNA_YAML - Value systemVarCount; - Vector systemVars; - Value gameVarCount; - Vector gameVars; - Value gameObjectCount; - Vector gameObjects; -}; -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/STRG.cpp b/DataSpec/DNAMP2/STRG.cpp deleted file mode 100644 index d48ea8fb2..000000000 --- a/DataSpec/DNAMP2/STRG.cpp +++ /dev/null @@ -1,221 +0,0 @@ -#include "STRG.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { - -void STRG::_read(athena::io::IStreamReader& reader) { - atUint32 langCount = reader.readUint32Big(); - atUint32 strCount = reader.readUint32Big(); - - std::vector readLangs; - readLangs.reserve(langCount); - for (atUint32 l = 0; l < langCount; ++l) { - DNAFourCC lang; - lang.read(reader); - readLangs.emplace_back(lang); - reader.seek(8); - } - - atUint32 nameCount = reader.readUint32Big(); - atUint32 nameTableSz = reader.readUint32Big(); - std::unique_ptr nameTableBuf(new uint8_t[nameTableSz]); - reader.readUBytesToBuf(nameTableBuf.get(), nameTableSz); - struct NameIdxEntry { - atUint32 nameOff; - atUint32 strIdx; - }* nameIndex = (NameIdxEntry*)nameTableBuf.get(); - for (atUint32 n = 0; n < nameCount; ++n) { - const char* name = (char*)(nameTableBuf.get() + hecl::SBig(nameIndex[n].nameOff)); - names[name] = hecl::SBig(nameIndex[n].strIdx); - } - - langs.clear(); - langs.reserve(langCount); - for (FourCC& lang : readLangs) { - std::vector strs; - reader.seek(strCount * 4); - for (atUint32 s = 0; s < strCount; ++s) - strs.emplace_back(reader.readU16StringBig()); - langs.emplace_back(lang, strs); - } - - langMap.clear(); - langMap.reserve(langCount); - for (std::pair>& item : langs) - langMap.emplace(item.first, &item.second); -} - -template <> -void STRG::Enumerate(athena::io::IStreamReader& reader) { - atUint32 magic = reader.readUint32Big(); - if (magic != 0x87654321) - Log.report(logvisor::Error, FMT_STRING("invalid STRG magic")); - - atUint32 version = reader.readUint32Big(); - if (version != 1) - Log.report(logvisor::Error, FMT_STRING("invalid STRG version")); - - _read(reader); -} - -template <> -void STRG::Enumerate(athena::io::IStreamWriter& writer) { - writer.writeUint32Big(0x87654321); - writer.writeUint32Big(1); - writer.writeUint32Big(langs.size()); - atUint32 strCount = STRG::count(); - writer.writeUint32Big(strCount); - - atUint32 offset = 0; - for (const auto& lang : langs) { - DNAFourCC{lang.first}.write(writer); - writer.writeUint32Big(offset); - offset += strCount * 4 + 4; - atUint32 langStrCount = lang.second.size(); - atUint32 tableSz = strCount * 4; - for (atUint32 s = 0; s < strCount; ++s) { - atUint32 chCount = lang.second[s].size(); - if (s < langStrCount) { - offset += chCount * 2 + 1; - tableSz += chCount * 2 + 1; - } else { - offset += 1; - tableSz += 1; - } - } - writer.writeUint32Big(tableSz); - } - - atUint32 nameTableSz = names.size() * 8; - for (const auto& name : names) { - nameTableSz += name.first.size() + 1; - } - writer.writeUint32Big(names.size()); - writer.writeUint32Big(nameTableSz); - offset = names.size() * 8; - for (const auto& name : names) { - writer.writeUint32Big(offset); - writer.writeInt32Big(name.second); - offset += name.first.size() + 1; - } - for (const auto& name : names) { - writer.writeString(name.first); - } - - for (const auto& lang : langs) { - offset = strCount * 4; - atUint32 langStrCount = lang.second.size(); - for (atUint32 s = 0; s < strCount; ++s) { - writer.writeUint32Big(offset); - if (s < langStrCount) - offset += lang.second[s].size() * 2 + 1; - else - offset += 1; - } - - for (atUint32 s = 0; s < strCount; ++s) { - if (s < langStrCount) - writer.writeU16StringBig(lang.second[s]); - else - writer.writeUByte(0); - } - } -} - -template <> -void STRG::Enumerate(size_t& __isz) { - __isz += 16; - - __isz += langs.size() * 12; - - __isz += 8; - __isz += names.size() * 8; - for (const auto& name : names) { - __isz += name.first.size() + 1; - } - - size_t strCount = STRG::count(); - for (const auto& lang : langs) { - atUint32 langStrCount = lang.second.size(); - __isz += strCount * 4; - - for (atUint32 s = 0; s < strCount; ++s) { - if (s < langStrCount) - __isz += (lang.second[s].size() + 1) * 2; - else - __isz += 1; - } - } -} - -template <> -void STRG::Enumerate(athena::io::YAMLDocReader& reader) { - const athena::io::YAMLNode* root = reader.getRootNode(); - - /* Validate Pass */ - if (root->m_type == YAML_MAPPING_NODE) { - for (const auto& lang : root->m_mapChildren) { - if (lang.first == "names") - continue; - if (lang.first.size() != 4) { - Log.report(logvisor::Warning, FMT_STRING("STRG language string '{}' must be exactly 4 characters; skipping"), - lang.first); - return; - } - if (lang.second->m_type != YAML_SEQUENCE_NODE) { - Log.report(logvisor::Warning, FMT_STRING("STRG language string '{}' must contain a sequence; skipping"), - lang.first); - return; - } - for (const auto& str : lang.second->m_seqChildren) { - if (str->m_type != YAML_SCALAR_NODE) { - Log.report(logvisor::Warning, FMT_STRING("STRG language '{}' must contain all scalars; skipping"), - lang.first); - return; - } - } - } - } else { - Log.report(logvisor::Warning, FMT_STRING("STRG must have a mapping root node; skipping")); - return; - } - - /* Read Pass */ - langs.clear(); - for (const auto& lang : root->m_mapChildren) { - std::vector strs; - for (const auto& str : lang.second->m_seqChildren) - strs.emplace_back(hecl::UTF8ToChar16(str->m_scalarString)); - langs.emplace_back(FourCC(lang.first.c_str()), strs); - } - - names.clear(); - const athena::io::YAMLNode* namesNode = root->findMapChild("names"); - if (namesNode) - for (const auto& item : namesNode->m_mapChildren) - names[item.first] = athena::io::NodeToVal(item.second.get()); - - langMap.clear(); - langMap.reserve(langs.size()); - for (std::pair>& item : langs) - langMap.emplace(item.first, &item.second); -} - -template <> -void STRG::Enumerate(athena::io::YAMLDocWriter& writer) { - for (const auto& lang : langs) { - if (auto v = writer.enterSubVector(lang.first.toString())) - for (const std::u16string& str : lang.second) - writer.writeU16String(str); - } - if (names.size()) { - if (auto rec = writer.enterSubRecord("names")) - for (const auto& name : names) - if (auto rec = writer.enterSubRecord(name.first)) - writer.writeInt32(name.second); - } -} - -std::string_view STRG::DNAType() { return "DNAMP2::STRG"sv; } - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/STRG.hpp b/DataSpec/DNAMP2/STRG.hpp deleted file mode 100644 index d740423fe..000000000 --- a/DataSpec/DNAMP2/STRG.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/STRG.hpp" - -namespace DataSpec::DNAMP2 { - -struct STRG : ISTRG { - AT_DECL_EXPLICIT_DNA_YAMLV - void _read(athena::io::IStreamReader& reader); - std::vector>> langs; - std::unordered_map*> langMap; - std::map names; - - int32_t lookupIdx(std::string_view name) const override { - // TODO: Heterogeneous lookup when C++20 available - auto search = names.find(name.data()); - if (search == names.end()) - return -1; - return search->second; - } - - size_t count() const override { - size_t retval = 0; - for (const auto& item : langs) { - size_t sz = item.second.size(); - if (sz > retval) - retval = sz; - } - return retval; - } - std::string getUTF8(const FourCC& lang, size_t idx) const override { - auto search = langMap.find(lang); - if (search != langMap.end()) - return hecl::Char16ToUTF8(search->second->at(idx)); - return std::string(); - } - std::u16string getUTF16(const FourCC& lang, size_t idx) const override { - auto search = langMap.find(lang); - if (search != langMap.end()) - return search->second->at(idx); - return std::u16string(); - } - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - STRG strg; - strg.read(rs); - athena::io::TransactionalFileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(strg, writer); - return true; - } - - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - STRG strg; - athena::io::FileReader reader(inPath.getAbsolutePath()); - athena::io::FromYAMLStream(strg, reader); - athena::io::TransactionalFileWriter ws(outPath.getAbsolutePath()); - strg.write(ws); - return true; - } -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/ScriptObjects/CMakeLists.txt b/DataSpec/DNAMP2/ScriptObjects/CMakeLists.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/DataSpec/DNAMP3/ANIM.cpp b/DataSpec/DNAMP3/ANIM.cpp deleted file mode 100644 index e35825894..000000000 --- a/DataSpec/DNAMP3/ANIM.cpp +++ /dev/null @@ -1,537 +0,0 @@ -#include "ANIM.hpp" -#include -#include "zeus/Math.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP3 { - -using ANIMOutStream = hecl::blender::ANIMOutStream; - -void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter& rig, - bool additive) const { - os.format(FMT_STRING("act.hecl_fps = round({})\n" - "act.hecl_additive = {}\n" - "act.hecl_looping = {}\n"), - 1.0f / mainInterval, additive ? "True" : "False", looping ? "True" : "False"); - - auto kit = chanKeys.begin() + 1; - - std::vector fixedRotKeys; - std::vector fixedTransKeys; - - for (const std::pair>& bone : bones) { - const std::string* bName = rig.getCINF().getBoneNameFromId(bone.first); - if (!bName) { - if (std::get<0>(bone.second)) - ++kit; - if (std::get<1>(bone.second)) - ++kit; - if (std::get<2>(bone.second)) - ++kit; - continue; - } - - os.format(FMT_STRING("bone_string = '{}'\n"), *bName); - os << "action_group = act.groups.new(bone_string)\n" - "\n"; - - if (std::get<0>(bone.second)) - os << "rotCurves = []\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=0, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=1, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=2, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=3, " - "action_group=bone_string))\n" - "\n"; - - if (std::get<1>(bone.second)) - os << "transCurves = []\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=0, " - "action_group=bone_string))\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=1, " - "action_group=bone_string))\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=2, " - "action_group=bone_string))\n" - "\n"; - - if (std::get<2>(bone.second)) - os << "scaleCurves = []\n" - "scaleCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].scale', index=0, " - "action_group=bone_string))\n" - "scaleCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].scale', index=1, " - "action_group=bone_string))\n" - "scaleCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].scale', index=2, " - "action_group=bone_string))\n" - "\n"; - - ANIMOutStream ao = os.beginANIMCurve(); - if (std::get<0>(bone.second)) { - const std::vector& rotKeys = *kit++; - fixedRotKeys.clear(); - fixedRotKeys.resize(rotKeys.size()); - - for (int c = 0; c < 4; ++c) { - size_t idx = 0; - for (const DNAANIM::Value& val : rotKeys) - fixedRotKeys[idx++][c] = val.simd[c]; - } - - for (zeus::CQuaternion& rot : fixedRotKeys) - rot = rig.invertRotation(bone.first, rot); - - for (int c = 0; c < 4; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Rotate, c, rotKeys.size()); - for (const zeus::CQuaternion& val : fixedRotKeys) - ao.write(*frameit++, val[c]); - } - } - - if (std::get<1>(bone.second)) { - const std::vector& transKeys = *kit++; - fixedTransKeys.clear(); - fixedTransKeys.resize(transKeys.size()); - - for (int c = 0; c < 3; ++c) { - size_t idx = 0; - for (const DNAANIM::Value& val : transKeys) - fixedTransKeys[idx++][c] = val.simd[c]; - } - - for (zeus::CVector3f& t : fixedTransKeys) - t = rig.invertPosition(bone.first, t, !additive); - - for (int c = 0; c < 3; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Translate, c, fixedTransKeys.size()); - for (const zeus::CVector3f& val : fixedTransKeys) - ao.write(*frameit++, val[c]); - } - } - - if (std::get<2>(bone.second)) { - const std::vector& scaleKeys = *kit++; - for (int c = 0; c < 3; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Scale, c, scaleKeys.size()); - for (const DNAANIM::Value& val : scaleKeys) - ao.write(*frameit++, val.simd[c]); - } - } - } -} - -template <> -void ANIM::Enumerate(typename Read::StreamT& reader) { - atUint32 version = reader.readUint32Big(); - switch (version) { - case 0: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case 1: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - default: - Log.report(logvisor::Fatal, FMT_STRING("unrecognized ANIM version")); - break; - } -} - -template <> -void ANIM::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(m_anim->m_version); - m_anim->write(writer); -} - -template <> -void ANIM::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - m_anim->binarySize(s); -} - -std::string_view ANIM::ANIM0::DNAType() { return "ANIM0"sv; } - -template <> -void ANIM::ANIM0::Enumerate(athena::io::IStreamReader& reader) { - Header head; - head.read(reader); - mainInterval = head.interval; - - frames.clear(); - frames.reserve(head.keyCount); - for (size_t k = 0; k < head.keyCount; ++k) - frames.push_back(k); - - std::map boneMap; - for (size_t b = 0; b < head.boneSlotCount; ++b) { - atUint8 idx = reader.readUByte(); - if (idx == 0xff) - continue; - boneMap[idx] = b; - } - - atUint32 boneCount = reader.readUint32Big(); - bones.clear(); - bones.reserve(boneCount); - for (size_t b = 0; b < boneCount; ++b) { - bones.emplace_back(boneMap[b], std::make_tuple(false, false, false)); - atUint8 idx = reader.readUByte(); - if (idx != 0xff) - std::get<0>(bones.back().second) = true; - } - - boneCount = reader.readUint32Big(); - for (size_t b = 0; b < boneCount; ++b) { - atUint8 idx = reader.readUByte(); - if (idx != 0xff) - std::get<1>(bones[b].second) = true; - } - - boneCount = reader.readUint32Big(); - for (size_t b = 0; b < boneCount; ++b) { - atUint8 idx = reader.readUByte(); - if (idx != 0xff) - std::get<2>(bones[b].second) = true; - } - - channels.clear(); - chanKeys.clear(); - channels.emplace_back(); - channels.back().type = DNAANIM::Channel::Type::KfHead; - chanKeys.emplace_back(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Rotation; - chanKeys.emplace_back(); - } - if (std::get<1>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Translation; - chanKeys.emplace_back(); - } - if (std::get<2>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Scale; - chanKeys.emplace_back(); - } - } - - reader.readUint32Big(); - auto kit = chanKeys.begin() + 1; - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++kit; - if (std::get<1>(bone.second)) - ++kit; - if (std::get<2>(bone.second)) { - std::vector& keys = *kit++; - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec3fBig()); - } - } - - reader.readUint32Big(); - kit = chanKeys.begin() + 1; - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - std::vector& keys = *kit++; - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec4fBig()); - } - if (std::get<1>(bone.second)) - ++kit; - if (std::get<2>(bone.second)) - ++kit; - } - - reader.readUint32Big(); - kit = chanKeys.begin() + 1; - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++kit; - if (std::get<1>(bone.second)) { - std::vector& keys = *kit++; - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec3fBig()); - } - if (std::get<2>(bone.second)) - ++kit; - } -} - -template <> -void ANIM::ANIM0::Enumerate(athena::io::IStreamWriter& writer) { - Header head; - head.unk0 = 0; - head.unk1 = 0; - head.unk2 = 0; - head.keyCount = frames.size(); - head.duration = head.keyCount * mainInterval; - head.interval = mainInterval; - - atUint32 maxId = 0; - for (const std::pair>& bone : bones) - maxId = std::max(maxId, bone.first); - head.boneSlotCount = maxId + 1; - head.write(writer); - - for (size_t s = 0; s < head.boneSlotCount; ++s) { - size_t boneIdx = 0; - bool found = false; - for (const std::pair>& bone : bones) { - if (s == bone.first) { - writer.writeUByte(boneIdx); - found = true; - break; - } - ++boneIdx; - } - if (!found) - writer.writeUByte(0xff); - } - - writer.writeUint32Big(bones.size()); - size_t boneIdx = 0; - size_t rotKeyCount = 0; - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - writer.writeUByte(boneIdx); - ++rotKeyCount; - } else - writer.writeUByte(0xff); - ++boneIdx; - } - - writer.writeUint32Big(bones.size()); - boneIdx = 0; - size_t transKeyCount = 0; - for (const std::pair>& bone : bones) { - if (std::get<1>(bone.second)) { - writer.writeUByte(boneIdx); - ++transKeyCount; - } else - writer.writeUByte(0xff); - ++boneIdx; - } - - writer.writeUint32Big(bones.size()); - boneIdx = 0; - size_t scaleKeyCount = 0; - for (const std::pair>& bone : bones) { - if (std::get<2>(bone.second)) { - writer.writeUByte(boneIdx); - ++scaleKeyCount; - } else - writer.writeUByte(0xff); - ++boneIdx; - } - - writer.writeUint32Big(scaleKeyCount * head.keyCount); - auto cit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++cit; - if (std::get<1>(bone.second)) - ++cit; - if (std::get<2>(bone.second)) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec3fBig(atVec3f{(*kit++).simd}); - } - } - - writer.writeUint32Big(rotKeyCount * head.keyCount); - cit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec4fBig(atVec4f{(*kit++).simd}); - } - if (std::get<1>(bone.second)) - ++cit; - if (std::get<2>(bone.second)) - ++cit; - } - - writer.writeUint32Big(transKeyCount * head.keyCount); - cit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++cit; - if (std::get<1>(bone.second)) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec3fBig(atVec3f{(*kit++).simd}); - } - if (std::get<2>(bone.second)) - ++cit; - } -} - -template <> -void ANIM::ANIM0::Enumerate(size_t& __isz) { - Header head; - - atUint32 maxId = 0; - for (const std::pair>& bone : bones) - maxId = std::max(maxId, bone.first); - - head.binarySize(__isz); - __isz += maxId + 1; - __isz += bones.size() * 3 + 12; - - __isz += 12; - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - __isz += head.keyCount * 16; - if (std::get<1>(bone.second)) - __isz += head.keyCount * 12; - if (std::get<2>(bone.second)) - __isz += head.keyCount * 12; - } -} - -static float ComputeFrames(const std::vector& keyTimes, std::vector& framesOut) { - if (keyTimes.size() <= 1) - return 0.0; - - float mainInterval = FLT_MAX; - float lastTime = keyTimes[0]; - for (auto it = keyTimes.begin() + 1; it != keyTimes.end(); ++it) { - float diff = *it - lastTime; - if (diff < mainInterval) - mainInterval = diff; - lastTime = *it; - } - - float fps = round(1.0 / mainInterval); - if (fps < 15.0) - fps = 15.0; - mainInterval = 1.0 / fps; - - framesOut.clear(); - framesOut.reserve(keyTimes.size()); - atUint32 frameAccum = 0; - for (float time : keyTimes) { - while (frameAccum * mainInterval < time) - ++frameAccum; - framesOut.push_back(frameAccum); - } - - return mainInterval; -} - -std::string_view ANIM::ANIM1::DNAType() { return "ANIM1"sv; } - -template <> -void ANIM::ANIM1::Enumerate(athena::io::IStreamReader& reader) { - Header head; - head.read(reader); - - std::vector keyTimes; - keyTimes.reserve(head.keyCount); - for (size_t k = 0; k < head.keyCount; ++k) - keyTimes.push_back(reader.readFloatBig()); - mainInterval = ComputeFrames(keyTimes, frames); - - atUint8 boneFlagCount = reader.readUByte(); - bones.clear(); - bones.reserve(boneFlagCount); - atUint32 boneChannelCount = 0; - for (atUint8 f = 0; f < boneFlagCount; ++f) { - atUint8 flag = reader.readUByte(); - bones.emplace_back(f, std::make_tuple(bool(flag & 0x1), bool(flag & 0x2), bool(flag & 0x4))); - if (flag & 0x1) - ++boneChannelCount; - if (flag & 0x2) - ++boneChannelCount; - if (flag & 0x4) - ++boneChannelCount; - } - - std::vector initBlock; - initBlock.reserve(head.initBlockSize / 2); - for (size_t i = 0; i < head.initBlockSize / 2; ++i) - initBlock.push_back(reader.readInt16Big()); - - atUint32 rawChannelCount = reader.readUint32Big(); - reader.readUint32Big(); - reader.readUint32Big(); - - std::vector chanBitCounts; - chanBitCounts.reserve(rawChannelCount); - for (size_t c = 0; c < rawChannelCount; ++c) - chanBitCounts.push_back(reader.readUByte()); - - channels.clear(); - channels.reserve(boneChannelCount + 1); - channels.emplace_back(); - channels.back().type = DNAANIM::Channel::Type::KfHead; - auto initsIt = initBlock.begin(); - auto bitsIt = chanBitCounts.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::RotationMP3; - chan.i[0] = *initsIt++; - chan.q[0] = *bitsIt++; - chan.i[1] = *initsIt++; - chan.q[1] = *bitsIt++; - chan.i[2] = *initsIt++; - chan.q[2] = *bitsIt++; - chan.i[3] = *initsIt++; - chan.q[3] = *bitsIt++; - } - - if (std::get<1>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Translation; - chan.i[0] = *initsIt++; - chan.q[0] = *bitsIt++; - chan.i[1] = *initsIt++; - chan.q[1] = *bitsIt++; - chan.i[2] = *initsIt++; - chan.q[2] = *bitsIt++; - } - - if (std::get<2>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Scale; - chan.i[0] = *initsIt++; - chan.q[0] = *bitsIt++; - chan.i[1] = *initsIt++; - chan.q[1] = *bitsIt++; - chan.i[2] = *initsIt++; - chan.q[2] = *bitsIt++; - } - } - - size_t bsSize = DNAANIM::ComputeBitstreamSize(head.keyCount - 1, channels); - std::unique_ptr bsData = reader.readUBytes(bsSize); - DNAANIM::BitstreamReader bsReader; - chanKeys = bsReader.read(bsData.get(), head.keyCount - 1, channels, 32767, head.translationMult, head.scaleMult); -} - -template <> -void ANIM::ANIM1::Enumerate(athena::io::IStreamWriter& writer) {} - -template <> -void ANIM::ANIM1::Enumerate(size_t& __isz) {} - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/ANIM.hpp b/DataSpec/DNAMP3/ANIM.hpp deleted file mode 100644 index d7cd97aba..000000000 --- a/DataSpec/DNAMP3/ANIM.hpp +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once - -#include "DNAMP3.hpp" -#include "DataSpec/DNACommon/ANIM.hpp" -#include "DataSpec/DNACommon/RigInverter.hpp" -#include "CINF.hpp" -#include "DataSpec/DNACommon/ANCS.hpp" - -namespace DataSpec::DNAMP3 { - -struct ANIM : BigDNA { - AT_DECL_EXPLICIT_DNA - - struct IANIM : BigDNAV { - Delete expl; - atUint32 m_version; - IANIM(atUint32 version) : m_version(version) {} - - std::vector>> bones; - std::vector frames; - std::vector channels; - std::vector> chanKeys; - float mainInterval = 0.0; - bool looping = false; - - void sendANIMToBlender(hecl::blender::PyOutStream&, const DNAANIM::RigInverter& rig, bool additive) const; - }; - - struct ANIM0 : IANIM { - AT_DECL_EXPLICIT_DNAV - ANIM0() : IANIM(0) {} - - struct Header : BigDNA { - AT_DECL_DNA - Value unkS; - Value duration; - Value unk0; - Value interval; - Value unk1; - Value keyCount; - Value unk2; - Value boneSlotCount; - }; - }; - - struct ANIM1 : IANIM { - AT_DECL_EXPLICIT_DNAV - ANIM1() : IANIM(1) {} - - struct Header : BigDNA { - AT_DECL_DNA - Value unk1; - Value unk2; - Value unk3; - Value unk4[3]; - Value translationMult; - Value scaleMult; - Value unk7; - Value unk8; - Value unk9; - Value duration; - Value keyCount; - Value blobSize; - Value unk10; - Value floatsSize; - Value flagsSize; - Value initBlockSize; - Value streamSize; - Value unk11; - Value boneCount; - }; - }; - - std::unique_ptr m_anim; - - void sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter& rig, bool additive) const { - m_anim->sendANIMToBlender(os, rig, additive); - } - - void extractEVNT(const DNAANCS::AnimationResInfo& animInfo, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, bool force) const {} -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CAUD.hpp b/DataSpec/DNAMP3/CAUD.hpp deleted file mode 100644 index 6b9964849..000000000 --- a/DataSpec/DNAMP3/CAUD.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/MayaSpline.hpp" -#include "DataSpec/DNACommon/PAK.hpp" -namespace DataSpec::DNAMP3 { - -struct CAUD : BigDNA { - AT_DECL_DNA_YAML - DNAFourCC magic; - Value version; - String<-1> name; - Value volumeGroupCount; - Vector, AT_DNA_COUNT(volumeGroupCount)> volumeGroups; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - - struct CSMPInfo : BigDNA { - AT_DECL_DNA_YAML - Value dataLen; - UniqueID64 csmpId; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - Value unknown16; - Value unknown17; - Value unknown18; - Value unknown19; - MayaSpline spline1; - MayaSpline spline2; - MayaSpline spline3; - MayaSpline spline4; - Value unkStructCount; - struct UnknownStruct : BigDNA { - AT_DECL_DNA_YAML - Value unknown1; - Value unknown2; - }; - Vector unkStructs; - Value unknown20; - Value unknown21; - Value unknown22; - Value unknown23; - MayaSpline spline5; - }; - - Value infoCount; - Vector info; - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - CAUD caud; - caud.read(rs); - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(caud, writer); - return true; - } -}; -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CHAR.cpp b/DataSpec/DNAMP3/CHAR.cpp deleted file mode 100644 index c9318d5d1..000000000 --- a/DataSpec/DNAMP3/CHAR.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "CHAR.hpp" - -namespace DataSpec::DNAMP3 { - -template <> -void CHAR::AnimationInfo::EVNT::SFXEvent::Enumerate(athena::io::IStreamReader& reader) { - EventBase::read(reader); - caudId.read(reader); - unk1 = reader.readUint32Big(); - unk2 = reader.readUint32Big(); - unk3 = reader.readUint32Big(); - reader.enumerateBig(unk3Vals, unk3); - extraType = reader.readUint32Big(); - if (extraType == 1) - extraFloat = reader.readFloatBig(); - else if (extraType == 2) - reader.seek(35, athena::SeekOrigin::Current); -} - -template <> -void CHAR::AnimationInfo::EVNT::SFXEvent::Enumerate(athena::io::IStreamWriter& writer) { - EventBase::write(writer); - caudId.write(writer); - writer.writeUint32Big(unk1); - writer.writeUint32Big(unk2); - writer.writeUint32Big(unk3); - writer.enumerateBig(unk3Vals); - writer.writeUint32Big(extraType); - if (extraType == 1) - writer.writeFloatBig(extraFloat); - else if (extraType == 2) - writer.seek(35, athena::SeekOrigin::Current); -} - -template <> -void CHAR::AnimationInfo::EVNT::SFXEvent::Enumerate(size_t& __isz) { - EventBase::binarySize(__isz); - caudId.binarySize(__isz); - __isz += 16; - __isz += unk3Vals.size() * 4; - if (extraType == 1) - __isz += 4; - else if (extraType == 2) - __isz += 35; -} - -template <> -void CHAR::AnimationInfo::EVNT::SFXEvent::Enumerate(athena::io::YAMLDocReader& reader) { - EventBase::read(reader); - reader.enumerate("caudId", caudId); - unk1 = reader.readUint32("unk1"); - unk2 = reader.readUint32("unk2"); - unk3 = reader.enumerate("unk3Vals", unk3Vals); - extraType = reader.readUint32("extraType"); - if (extraType == 1) - extraFloat = reader.readFloat("extraFloat"); -} - -template <> -void CHAR::AnimationInfo::EVNT::SFXEvent::Enumerate(athena::io::YAMLDocWriter& writer) { - EventBase::write(writer); - writer.enumerate("caudId", caudId); - writer.writeUint32("unk1", unk1); - writer.writeUint32("unk2", unk2); - writer.enumerate("unk3Vals", unk3Vals); - writer.writeUint32("extraType", extraType); - if (extraType == 1) - writer.writeFloat("extraFloat", extraFloat); -} - -std::string_view CHAR::AnimationInfo::EVNT::SFXEvent::DNAType() { - return "DNAMP3::CHAR::AnimationInfo::EVNT::SFXEvent"sv; -} - -template <> -void CHAR::AnimationInfo::MetaAnimFactory::Enumerate(athena::io::IStreamReader& reader) { - const auto type = IMetaAnim::Type(reader.readUint32Big()); - switch (type) { - case IMetaAnim::Type::Primitive: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::Blend: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::PhaseBlend: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::Random: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::Sequence: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - default: - m_anim.reset(); - break; - } -} - -template <> -void CHAR::AnimationInfo::MetaAnimFactory::Enumerate(athena::io::IStreamWriter& writer) { - if (!m_anim) - return; - writer.writeInt32Big(atInt32(m_anim->m_type)); - m_anim->write(writer); -} - -template <> -void CHAR::AnimationInfo::MetaAnimFactory::Enumerate(size_t& __isz) { - if (!m_anim) - return; - __isz += 4; - m_anim->binarySize(__isz); -} - -template <> -void CHAR::AnimationInfo::MetaAnimFactory::Enumerate(athena::io::YAMLDocReader& reader) { - std::string type = reader.readString("type"); - std::transform(type.begin(), type.end(), type.begin(), tolower); - if (type == "primitive") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "blend") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "phaseblend") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "random") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "sequence") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else { - m_anim.reset(); - } -} - -template <> -void CHAR::AnimationInfo::MetaAnimFactory::Enumerate(athena::io::YAMLDocWriter& writer) { - if (!m_anim) - return; - writer.writeString("type", m_anim->m_typeStr); - m_anim->write(writer); -} - -std::string_view CHAR::AnimationInfo::MetaAnimFactory::DNAType() { - return "DNAMP3::CHAR::AnimationInfo::MetaAnimFactory"sv; -} - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CHAR.hpp b/DataSpec/DNAMP3/CHAR.hpp deleted file mode 100644 index a07b4f53a..000000000 --- a/DataSpec/DNAMP3/CHAR.hpp +++ /dev/null @@ -1,295 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ANCS.hpp" -#include "CMDLMaterials.hpp" -#include "CINF.hpp" -#include "CSKR.hpp" -#include "ANIM.hpp" -#include "../DNAMP2/ANCS.hpp" - -namespace DataSpec::DNAMP3 { - -struct CHAR : BigDNA { - using CINFType = CINF; - using CSKRType = CSKR; - using ANIMType = ANIM; - - AT_DECL_DNA_YAML - Value version; - - struct CharacterInfo : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - UniqueID64 cmdl; - UniqueID64 cskr; - Value overlayCount; - struct Overlay : BigDNA { - AT_DECL_DNA_YAML - DNAFourCC type; - UniqueID64 cmdl; - UniqueID64 cskr; - }; - Vector overlays; - UniqueID64 cinf; - UniqueID64 sand; - - using MP1CharacterInfo = DNAMP1::ANCS::CharacterSet::CharacterInfo; - MP1CharacterInfo::PASDatabase pasDatabase; - - struct ParticleResData : BigDNA { - AT_DECL_DNA_YAML - Value partCount; - Vector part; - Value swhcCount; - Vector swhc; - Value unkCount; - Vector unk; - Value elscCount; - Vector elsc; - Value spscCount; - Vector spsc; - Value unk2Count; - Vector unk2; - } partResData; - - } characterInfo; - - struct AnimationInfo : BigDNA { - AT_DECL_DNA_YAML - - struct EVNT : BigDNA { - AT_DECL_DNA_YAML - Value eventIdx; - String<-1> eventName; - - struct EventBase : BigDNA { - AT_DECL_DNA_YAML - String<-1> name1; - Value unk0; - String<-1> name2; - Value type; - Value unk1; - Value unk2; - Value unk3; - Value unk4; - Value unk5; - Value unk6; - Value unk7; - Value unk8; - Value unk9; - Value unk10; - Value unk11; - Value unk12; - Value unk13; - }; - - struct EffectEvent : EventBase { - AT_DECL_DNA_YAML - DNAFourCC effectType; - UniqueID64 effectId; - Value scale; - Value parentMode; - }; - Value effectCount; - Vector effectEvents; - - struct SFXEvent : EventBase { - AT_DECL_DNA_YAML - Delete expl; - - UniqueID64 caudId; - Value unk1_; - Value unk2_; - Value unk3_; - std::vector unk3Vals; - Value extraType; - Value extraFloat; - }; - Value sfxCount; - Vector sfxEvents; - }; - Value evntCount; - Vector evnts; - - struct IMetaAnim : BigDNAVYaml { - Delete expl; - enum class Type { Primitive = 0, Blend = 1, PhaseBlend = 2, Random = 3, Sequence = 4 } m_type; - const char* m_typeStr; - IMetaAnim(Type type, const char* typeStr) : m_type(type), m_typeStr(typeStr) {} - virtual void gatherPrimitives(std::map>& out) = 0; - }; - struct MetaAnimFactory : BigDNA { - AT_DECL_DNA_YAML - Delete expl; - std::unique_ptr m_anim; - }; - struct MetaAnimPrimitive : IMetaAnim { - MetaAnimPrimitive() : IMetaAnim(Type::Primitive, "Primitive") {} - AT_DECL_DNA_YAMLV - UniqueID64 animId; - Value animIdx; - String<-1> animName; - Value unk1; - Value unk2; - - void gatherPrimitives(std::map>& out) override { - out[animIdx] = {animName, animId, UniqueID64(), false}; - } - }; - struct MetaAnimBlend : IMetaAnim { - MetaAnimBlend() : IMetaAnim(Type::Blend, "Blend") {} - AT_DECL_DNA_YAMLV - MetaAnimFactory animA; - MetaAnimFactory animB; - Value unkFloat; - Value unk; - - void gatherPrimitives(std::map>& out) override { - animA.m_anim->gatherPrimitives(out); - animB.m_anim->gatherPrimitives(out); - } - }; - struct MetaAnimPhaseBlend : IMetaAnim { - MetaAnimPhaseBlend() : IMetaAnim(Type::PhaseBlend, "PhaseBlend") {} - AT_DECL_DNA_YAMLV - MetaAnimFactory animA; - MetaAnimFactory animB; - Value unkFloat; - Value unk; - - void gatherPrimitives(std::map>& out) override { - animA.m_anim->gatherPrimitives(out); - animB.m_anim->gatherPrimitives(out); - } - }; - struct MetaAnimRandom : IMetaAnim { - MetaAnimRandom() : IMetaAnim(Type::Random, "Random") {} - AT_DECL_DNA_YAMLV - Value animCount; - struct Child : BigDNA { - AT_DECL_DNA_YAML - MetaAnimFactory anim; - Value probability; - }; - Vector children; - - void gatherPrimitives(std::map>& out) override { - for (const auto& child : children) - child.anim.m_anim->gatherPrimitives(out); - } - }; - struct MetaAnimSequence : IMetaAnim { - MetaAnimSequence() : IMetaAnim(Type::Sequence, "Sequence") {} - AT_DECL_DNA_YAMLV - Value animCount; - Vector children; - - void gatherPrimitives(std::map>& out) override { - for (const auto& child : children) - child.m_anim->gatherPrimitives(out); - } - }; - - struct Animation : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - MetaAnimFactory metaAnim; - }; - Value animationCount; - Vector animations; - - struct ActionAABB : BigDNA { - AT_DECL_DNA_YAML - UniqueID64 animId; - Value aabb[2]; - }; - Value animAABBCount; - Vector animAABBs; - - Value unkByte; - - Value additiveMapCount; - Vector additiveMap; - - } animationInfo; - - struct HitboxSet : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value hitboxCount; - struct Hitbox : BigDNA { - AT_DECL_DNA_YAML - Value unk1; - Value unk2; - Value unk3; - Value unk4; - Value unk5; - Value unk6; - Value unk7; - Value unk8; - Value unk9; - Value unk10; - Value unk11; - Value unk12; - Value unk13; - String<-1> boneName; - Value unk14; - }; - Vector hitboxes; - }; - Value hitboxSetCount; - Vector hitboxSets; - - void getCharacterResInfo(std::vector>& out) const { - out.clear(); - out.reserve(1); - out.emplace_back(); - DNAANCS::CharacterResInfo& chOut = out.back(); - chOut.name = characterInfo.name; - chOut.cmdl = characterInfo.cmdl; - chOut.cskr = characterInfo.cskr; - chOut.cinf = characterInfo.cinf; - - for (const CharacterInfo::Overlay& overlay : characterInfo.overlays) - chOut.overlays.emplace_back(overlay.type.toString(), std::make_pair(overlay.cmdl, overlay.cskr)); - } - - void getAnimationResInfo(PAKRouter* pakRouter, - std::map>& out) const { - out.clear(); - for (const AnimationInfo::Animation& ai : animationInfo.animations) - ai.metaAnim.m_anim->gatherPrimitives(out); - for (auto& animRes : out) - animRes.second.additive = animationInfo.additiveMap.at(animRes.first); - } - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - hecl::ProjectPath yamlPath = outPath.getWithExtension(".yaml", true); - hecl::ProjectPath::Type yamlType = yamlPath.getPathType(); - hecl::ProjectPath blendPath = outPath.getWithExtension(".blend", true); - hecl::ProjectPath::Type blendType = blendPath.getPathType(); - - if (force || yamlType == hecl::ProjectPath::Type::None || blendType == hecl::ProjectPath::Type::None) { - CHAR aChar; - aChar.read(rs); - - if (force || yamlType == hecl::ProjectPath::Type::None) { - athena::io::FileWriter writer(yamlPath.getAbsolutePath()); - athena::io::ToYAMLStream(aChar, writer); - } - - if (force || blendType == hecl::ProjectPath::Type::None) { - DNAANCS::ReadANCSToBlender, CHAR, MaterialSet, DNACMDL::SurfaceHeader_3, 4>( - btok, aChar, blendPath, pakRouter, entry, dataSpec, fileChanged, force); - } - } - - return true; - } -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CINF.hpp b/DataSpec/DNAMP3/CINF.hpp deleted file mode 100644 index d40286143..000000000 --- a/DataSpec/DNAMP3/CINF.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNAMP2/CINF.hpp" - -namespace DataSpec::DNAMP3 { -using CINF = DNAMP2::CINF; -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CMDL.cpp b/DataSpec/DNAMP3/CMDL.cpp deleted file mode 100644 index 989bfa5f6..000000000 --- a/DataSpec/DNAMP3/CMDL.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "CMDL.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP3 { - -bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool, hecl::blender::Token& btok, - std::function) { - /* Check for RigPair */ - CINF cinf; - CSKR cskr; - using RigPair = std::pair, std::pair>; - RigPair loadRp = {}; - if (const typename CharacterAssociations::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id)) { - pakRouter.lookupAndReadDNA(rp->cskr, cskr); - pakRouter.lookupAndReadDNA(rp->cinf, cinf); - loadRp.first = {rp->cskr, &cskr}; - loadRp.second = {rp->cinf, &cinf}; - } - - /* Do extract */ - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh)) - return false; - DNACMDL::ReadCMDLToBlender, MaterialSet, RigPair, DNACMDL::SurfaceHeader_3, 5>( - conn, rs, pakRouter, entry, dataSpec, loadRp); - return conn.saveBlend(); -} - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CMDL.hpp b/DataSpec/DNAMP3/CMDL.hpp deleted file mode 100644 index 1650c9ccb..000000000 --- a/DataSpec/DNAMP3/CMDL.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/CMDL.hpp" -#include "CMDLMaterials.hpp" -#include "DNAMP3.hpp" -#include "CINF.hpp" -#include "CSKR.hpp" - -namespace DataSpec::DNAMP3 { - -struct CMDL { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool, hecl::blender::Token& btok, - std::function); -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CMDLMaterials.cpp b/DataSpec/DNAMP3/CMDLMaterials.cpp deleted file mode 100644 index c675f06f6..000000000 --- a/DataSpec/DNAMP3/CMDLMaterials.cpp +++ /dev/null @@ -1,310 +0,0 @@ -#include "CMDLMaterials.hpp" -#include "hecl/Blender/Connection.hpp" - -using Stream = hecl::blender::PyOutStream; - -namespace DataSpec::DNAMP3 { -using Material = MaterialSet::Material; - -template <> -void MaterialSet::Material::Enumerate(typename Read::StreamT& reader) { - header.read(reader); - chunks.clear(); - do { - chunks.emplace_back().read(reader); - } while (!chunks.back().holds_alternative()); - chunks.pop_back(); -} -template <> -void MaterialSet::Material::Enumerate(typename Write::StreamT& writer) { - header.write(writer); - for (const auto& chunk : chunks) - chunk.visit([&](auto& arg) { arg.write(writer); }); - DNAFourCC(FOURCC('END ')).write(writer); -} -template <> -void MaterialSet::Material::Enumerate(typename BinarySize::StreamT& s) { - header.binarySize(s); - for (const auto& chunk : chunks) - chunk.visit([&](auto& arg) { arg.binarySize(s); }); - s += 4; -} - -void MaterialSet::RegisterMaterialProps(Stream& out) { - out << "bpy.types.Material.retro_enable_bloom = bpy.props.BoolProperty(name='Retro: Enable Bloom')\n" - "bpy.types.Material.retro_force_lighting_stage = bpy.props.BoolProperty(name='Retro: Force Lighting Stage')\n" - "bpy.types.Material.retro_pre_inca_transparency = bpy.props.BoolProperty(name='Retro: Pre-INCA " - "Transparency')\n" - "bpy.types.Material.retro_alpha_test = bpy.props.BoolProperty(name='Retro: Alpha Test')\n" - "bpy.types.Material.retro_shadow_occluder = bpy.props.BoolProperty(name='Retro: Shadow Occluder')\n" - "bpy.types.Material.retro_solid_white = bpy.props.BoolProperty(name='Retro: Solid White Only')\n" - "bpy.types.Material.retro_reflection_alpha_target = bpy.props.BoolProperty(name='Retro: Reflection Alpha " - "Target')\n" - "bpy.types.Material.retro_solid_color = bpy.props.BoolProperty(name='Retro: Solid Color Only')\n" - "bpy.types.Material.retro_exclude_scan = bpy.props.BoolProperty(name='Retro: Exclude From Scan Visor')\n" - "bpy.types.Material.retro_xray_opaque = bpy.props.BoolProperty(name='Retro: XRay Opaque')\n" - "bpy.types.Material.retro_xray_alpha_target = bpy.props.BoolProperty(name='Retro: XRay Alpha Target')\n" - "bpy.types.Material.retro_inca_color_mod = bpy.props.BoolProperty(name='Retro: INCA Color Mod')\n" - "\n"; -} - -static void LoadTexture(Stream& out, const UniqueID64& tex, const PAKRouter& pakRouter, - const PAK::Entry& entry) { - if (!tex.isValid()) { - out << "image = None\n"; - return; - } - std::string texName = pakRouter.getBestEntryName(tex); - const nod::Node* node; - const typename PAKRouter::EntryType* texEntry = pakRouter.lookupEntry(tex, &node); - hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry); - if (!txtrPath.isNone()) { - txtrPath.makeDirChain(false); - PAKEntryReadStream rs = texEntry->beginReadStream(*node); - TXTR::Extract(rs, txtrPath); - } - std::string resPath = pakRouter.getResourceRelativePath(entry, tex); - out.format(FMT_STRING("if '{}' in bpy.data.images:\n" - " image = bpy.data.images['{}']\n" - "else:\n" - " image = bpy.data.images.load('''//{}''')\n" - " image.name = '{}'\n" - "\n"), - texName, texName, resPath, texName); -} - -void MaterialSet::ConstructMaterial(Stream& out, const PAKRouter& pakRouter, const PAK::Entry& entry, - const Material& material, unsigned groupIdx, unsigned matIdx) { - out.format(FMT_STRING("new_material = bpy.data.materials.new('MAT_{}_{}')\n"), groupIdx, matIdx); - out << "new_material.use_fake_user = True\n" - "new_material.use_nodes = True\n" - "new_material.use_backface_culling = True\n" - "new_material.show_transparent_back = False\n" - "new_material.blend_method = 'BLEND'\n" - "new_nodetree = new_material.node_tree\n" - "for n in new_nodetree.nodes:\n" - " new_nodetree.nodes.remove(n)\n" - "\n" - "gridder = hecl.Nodegrid(new_nodetree)\n" - "new_nodetree.nodes.remove(gridder.frames[2])\n" - "\n" - "texture_nodes = []\n" - "kcolors = {}\n" - "kalphas = {}\n" - "tex_links = []\n" - "\n"; - - /* Material Flags */ - out.format(FMT_STRING("new_material.retro_enable_bloom = {}\n" - "new_material.retro_force_lighting_stage = {}\n" - "new_material.retro_pre_inca_transparency = {}\n" - "new_material.retro_alpha_test = {}\n" - "new_material.retro_shadow_occluder = {}\n" - "new_material.retro_solid_white = {}\n" - "new_material.retro_reflection_alpha_target = {}\n" - "new_material.retro_solid_color = {}\n" - "new_material.retro_exclude_scan = {}\n" - "new_material.retro_xray_opaque = {}\n" - "new_material.retro_xray_alpha_target = {}\n" - "new_material.retro_inca_color_mod = False\n"), - material.header.flags.enableBloom() ? "True" : "False", - material.header.flags.forceLightingStage() ? "True" : "False", - material.header.flags.preIncaTransparency() ? "True" : "False", - material.header.flags.alphaTest() ? "True" : "False", - material.header.flags.shadowOccluderMesh() ? "True" : "False", - material.header.flags.justWhite() ? "True" : "False", - material.header.flags.reflectionAlphaTarget() ? "True" : "False", - material.header.flags.justSolidColor() ? "True" : "False", - material.header.flags.excludeFromScanVisor() ? "True" : "False", - material.header.flags.xrayOpaque() ? "True" : "False", - material.header.flags.xrayAlphaTarget() ? "True" : "False"); - - out << "pnode = new_nodetree.nodes.new('ShaderNodeGroup')\n" - "pnode.name = 'Output'\n" - "pnode.node_tree = bpy.data.node_groups['RetroShaderMP3']\n" - "gridder.place_node(pnode, 1)\n"; - - if (material.header.flags.additiveIncandecence()) - out << "pnode.inputs['Add INCA'].default_value = 1\n"; - - int texMtxIdx = 0; - for (const auto& chunk : material.chunks) { - if (const Material::PASS* pass = chunk.get_if()) { - LoadTexture(out, pass->txtrId, pakRouter, entry); - out << "# Texture\n" - "tex_node = new_nodetree.nodes.new('ShaderNodeTexImage')\n" - "texture_nodes.append(tex_node)\n" - "tex_node.image = image\n"; - - if (!pass->uvAnim.empty()) { - const auto& uva = pass->uvAnim[0]; - switch (uva.uvSource) { - case Material::UVAnimationUVSource::Position: - default: - out << "tex_uv_node = new_nodetree.nodes.new('ShaderNodeTexCoord')\n" - "tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['Window'], tex_node.inputs['Vector']))\n"; - break; - case Material::UVAnimationUVSource::Normal: - out << "tex_uv_node = new_nodetree.nodes.new('ShaderNodeTexCoord')\n" - "tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['Normal'], tex_node.inputs['Vector']))\n"; - break; - case Material::UVAnimationUVSource::UV: - out.format( - FMT_STRING( - "tex_uv_node = new_nodetree.nodes.new('ShaderNodeUVMap')\n" - "tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['UV'], tex_node.inputs['Vector']))\n" - "tex_uv_node.uv_map = 'UV_{}'\n"), - pass->uvSrc); - break; - } - out.format(FMT_STRING("tex_uv_node.label = 'MTX_{}'\n"), texMtxIdx); - } else { - out.format( - FMT_STRING( - "tex_uv_node = new_nodetree.nodes.new('ShaderNodeUVMap')\n" - "tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['UV'], tex_node.inputs['Vector']))\n" - "tex_uv_node.uv_map = 'UV_{}'\n"), - pass->uvSrc); - } - - out << "gridder.place_node(tex_uv_node, 0)\n" - "gridder.place_node(tex_node, 0)\n" - "tex_uv_node.location[0] -= 120\n" - "tex_node.location[0] += 120\n" - "tex_node.location[1] += 176\n" - "\n"; - - if (!pass->uvAnim.empty()) { - const auto& uva = pass->uvAnim[0]; - DNAMP1::MaterialSet::Material::AddTextureAnim(out, uva.anim.mode, texMtxIdx++, uva.anim.vals); - } - - auto DoSwap = [&]() { - if (pass->flags.swapColorComponent() == Material::SwapColorComponent::Alpha) { - out << "swap_output = tex_node.outputs['Alpha']\n"; - } else { - out << "separate_node = new_nodetree.nodes.new('ShaderNodeSeparateRGB')\n" - "gridder.place_node(separate_node, 0, False)\n" - "separate_node.location[0] += 350\n" - "separate_node.location[1] += 350\n" - "new_nodetree.links.new(tex_node.outputs['Color'], separate_node.inputs[0])\n"; - out.format(FMT_STRING("swap_output = separate_node.outputs[{}]\n"), int(pass->flags.swapColorComponent())); - } - }; - - using Subtype = Material::PASS::Subtype; - switch (Subtype(pass->subtype.toUint32())) { - case Subtype::DIFF: - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['DIFFC'])\n" - "new_nodetree.links.new(tex_node.outputs['Alpha'], pnode.inputs['DIFFA'])\n"; - break; - case Subtype::BLOL: - DoSwap(); - out << "new_nodetree.links.new(swap_output, pnode.inputs['BLOL'])\n"; - break; - case Subtype::BLOD: - DoSwap(); - out << "new_nodetree.links.new(swap_output, pnode.inputs['BLOD'])\n"; - break; - case Subtype::CLR: - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['CLR'])\n" - "new_nodetree.links.new(tex_node.outputs['Alpha'], pnode.inputs['CLRA'])\n"; - break; - case Subtype::TRAN: - DoSwap(); - if (pass->flags.TRANInvert()) - out << "invert_node = new_nodetree.nodes.new('ShaderNodeInvert')\n" - "gridder.place_node(invert_node, 0, False)\n" - "invert_node.location[0] += 400\n" - "invert_node.location[1] += 350\n" - "new_nodetree.links.new(swap_output, invert_node.inputs['Color'])\n" - "swap_output = invert_node.outputs['Color']\n"; - out << "new_nodetree.links.new(swap_output, pnode.inputs['TRAN'])\n"; - break; - case Subtype::INCA: - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['INCAC'])\n"; - if (pass->flags.alphaContribution()) { - DoSwap(); - out << "new_nodetree.links.new(swap_output, pnode.inputs['INCAA'])\n"; - } - out.format(FMT_STRING("new_material.retro_inca_color_mod = {}\n"), - pass->flags.INCAColorMod() ? "True" : "False"); - break; - case Subtype::RFLV: - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['RFLV'])\n"; - break; - case Subtype::RFLD: - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['RFLD'])\n" - "new_nodetree.links.new(tex_node.outputs['Alpha'], pnode.inputs['RFLDA'])\n"; - break; - case Subtype::LRLD: - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['LRLD'])\n"; - break; - case Subtype::LURD: - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['LURDC'])\n" - "new_nodetree.links.new(tex_node.outputs['Alpha'], pnode.inputs['LURDA'])\n"; - break; - case Subtype::BLOI: - DoSwap(); - out << "new_nodetree.links.new(swap_output, pnode.inputs['BLOI'])\n"; - break; - case Subtype::XRAY: - DoSwap(); - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['XRAYC'])\n" - "new_nodetree.links.new(swap_output, pnode.inputs['XRAYA'])\n"; - break; - default: - Log.report(logvisor::Fatal, FMT_STRING("Unknown PASS subtype")); - break; - } - } else if (const Material::CLR* clr = chunk.get_if()) { - using Subtype = Material::CLR::Subtype; - athena::simd_floats vec4; - clr->color.toVec4f().simd.copy_to(vec4); - switch (Subtype(clr->subtype.toUint32())) { - case Subtype::CLR: - out.format(FMT_STRING("pnode.inputs['CLR'].default_value = ({}, {}, {}, 1.0)\n" - "pnode.inputs['CLRA'].default_value = {}\n"), - vec4[0], vec4[1], vec4[2], vec4[3]); - break; - case Subtype::DIFB: - out.format(FMT_STRING("pnode.inputs['DIFBC'].default_value = ({}, {}, {}, 1.0)\n" - "pnode.inputs['DIFBA'].default_value = {}\n"), - vec4[0], vec4[1], vec4[2], vec4[3]); - break; - default: - Log.report(logvisor::Fatal, FMT_STRING("Unknown CLR subtype")); - break; - } - } else if (const Material::INT* val = chunk.get_if()) { - using Subtype = Material::INT::Subtype; - switch (Subtype(val->subtype.toUint32())) { - case Subtype::OPAC: - out.format(FMT_STRING("pnode.inputs['OPAC'].default_value = {}\n"), val->value / 255.f); - break; - case Subtype::BLOD: - out.format(FMT_STRING("pnode.inputs['BLOD'].default_value = {}\n"), val->value / 255.f); - break; - case Subtype::BLOI: - out.format(FMT_STRING("pnode.inputs['BLOI'].default_value = {}\n"), val->value / 255.f); - break; - case Subtype::BNIF: - out.format(FMT_STRING("pnode.inputs['BNIF'].default_value = {}\n"), val->value / 255.f); - break; - case Subtype::XRBR: - out.format(FMT_STRING("pnode.inputs['XRBR'].default_value = {}\n"), val->value / 255.f); - break; - default: - Log.report(logvisor::Fatal, FMT_STRING("Unknown INT subtype")); - break; - } - } - } -} - -} // namespace DataSpec::DNAMP3 - -AT_SPECIALIZE_TYPED_VARIANT_BIGDNA(DataSpec::DNAMP3::MaterialSet::Material::PASS, - DataSpec::DNAMP3::MaterialSet::Material::CLR, - DataSpec::DNAMP3::MaterialSet::Material::INT, - DataSpec::DNAMP3::MaterialSet::Material::END) diff --git a/DataSpec/DNAMP3/CMDLMaterials.hpp b/DataSpec/DNAMP3/CMDLMaterials.hpp deleted file mode 100644 index f933974a7..000000000 --- a/DataSpec/DNAMP3/CMDLMaterials.hpp +++ /dev/null @@ -1,202 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/GX.hpp" -#include "../DNAMP1/CMDLMaterials.hpp" -#include "DNAMP3.hpp" - -namespace DataSpec::DNAMP3 { - -struct MaterialSet : BigDNA { - static constexpr bool OneSection() { return true; } - - AT_DECL_DNA - Value materialCount; - - /* Dummy methods from MP1/2 */ - void addTexture(const UniqueID32&) {} - void addMaterialEndOff(atUint32) { ++materialCount; } - - struct Material : BigDNA { - enum class SwapColorComponent { Red, Green, Blue, Alpha }; - enum class UVAnimationUVSource : atUint16 { Position, Normal, UV }; - enum class UVAnimationMatrixConfig : atUint16 { NoMtxNoPost, MtxNoPost, NoMtxPost, MtxPost }; - - AT_DECL_EXPLICIT_DNA - using VAFlags = DNAMP1::MaterialSet::Material::VAFlags; - struct Header : BigDNA { - AT_DECL_DNA - Value size; - struct Flags : BigDNA { - AT_DECL_DNA - Value flags; - bool enableBloom() const { return (flags & 0x1) != 0; } - void setEnableBloom(bool enabled) { - flags &= ~0x1; - flags |= atUint32(enabled) << 0; - } - bool forceLightingStage() const { return (flags & 0x4) != 0; } - void setForceLightingStage(bool enabled) { - flags &= ~0x4; - flags |= atUint32(enabled) << 2; - } - bool preIncaTransparency() const { return (flags & 0x8) != 0; } - void setPreIncaTransparency(bool enabled) { - flags &= ~0x8; - flags |= atUint32(enabled) << 3; - } - bool alphaTest() const { return (flags & 0x10) != 0; } - void setPunchthroughAlpha(bool enabled) { - flags &= ~0x10; - flags |= atUint32(enabled) << 4; - } - bool additiveIncandecence() const { return (flags & 0x20) != 0; } - void setAdditiveIncandecence(bool enabled) { - flags &= ~0x20; - flags |= atUint32(enabled) << 5; - } - bool shadowOccluderMesh() const { return (flags & 0x100) != 0; } - void setShadowOccluderMesh(bool enabled) { - flags &= ~0x100; - flags |= atUint32(enabled) << 8; - } - bool justWhite() const { return (flags & 0x200) != 0; } - void setJustWhite(bool enabled) { - flags &= ~0x200; - flags |= atUint32(enabled) << 9; - } - bool reflectionAlphaTarget() const { return (flags & 0x400) != 0; } - void setReflectionAlphaTarget(bool enabled) { - flags &= ~0x400; - flags |= atUint32(enabled) << 10; - } - bool justSolidColor() const { return (flags & 0x800) != 0; } - void setJustSolidColor(bool enabled) { - flags &= ~0x800; - flags |= atUint32(enabled) << 11; - } - bool excludeFromScanVisor() const { return (flags & 0x4000) != 0; } - void setExcludeFromScanVisor(bool enabled) { - flags &= ~0x4000; - flags |= atUint32(enabled) << 14; - } - bool xrayOpaque() const { return (flags & 0x8000) != 0; } - void setXRayOpaque(bool enabled) { - flags &= ~0x8000; - flags |= atUint32(enabled) << 15; - } - bool xrayAlphaTarget() const { return (flags & 0x10000) != 0; } - void setXRayAlphaTarget(bool enabled) { - flags &= ~0x10000; - flags |= atUint32(enabled) << 16; - } - bool lightmapUVArray() const { return false; } /* For polymorphic compatibility with MP1/2 */ - } flags; - Value uniqueIdx; - Value unk1; - VAFlags vaFlags; - Value unk2; - Value unk3; - Value unk4; - } header; - const Header::Flags& getFlags() const { return header.flags; } - const VAFlags& getVAFlags() const { return header.vaFlags; } - - enum class ChunkType : atUint32 { PASS = 'PASS', CLR = 'CLR ', INT = 'INT ', END = 'END ' }; - - struct PASS : hecl::TypedRecordBigDNA { - AT_DECL_DNA - Value size; - enum class Subtype : atUint32 { - DIFF = SBIG('DIFF'), - RIML = SBIG('RIML'), - BLOL = SBIG('BLOL'), - BLOD = SBIG('BLOD'), - CLR = SBIG('CLR '), - TRAN = SBIG('TRAN'), - INCA = SBIG('INCA'), - RFLV = SBIG('RFLV'), - RFLD = SBIG('RFLD'), - LRLD = SBIG('LRLD'), - LURD = SBIG('LURD'), - BLOI = SBIG('BLOI'), - XRAY = SBIG('XRAY'), - TOON = SBIG('TOON') - }; - DNAFourCC subtype; - struct Flags : BigDNA { - AT_DECL_DNA - Value flags; - SwapColorComponent swapColorComponent() const { return SwapColorComponent(flags & 0x3); } - void setSwapColorComponent(SwapColorComponent comp) { - flags &= ~0x3; - flags |= atUint32(comp) << 0; - } - bool alphaContribution() const { return (flags & 0x4) != 0; } - void setAlphaContribution(bool enabled) { - flags &= ~0x4; - flags |= atUint32(enabled) << 2; - } - bool INCAColorMod() const { return (flags & 0x8) != 0; } - void setINCAColorMod(bool enabled) { - flags &= ~0x8; - flags |= atUint32(enabled) << 3; - } - bool TRANInvert() const { return (flags & 0x10) != 0; } - void setTRANInvert(bool enabled) { - flags &= ~0x10; - flags |= atUint32(enabled) << 4; - } - } flags; - UniqueID64 txtrId; - Value uvSrc; - Value uvAnimSize; - struct UVAnimation : BigDNA { - AT_DECL_DNA - Value uvSource; - Value mtxConfig; - DNAMP1::MaterialSet::Material::UVAnimation anim; - }; - Vector uvAnim; - }; - struct CLR : hecl::TypedRecordBigDNA { - AT_DECL_DNA - enum class Subtype : atUint32 { CLR = SBIG('CLR '), DIFB = SBIG('DIFB') }; - DNAFourCC subtype; - GX::Color color; - CLR() = default; - }; - struct INT : hecl::TypedRecordBigDNA { - AT_DECL_DNA - enum class Subtype : atUint32 { - OPAC = SBIG('OPAC'), - BLOD = SBIG('BLOD'), - BLOI = SBIG('BLOI'), - BNIF = SBIG('BNIF'), - XRBR = SBIG('XRBR') - }; - DNAFourCC subtype; - Value value; - }; - struct END : hecl::TypedRecordBigDNA { - AT_DECL_DNA - }; - using Chunk = hecl::TypedVariantBigDNA; - std::vector chunks; - }; - Vector materials; - - static void RegisterMaterialProps(hecl::blender::PyOutStream& out); - static void ConstructMaterial(hecl::blender::PyOutStream& out, const PAKRouter& pakRouter, - const PAK::Entry& entry, const MaterialSet::Material& material, unsigned groupIdx, - unsigned matIdx); - - void readToBlender(hecl::blender::PyOutStream& os, const PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, unsigned setIdx) { - DNACMDL::ReadMaterialSetToBlender_3(os, *this, pakRouter, entry, setIdx); - } - - void ensureTexturesExtracted(PAKRouter& pakRouter) const {} -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CMakeLists.txt b/DataSpec/DNAMP3/CMakeLists.txt deleted file mode 100644 index 68a9cf943..000000000 --- a/DataSpec/DNAMP3/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -make_dnalist(PAK - MLVL - ANIM - CHAR - CMDLMaterials - CINF - CSKR - MREA - SAVW - CAUD - HINT - SAND) -set(DNAMP3_SOURCES - DNAMP3.hpp DNAMP3.cpp - PAK.cpp - ANIM.cpp - CINF.hpp - CHAR.cpp - CMDL.hpp CMDL.cpp - CMDLMaterials.cpp - CSKR.cpp - PATH.hpp - STRG.hpp STRG.cpp - MAPA.hpp - MREA.cpp) - -dataspec_add_list(DNAMP3 DNAMP3_SOURCES) diff --git a/DataSpec/DNAMP3/CSKR.cpp b/DataSpec/DNAMP3/CSKR.cpp deleted file mode 100644 index 11711dd5d..000000000 --- a/DataSpec/DNAMP3/CSKR.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "CSKR.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP3 { - -void CSKR::weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atInt16 skinIdx) const { - if (skinIdx < 0) - return; - const DNAMP2::CSKR::SkinningRule& rule = data.skinningRules[skinIdx]; - for (const DNAMP2::CSKR::SkinningRule::Weight& weight : rule.weights) - os.format(FMT_STRING("vert[dvert_lay][{}] = {}\n"), cinf.getBoneIdxFromId(weight.boneId), weight.weight); -} - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CSKR.hpp b/DataSpec/DNAMP3/CSKR.hpp deleted file mode 100644 index 2de889e0c..000000000 --- a/DataSpec/DNAMP3/CSKR.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "CINF.hpp" -#include "../DNAMP2/CSKR.hpp" - -namespace DataSpec::DNAMP3 { - -struct CSKR : BigDNA { - AT_DECL_DNA - DNAFourCC magic; - Value version; - DNAMP2::CSKR data; - Value matrixCount; - struct MatrixBindings : BigDNA { - AT_DECL_DNA - Value mtxs[10]; - }; - Vector mtxBindings; - - Value unkCount1; - Vector unk1; - Value unkCount2; - Vector unk2; - Value unkCount3; - Vector unk3; - Value unkCount4; - Vector unk4; - Value unkCount5; - Vector unk5; - - const atInt16* getMatrixBank(size_t idx) const { return mtxBindings.at(idx).mtxs; } - - void weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atInt16 skinIdx) const; -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/DNAMP3.cpp b/DataSpec/DNAMP3/DNAMP3.cpp deleted file mode 100644 index dc98b26e6..000000000 --- a/DataSpec/DNAMP3/DNAMP3.cpp +++ /dev/null @@ -1,273 +0,0 @@ -#include - -#define NOD_ATHENA 1 -#include "DNAMP3.hpp" -#include "STRG.hpp" -#include "MLVL.hpp" -#include "CAUD.hpp" -#include "CMDL.hpp" -#include "CHAR.hpp" -#include "MREA.hpp" -#include "MAPA.hpp" -#include "PATH.hpp" -#include "SAVW.hpp" -#include "HINT.hpp" -#include "DataSpec/DNACommon/TXTR.hpp" -#include "DataSpec/DNACommon/FONT.hpp" -#include "DataSpec/DNACommon/FSM2.hpp" -#include "DataSpec/DNACommon/DGRP.hpp" -#include "Runtime/GCNTypes.hpp" - -namespace DataSpec::DNAMP3 { -logvisor::Module Log("DataSpec::DNAMP3"); - -static bool GetNoShare(std::string_view name) { - std::string lowerName(name); - std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower); - return !lowerName.starts_with("metroid"sv) && !lowerName.starts_with("frontend"sv) && - !lowerName.starts_with("rs5fe"sv) && !lowerName.starts_with("universearea"sv) && - !lowerName.starts_with("mp1fe"sv); -} - -PAKBridge::PAKBridge(const nod::Node& node, bool doExtract) -: m_node(node), m_pak(GetNoShare(node.getName())), m_doExtract(doExtract) { - nod::AthenaPartReadStream rs(node.beginReadStream()); - m_pak.read(rs); - - /* Append Level String */ - std::set uniq; - for (auto& ent : m_pak.m_entries) { - PAK::Entry& entry = ent.second; - if (entry.type == FOURCC('MLVL')) { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - MLVL mlvl; - mlvl.read(rs); - const PAK::Entry* nameEnt = m_pak.lookupEntry(mlvl.worldNameId); - if (nameEnt) { - PAKEntryReadStream rs = nameEnt->beginReadStream(m_node); - STRG mlvlName; - mlvlName.read(rs); - uniq.insert(mlvlName.getUTF8(FOURCC('ENGL'), 0)); - } - } - } - bool comma = false; - for (const std::string& str : uniq) { - if (comma) - m_levelString += ", "; - comma = true; - m_levelString += str; - } -} - -static std::string LayerName(std::string_view name) { - std::string ret(name); - for (auto& ch : ret) - if (ch == '/' || ch == '\\') - ch = '-'; - return ret; -} - -void PAKBridge::build() { - /* First pass: build per-area/per-layer dependency map */ - for (const auto& ent : m_pak.m_entries) { - const PAK::Entry& entry = ent.second; - if (entry.type == FOURCC('MLVL')) { - Level& level = m_levelDeps[entry.id]; - - MLVL mlvl; - { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - mlvl.read(rs); - } - std::string catalogueName; - std::string bestName = m_pak.bestEntryName(m_node, entry, catalogueName); - level.name = bestName; - level.areas.reserve(mlvl.areaCount); - unsigned layerIdx = 0; - - /* Make MAPW available to lookup MAPAs */ - const PAK::Entry* worldMapEnt = m_pak.lookupEntry(mlvl.worldMap); - std::vector mapw; - if (worldMapEnt) { - PAKEntryReadStream rs = worldMapEnt->beginReadStream(m_node); - rs.seek(8, athena::SeekOrigin::Current); - atUint32 areaCount = rs.readUint32Big(); - mapw.reserve(areaCount); - for (atUint32 i = 0; i < areaCount; ++i) - mapw.emplace_back(rs); - } - - /* Index areas */ - unsigned ai = 0; - auto layerFlagsIt = mlvl.layerFlags.begin(); - for (const MLVL::Area& area : mlvl.areas) { - Level::Area& areaDeps = level.areas[area.areaMREAId]; - const PAK::Entry* areaNameEnt = m_pak.lookupEntry(area.areaNameId); - if (areaNameEnt) { - STRG areaName; - { - PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node); - areaName.read(rs); - } - areaDeps.name = areaName.getUTF8(FOURCC('ENGL'), 0); - areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name); - } - if (areaDeps.name.empty()) { - areaDeps.name = area.internalAreaName; - if (areaDeps.name.empty()) { - areaDeps.name = "MREA_" + area.areaMREAId.toString(); - } - } - std::string num = fmt::format(FMT_STRING("{:02d} "), ai); - areaDeps.name = num + areaDeps.name; - - const MLVL::LayerFlags& layerFlags = *layerFlagsIt++; - if (layerFlags.layerCount) { - areaDeps.layers.reserve(layerFlags.layerCount); - for (unsigned l = 1; l < layerFlags.layerCount; ++l) { - areaDeps.layers.emplace_back(); - Level::Area::Layer& layer = areaDeps.layers.back(); - layer.name = LayerName(mlvl.layerNames[layerIdx++]); - layer.active = layerFlags.flags >> (l - 1) & 0x1; - layer.name = hecl::StringUtils::TrimWhitespace(layer.name); - num = fmt::format(FMT_STRING("{:02d} "), l - 1); - layer.name = num + layer.name; - } - } - - /* Load area DEPS */ - const PAK::Entry* areaEntry = m_pak.lookupEntry(area.areaMREAId); - if (areaEntry) { - PAKEntryReadStream ars = areaEntry->beginReadStream(m_node); - MREA::ExtractLayerDeps(ars, areaDeps); - } - areaDeps.resources.emplace(area.areaMREAId); - if (mapw.size() > ai) - areaDeps.resources.emplace(mapw[ai]); - ++ai; - } - } - } - - /* Second pass: cross-compare uniqueness */ - for (auto& entry : m_pak.m_entries) { - entry.second.unique.checkEntry(*this, entry.second); - } -} - -void PAKBridge::addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const { - for (const auto& entry : m_pak.m_entries) { - if (entry.second.type == FOURCC('CHAR')) { - PAKEntryReadStream rs = entry.second.beginReadStream(m_node); - CHAR aChar; - aChar.read(rs); - const CHAR::CharacterInfo& ci = aChar.characterInfo; - charAssoc.m_cmdlRigs[ci.cmdl] = {ci.cskr, ci.cinf}; - charAssoc.m_cskrToCharacter[ci.cskr] = - std::make_pair(entry.second.id, fmt::format(FMT_STRING("{}_{}.CSKR"), ci.name, ci.cskr)); - for (const CHAR::CharacterInfo::Overlay& overlay : ci.overlays) { - charAssoc.m_cmdlRigs[overlay.cmdl] = {overlay.cskr, ci.cinf}; - charAssoc.m_cskrToCharacter[overlay.cskr] = std::make_pair( - entry.second.id, fmt::format(FMT_STRING("{}.{}_{}.CSKR"), ci.name, overlay.type, overlay.cskr)); - } - } - } -} - -static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}}; - -void PAKBridge::addMAPATransforms(PAKRouter& pakRouter, - std::unordered_map& addTo, - std::unordered_map& pathOverrides) const { - for (const auto& entry : m_pak.m_entries) { - if (entry.second.type == FOURCC('MLVL')) { - MLVL mlvl; - { - PAKEntryReadStream rs = entry.second.beginReadStream(m_node); - mlvl.read(rs); - } - hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath(); - - if (mlvl.worldNameId.isValid()) - pathOverrides[mlvl.worldNameId] = - hecl::ProjectPath(mlvlDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), mlvl.worldNameId)); - - for (const MLVL::Area& area : mlvl.areas) { - { - /* Get PATH transform */ - const nod::Node* areaNode; - const PAK::Entry* areaEntry = pakRouter.lookupEntry(area.areaMREAId, &areaNode); - PAKEntryReadStream rs = areaEntry->beginReadStream(*areaNode); - UniqueID64 pathId = MREA::GetPATHId(rs); - if (pathId.isValid()) - addTo[pathId] = zeus::CMatrix4f(area.transformMtx[0], area.transformMtx[1], area.transformMtx[2], BottomRow) - .transposed(); - } - hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath(); - if (area.areaNameId.isValid()) - pathOverrides[area.areaNameId] = - hecl::ProjectPath(areaDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), area.areaNameId)); - } - - if (mlvl.worldMap.isValid()) { - const nod::Node* mapNode; - const PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode); - if (mapEntry) { - PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode); - u32 magic = rs.readUint32Big(); - if (magic == 0xDEADF00D) { - rs.readUint32Big(); - u32 count = rs.readUint32Big(); - for (u32 i = 0; i < count && i < mlvl.areas.size(); ++i) { - MLVL::Area& areaData = mlvl.areas[i]; - UniqueID64 mapaId; - mapaId.read(rs); - addTo[mapaId] = zeus::CMatrix4f(areaData.transformMtx[0], areaData.transformMtx[1], - areaData.transformMtx[2], BottomRow) - .transposed(); - } - } - } - } - } - } -} - -ResExtractor PAKBridge::LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry) { - switch (entry.type.toUint32()) { - case SBIG('CAUD'): - return {CAUD::Extract, {".yaml"}}; - case SBIG('STRG'): - return {STRG::Extract, {".yaml"}}; - case SBIG('TXTR'): - return {TXTR::Extract, {".png"}}; - case SBIG('SAVW'): - return {SAVWCommon::ExtractSAVW, {".yaml"}}; - case SBIG('HINT'): - return {HINT::Extract, {".yaml"}}; - case SBIG('CMDL'): - return {CMDL::Extract, {".blend"}, 1}; - case SBIG('CINF'): - return {CINF::Extract, {".blend"}, 1}; - case SBIG('CHAR'): - return {CHAR::Extract, {".yaml", ".blend"}, 2}; - case SBIG('MLVL'): - return {MLVL::Extract, {".yaml", ".blend"}, 3}; - case SBIG('MREA'): - return {MREA::Extract, {".blend"}, 4}; - case SBIG('MAPA'): - return {MAPA::Extract, {".blend"}, 4}; - case SBIG('PATH'): - return {PATH::Extract, {".blend"}, 5}; - case SBIG('FSM2'): - return {DNAFSM2::ExtractFSM2, {".yaml"}}; - case SBIG('FONT'): - return {DNAFont::ExtractFONT, {".yaml"}}; - case SBIG('DGRP'): - return {DNADGRP::ExtractDGRP, {".yaml"}}; - } - return {}; -} - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/DNAMP3.hpp b/DataSpec/DNAMP3/DNAMP3.hpp deleted file mode 100644 index 4c399d33f..000000000 --- a/DataSpec/DNAMP3/DNAMP3.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "PAK.hpp" - -namespace DataSpec::DNAMP3 { - -extern logvisor::Module Log; - -/* MP3-specific, one-shot PAK traversal/extraction class */ -class PAKBridge { - const nod::Node& m_node; - PAK m_pak; - -public: - bool m_doExtract; - using Level = DataSpec::Level; - std::unordered_map m_levelDeps; - std::string m_levelString; - - PAKBridge(const nod::Node& node, bool doExtract = true); - void build(); - static ResExtractor LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry); - std::string_view getName() const { return m_node.getName(); } - std::string_view getLevelString() const { return m_levelString; } - - using PAKType = PAK; - const PAKType& getPAK() const { return m_pak; } - const nod::Node& getNode() const { return m_node; } - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const; - - void addMAPATransforms(PAKRouter& pakRouter, std::unordered_map& addTo, - std::unordered_map& pathOverrides) const; -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/HINT.hpp b/DataSpec/DNAMP3/HINT.hpp deleted file mode 100644 index 7885f9f00..000000000 --- a/DataSpec/DNAMP3/HINT.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "PAK.hpp" - -namespace DataSpec::DNAMP3 { -struct HINT : BigDNA { - AT_DECL_DNA_YAML - Value magic; - Value version; - - struct Hint : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknown1; - Value fadeInTime; - UniqueID64 stringID; - Value unknown2; - struct Location : BigDNA { - AT_DECL_DNA_YAML - UniqueID64 worldAssetID; - UniqueID64 areaAssetID; - Value areaID; - UniqueID64 stringID; - Value unknown[3]; - }; - - Value locationCount; - Vector locations; - }; - Value hintCount; - Vector hints; - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - HINT hint; - hint.read(rs); - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(hint, writer); - return true; - } -}; -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/MAPA.hpp b/DataSpec/DNAMP3/MAPA.hpp deleted file mode 100644 index 5a7ab9b48..000000000 --- a/DataSpec/DNAMP3/MAPA.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MAPA.hpp" -#include "DNAMP3.hpp" - -namespace DataSpec::DNAMP3 { -struct MAPA : DNAMAPA::MAPA { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - MAPA mapa; - mapa.read(rs); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); - } - - static bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out) { - return DNAMAPA::Cook(mapa, out); - } - - static uint32_t Version() { return 5; } - using Header = DNAMAPA::MAPA::HeaderMP3; - using MappableObject = DNAMAPA::MAPA::MappableObjectMP3; -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/MLVL.hpp b/DataSpec/DNAMP3/MLVL.hpp deleted file mode 100644 index ba3f56aee..000000000 --- a/DataSpec/DNAMP3/MLVL.hpp +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MLVL.hpp" -#include "DNAMP3.hpp" - -namespace DataSpec::DNAMP3 { - -struct MLVL : BigDNA { - AT_DECL_DNA_YAML - Value magic; - Value version; - UniqueID64 worldNameId; - Value unk; - UniqueID64 saveWorldId; - UniqueID64 worldSkyboxId; - - Value areaCount; - struct Area : BigDNA { - AT_DECL_DNA_YAML - UniqueID64 areaNameId; - Value transformMtx[3]; - Value aabb[2]; - UniqueID64 areaMREAId; - Value areaId; - - Value attachedAreaCount; - Vector attachedAreas; - - Value dockCount; - struct Dock : BigDNA { - AT_DECL_DNA_YAML - Value endpointCount; - struct Endpoint : BigDNA { - AT_DECL_DNA_YAML - Value areaIdx; - Value dockIdx; - }; - Vector endpoints; - - Value planeVertCount; - Vector planeVerts; - }; - Vector docks; - - String<-1> internalAreaName; - }; - Vector areas; - - UniqueID64 worldMap; - Value unknown2; - Value unknown3; - - Value layerFlagCount; - struct LayerFlags : BigDNA { - AT_DECL_DNA_YAML - Value layerCount; - Value flags; - }; - Vector layerFlags; - - Value layerNameCount; - Vector, AT_DNA_COUNT(layerNameCount)> layerNames; - - Value layerIDCount; - struct LayerID : BigDNA { - AT_DECL_DNA_YAML - Value id[2]; - }; - Vector layerIDs; - - Value layerNameOffsetCount; - Vector layerNameOffsets; - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - MLVL mlvl; - mlvl.read(rs); - athena::io::FileWriter writer(outPath.getWithExtension(".yaml", true).getAbsolutePath()); - athena::io::ToYAMLStream(mlvl, writer); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged); - } -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/MREA.cpp b/DataSpec/DNAMP3/MREA.cpp deleted file mode 100644 index 45f5de33a..000000000 --- a/DataSpec/DNAMP3/MREA.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#include -#include "MREA.hpp" -#include "../DNAMP2/DeafBabe.hpp" -#include "DataSpec/DNACommon/BabeDead.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec { -extern hecl::Database::DataSpecEntry SpecEntMP3ORIG; - -namespace DNAMP3 { - -MREA::StreamReader::StreamReader(athena::io::IStreamReader& source, atUint32 blkCount, atUint32 secIdxCount) -: DNAMP2::MREA::StreamReader(source) { - m_blkCount = blkCount; - m_blockInfos.reserve(blkCount); - for (atUint32 i = 0; i < blkCount; ++i) { - BlockInfo& info = m_blockInfos.emplace_back(); - info.read(source); - m_totalDecompLen += info.decompSize; - } - source.seekAlign32(); - m_secIdxs.reserve(secIdxCount); - for (atUint32 i = 0; i < secIdxCount; ++i) { - std::pair& idx = m_secIdxs.emplace_back(); - idx.first.read(source); - idx.second = source.readUint32Big(); - } - source.seekAlign32(); - m_blkBase = source.position(); - nextBlock(); -} - -void MREA::StreamReader::writeSecIdxs(athena::io::IStreamWriter& writer) const { - for (const std::pair& idx : m_secIdxs) { - idx.first.write(writer); - writer.writeUint32Big(idx.second); - } -} - -bool MREA::StreamReader::seekToSection(FourCC sec, const std::vector& secSizes) { - auto search = std::find_if(m_secIdxs.begin(), m_secIdxs.end(), [sec](const auto& s) { return s.first == sec; }); - if (search != m_secIdxs.end()) { - DNAMP2::MREA::StreamReader::seekToSection(search->second, secSizes); - return true; - } - return false; -} - -void MREA::ReadBabeDeadToBlender_3(hecl::blender::PyOutStream& os, athena::io::IStreamReader& rs) { - atUint32 bdMagic = rs.readUint32Big(); - if (bdMagic != 0xBABEDEAD) - Log.report(logvisor::Fatal, FMT_STRING("invalid BABEDEAD magic")); - os << "bpy.context.scene.world.use_nodes = True\n" - "bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n" - "bg_node.inputs[1].default_value = 0.0\n"; - for (atUint32 s = 0; s < 4; ++s) { - atUint32 lightCount = rs.readUint32Big(); - for (atUint32 l = 0; l < lightCount; ++l) { - BabeDeadLight light; - light.read(rs); - ReadBabeDeadLightToBlender(os, light, s, l); - } - } -} - -bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function) { - using RigPair = std::pair, std::pair>; - RigPair dummy = {}; - - if (!force && outPath.isFile()) - return true; - - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* MREA decompression stream */ - StreamReader drs(rs, head.compressedBlockCount, head.secIndexCount); - hecl::ProjectPath decompPath = outPath.getCookedPath(SpecEntMP3ORIG).getWithExtension(".decomp"); - decompPath.makeDirChain(false); - athena::io::FileWriter mreaDecompOut(decompPath.getAbsolutePath()); - head.write(mreaDecompOut); - mreaDecompOut.seekAlign32(); - drs.writeDecompInfos(mreaDecompOut); - mreaDecompOut.seekAlign32(); - drs.writeSecIdxs(mreaDecompOut); - mreaDecompOut.seekAlign32(); - atUint64 decompLen = drs.length(); - mreaDecompOut.writeBytes(drs.readBytes(decompLen).get(), decompLen); - mreaDecompOut.close(); - drs.seek(0, athena::SeekOrigin::Begin); - - /* Start up blender connection */ - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Area)) - return false; - - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os.format(FMT_STRING("import bpy\n" - "import bmesh\n" - "from mathutils import Vector\n" - "\n" - "bpy.context.scene.name = '{}'\n"), - pakRouter.getBestEntryName(entry, false)); - DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath()); - MaterialSet::RegisterMaterialProps(os); - os << "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "bpy.types.Light.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n" - "bpy.types.Light.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n" - "\n"; - - /* One shared material set for all meshes */ - os << "# Materials\n" - "materials = []\n" - "\n"; - MaterialSet matSet; - atUint64 secStart = drs.position(); - matSet.read(drs); - matSet.readToBlender(os, pakRouter, entry, 0); - drs.seek(secStart + head.secSizes[0], athena::SeekOrigin::Begin); - std::vector vertAttribs; - DNACMDL::GetVertexAttributes(matSet, vertAttribs); - - /* Read mesh info */ - atUint32 curSec = 1; - std::vector surfaceCounts; - surfaceCounts.reserve(head.meshCount); - for (atUint32 m = 0; m < head.meshCount; ++m) { - /* Mesh header */ - MeshHeader mHeader; - secStart = drs.position(); - mHeader.read(drs); - drs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Surface count from here */ - secStart = drs.position(); - surfaceCounts.push_back(drs.readUint32Big()); - drs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Seek through AROT-relation sections */ - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - } - - /* Skip though WOBJs */ - auto secIdxIt = drs.beginSecIdxs(); - while (secIdxIt->first == FOURCC('WOBJ')) - ++secIdxIt; - - /* Skip AROT */ - if (secIdxIt->first == FOURCC('ROCT')) { - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - ++secIdxIt; - } - - /* Skip AABB */ - if (secIdxIt->first == FOURCC('AABB')) { - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - ++secIdxIt; - } - - /* Now the meshes themselves */ - if (secIdxIt->first == FOURCC('GPUD')) { - for (atUint32 m = 0; m < head.meshCount; ++m) { - curSec += - DNACMDL::ReadGeomSectionsToBlender, MaterialSet, RigPair, DNACMDL::SurfaceHeader_3>( - os, drs, pakRouter, entry, dummy, true, false, vertAttribs, m, head.secCount, 0, &head.secSizes[curSec], - surfaceCounts[m]); - } - ++secIdxIt; - } - - /* Skip DEPS */ - if (secIdxIt->first == FOURCC('DEPS')) { - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - ++secIdxIt; - } - - /* Skip SOBJ (SCLY) */ - if (secIdxIt->first == FOURCC('SOBJ')) { - for (atUint32 l = 0; l < head.sclyLayerCount; ++l) - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - ++secIdxIt; - } - - /* Skip SGEN */ - if (secIdxIt->first == FOURCC('SGEN')) { - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - ++secIdxIt; - } - - /* Read Collision Meshes */ - if (secIdxIt->first == FOURCC('COLI')) { - DNAMP2::DeafBabe collision; - secStart = drs.position(); - collision.read(drs); - DNAMP2::DeafBabe::BlenderInit(os); - collision.sendToBlender(os); - drs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - ++secIdxIt; - } - - /* Read BABEDEAD Lights as Cycles emissives */ - if (secIdxIt->first == FOURCC('LITE')) { - secStart = drs.position(); - ReadBabeDeadToBlender_3(os, drs); - drs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - ++secIdxIt; - } - - /* Origins to center of mass */ - os << "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = False\n" - "bpy.ops.object.select_by_type(type='MESH')\n" - "bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')\n" - "bpy.ops.object.select_all(action='DESELECT')\n" - "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = True\n"; - - os.centerView(); - os.close(); - return conn.saveBlend(); -} - -bool MREA::ExtractLayerDeps(PAKEntryReadStream& rs, PAKBridge::Level::Area& areaOut) { - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* MREA decompression stream */ - StreamReader drs(rs, head.compressedBlockCount, head.secIndexCount); - for (const std::pair& idx : drs.m_secIdxs) { - if (idx.first == FOURCC('DEPS')) { - drs.seek(head.getSecOffset(idx.second), athena::SeekOrigin::Begin); - DEPS deps; - deps.read(drs); - - unsigned r = 0; - for (unsigned l = 1; l < deps.depLayerCount; ++l) { - if (l > areaOut.layers.size()) - break; - PAKBridge::Level::Area::Layer& layer = areaOut.layers.at(l - 1); - layer.resources.reserve(deps.depLayers[l] - r); - for (; r < deps.depLayers[l]; ++r) - layer.resources.emplace(deps.deps[r].id); - } - areaOut.resources.reserve(deps.depCount - r + 2); - for (; r < deps.depCount; ++r) - areaOut.resources.emplace(deps.deps[r].id); - - return true; - } - } - return false; -} - -UniqueID64 MREA::GetPATHId(PAKEntryReadStream& rs) { - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* MREA decompression stream */ - StreamReader drs(rs, head.compressedBlockCount, head.secIndexCount); - - /* Skip to PATH */ - if (drs.seekToSection(FOURCC('PFL2'), head.secSizes)) - return {drs}; - return {}; -} - -} // namespace DNAMP3 -} // namespace DataSpec diff --git a/DataSpec/DNAMP3/MREA.hpp b/DataSpec/DNAMP3/MREA.hpp deleted file mode 100644 index 2fb0ebf9b..000000000 --- a/DataSpec/DNAMP3/MREA.hpp +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "CMDLMaterials.hpp" -#include "CSKR.hpp" -#include "../DNAMP2/MREA.hpp" - -namespace DataSpec::DNAMP3 { - -struct MREA { - struct StreamReader : DNAMP2::MREA::StreamReader { - std::vector> m_secIdxs; - StreamReader(athena::io::IStreamReader& source, atUint32 blkCount, atUint32 secIdxCount); - std::vector>::const_iterator beginSecIdxs() { return m_secIdxs.begin(); } - void writeSecIdxs(athena::io::IStreamWriter& writer) const; - bool seekToSection(FourCC sec, const std::vector& secSizes); - }; - - struct Header : BigDNA { - AT_DECL_DNA - Value magic; - Value version; - Value localToWorldMtx[3]; - Value meshCount; - Value sclyLayerCount; - Value secCount; - Value compressedBlockCount; - Value secIndexCount; - Seek<20, athena::SeekOrigin::Current> align1; - Vector secSizes; - - atUint32 getSecOffset(atUint32 idx) const { - if (idx >= secSizes.size()) - return -1; - atUint32 retval = 0; - for (atUint32 i = 0; i < idx; ++i) - retval += secSizes[i]; - return retval; - } - }; - - struct MeshHeader : BigDNA { - AT_DECL_DNA - struct VisorFlags : BigDNA { - AT_DECL_DNA - Value flags; - } visorFlags; - Value xfMtx[3]; - Value aabb[2]; - }; - - struct DEPS : BigDNA { - AT_DECL_DNA - Value depCount; - struct Dependency : BigDNA { - AT_DECL_DNA - UniqueID64 id; - DNAFourCC type; - }; - Vector deps; - Value depLayerCount; - Vector depLayers; - }; - - struct BabeDeadLight : BigDNA { - AT_DECL_DNA - enum class LightType : atUint32 { LocalAmbient, Directional, Custom, Spot, Spot2, LocalAmbient2 }; - enum class Falloff : atUint32 { Constant, Linear, Quadratic }; - Value lightType; - Value color; - Value alpha = 1.f; - Value position; - Value direction; - Value codirection; - Value q; - Value spotCutoff; - Value unk7; - Value castShadows; - Value unk9; - Value falloff; - Value unk11; - Value unk12; - Value unk13; - }; - - static void ReadBabeDeadToBlender_3(hecl::blender::PyOutStream& os, athena::io::IStreamReader& rs); - - static UniqueID64 GetPATHId(PAKEntryReadStream& rs); - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool, hecl::blender::Token& btok, - std::function); - - static bool ExtractLayerDeps(PAKEntryReadStream& rs, PAKBridge::Level::Area& areaOut); -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/PAK.cpp b/DataSpec/DNAMP3/PAK.cpp deleted file mode 100644 index 81a4b016a..000000000 --- a/DataSpec/DNAMP3/PAK.cpp +++ /dev/null @@ -1,231 +0,0 @@ -#include "PAK.hpp" -#include "DNAMP3.hpp" - -namespace DataSpec::DNAMP3 { - -const hecl::FourCC CMPD("CMPD"); - -template <> -void PAK::Enumerate(athena::io::IStreamReader& reader) { - m_header.read(reader); - if (m_header.version != 2) - Log.report(logvisor::Fatal, FMT_STRING("unexpected PAK magic")); - - reader.seek(8, athena::SeekOrigin::Current); - atUint32 strgSz = reader.readUint32Big(); - reader.seek(4, athena::SeekOrigin::Current); - atUint32 rshdSz = reader.readUint32Big(); - reader.seek(44, athena::SeekOrigin::Current); - atUint32 dataOffset = 128 + strgSz + rshdSz; - - atUint64 strgBase = reader.position(); - atUint32 nameCount = reader.readUint32Big(); - m_nameEntries.clear(); - m_nameEntries.reserve(nameCount); - for (atUint32 n = 0; n < nameCount; ++n) { - m_nameEntries.emplace_back(); - m_nameEntries.back().read(reader); - } - reader.seek(strgBase + strgSz, athena::SeekOrigin::Begin); - - atUint32 count = reader.readUint32Big(); - m_entries.clear(); - m_entries.reserve(count); - m_firstEntries.clear(); - m_firstEntries.reserve(count); - std::vector entries; - entries.reserve(count); - for (atUint32 e = 0; e < count; ++e) { - entries.emplace_back(); - entries.back().read(reader); - } - for (atUint32 e = 0; e < count; ++e) { - Entry& entry = entries[e]; - entry.offset += dataOffset; - - auto search = m_entries.find(entry.id); - if (search == m_entries.end()) { - m_firstEntries.push_back(entry.id); - m_entries[entry.id] = std::move(entry); - } else { - /* Find next MREA to record which area has dupes */ - for (atUint32 e2 = e + 1; e2 < count; ++e2) { - Entry& entry2 = entries[e2]; - if (entry2.type != FOURCC('MREA')) - continue; - m_dupeMREAs.insert(entry2.id); - break; - } - } - } - - m_nameMap.clear(); - m_nameMap.reserve(nameCount); - for (NameEntry& entry : m_nameEntries) - m_nameMap[entry.name] = entry.id; -} - -template <> -void PAK::Enumerate(athena::io::IStreamWriter& writer) { - m_header.write(writer); - - DNAFourCC("STRG").write(writer); - atUint32 strgSz = 4; - for (const NameEntry& entry : m_nameEntries) - strgSz += (atUint32)entry.name.size() + 13; - atUint32 strgPad = ((strgSz + 63) & ~63) - strgSz; - strgSz += strgPad; - writer.writeUint32Big(strgSz); - - DNAFourCC("RSHD").write(writer); - atUint32 rshdSz = 4 + 24 * m_entries.size(); - atUint32 rshdPad = ((rshdSz + 63) & ~63) - rshdSz; - rshdSz += rshdPad; - writer.writeUint32Big(rshdSz); - atUint32 dataOffset = 128 + strgSz + rshdSz; - - DNAFourCC("DATA").write(writer); - atUint32 dataSz = 0; - for (const auto& entry : m_entries) - dataSz += (entry.second.size + 63) & ~63; - atUint32 dataPad = ((dataSz + 63) & ~63) - dataSz; - dataSz += dataPad; - writer.writeUint32Big(dataSz); - writer.seek(36, athena::SeekOrigin::Current); - - writer.writeUint32Big((atUint32)m_nameEntries.size()); - for (const NameEntry& entry : m_nameEntries) - entry.write(writer); - writer.seek(strgPad, athena::SeekOrigin::Current); - - writer.writeUint32Big((atUint32)m_entries.size()); - for (const auto& entry : m_entries) { - Entry copy = entry.second; - copy.offset -= dataOffset; - copy.write(writer); - } - writer.seek(rshdPad, athena::SeekOrigin::Current); -} - -template <> -void PAK::Enumerate(size_t& __isz) { - m_header.binarySize(__isz); - - size_t strgSz = 4; - for (const NameEntry& entry : m_nameEntries) - strgSz += entry.name.size() + 13; - size_t strgPad = ((strgSz + 63) & ~63) - strgSz; - - size_t rshdSz = 4 + 24 * m_entries.size(); - size_t rshdPad = ((rshdSz + 63) & ~63) - rshdSz; - - __isz += 60; - - __isz += 4; - for (const NameEntry& entry : m_nameEntries) - entry.binarySize(__isz); - __isz += strgPad; - - __isz += 4; - for (const auto& entry : m_entries) - entry.second.binarySize(__isz); - __isz += rshdPad; -} - -std::unique_ptr PAK::Entry::getBuffer(const nod::Node& pak, atUint64& szOut) const { - if (compressed) { - std::unique_ptr strm = pak.beginReadStream(offset); - struct { - hecl::FourCC magic; - atUint32 blockCount; - } head; - strm->read(&head, 8); - if (head.magic != CMPD) { - Log.report(logvisor::Error, FMT_STRING("invalid CMPD block")); - return nullptr; - } - head.blockCount = hecl::SBig(head.blockCount); - - struct Block { - atUint32 compSz; - atUint32 decompSz; - }; - std::unique_ptr blocks(new Block[head.blockCount]); - strm->read(blocks.get(), 8 * head.blockCount); - - atUint64 maxBlockSz = 0; - atUint64 totalDecompSz = 0; - for (atUint32 b = 0; b < head.blockCount; ++b) { - Block& block = blocks[b]; - block.compSz = hecl::SBig(block.compSz) & 0xffffff; - block.decompSz = hecl::SBig(block.decompSz); - if (block.compSz > maxBlockSz) - maxBlockSz = block.compSz; - totalDecompSz += block.decompSz; - } - - std::unique_ptr compBuf(new atUint8[maxBlockSz]); - std::unique_ptr buf{new atUint8[totalDecompSz]}; - atUint8* bufCur = buf.get(); - for (atUint32 b = 0; b < head.blockCount; ++b) { - Block& block = blocks[b]; - atUint8* compBufCur = compBuf.get(); - strm->read(compBufCur, block.compSz); - if (block.compSz == block.decompSz) { - memcpy(bufCur, compBufCur, block.decompSz); - bufCur += block.decompSz; - } else { - atUint32 rem = block.decompSz; - while (rem) { - atUint16 chunkSz = hecl::SBig(*(atUint16*)compBufCur); - compBufCur += 2; - size_t dsz; - lzokay::decompress(compBufCur, chunkSz, bufCur, rem, dsz); - compBufCur += chunkSz; - bufCur += dsz; - rem -= dsz; - } - } - } - - szOut = totalDecompSz; - return buf; - } else { - std::unique_ptr buf{new atUint8[size]}; - pak.beginReadStream(offset)->read(buf.get(), size); - szOut = size; - return buf; - } -} - -const PAK::Entry* PAK::lookupEntry(const UniqueID64& id) const { - auto result = m_entries.find(id); - if (result != m_entries.end()) - return &result->second; - return nullptr; -} - -const PAK::Entry* PAK::lookupEntry(std::string_view name) const { - // TODO: Heterogeneous lookup when C++20 available - auto result = m_nameMap.find(name.data()); - if (result != m_nameMap.end()) { - auto result1 = m_entries.find(result->second); - if (result1 != m_entries.end()) - return &result1->second; - } - return nullptr; -} - -std::string PAK::bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const { - /* Prefer named entries first */ - for (const NameEntry& nentry : m_nameEntries) - if (nentry.id == entry.id) { - catalogueName = nentry.name; - return fmt::format(FMT_STRING("{}_{}"), nentry.name, entry.id); - } - - /* Otherwise return ID format string */ - return fmt::format(FMT_STRING("{}_{}"), entry.type, entry.id); -} - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/PAK.hpp b/DataSpec/DNAMP3/PAK.hpp deleted file mode 100644 index 298dc5770..000000000 --- a/DataSpec/DNAMP3/PAK.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include - -#include -#include -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAMP3 { - -extern const hecl::FourCC CMPD; - -struct PAK : BigDNA { - bool m_noShare; - PAK(bool noShare) : m_noShare(noShare) {} - - struct Header : BigDNA { - AT_DECL_DNA - Value version; - Value headSz; - Value md5sum[16]; - Seek<40, athena::SeekOrigin::Current> seek; - } m_header; - - struct NameEntry : BigDNA { - AT_DECL_DNA - String<-1> name; - DNAFourCC type; - UniqueID64 id; - }; - - struct Entry : BigDNA { - AT_DECL_DNA - Value compressed; - DNAFourCC type; - UniqueID64 id; - Value size; - Value offset; - UniqueResult unique; - std::string name; - - std::unique_ptr getBuffer(const nod::Node& pak, atUint64& szOut) const; - inline PAKEntryReadStream beginReadStream(const nod::Node& pak, atUint64 off = 0) const { - atUint64 sz; - std::unique_ptr buf = getBuffer(pak, sz); - return PAKEntryReadStream(std::move(buf), sz, off); - } - }; - - std::vector m_nameEntries; - std::unordered_map m_entries; - std::vector m_firstEntries; - std::unordered_map m_nameMap; - std::unordered_set m_dupeMREAs; - - AT_DECL_EXPLICIT_DNA - - const Entry* lookupEntry(const UniqueID64& id) const; - const Entry* lookupEntry(std::string_view name) const; - std::string bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const; - - bool mreaHasDupeResources(const UniqueID64& id) const { return m_dupeMREAs.find(id) != m_dupeMREAs.cend(); } - - using IDType = UniqueID64; -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/PATH.hpp b/DataSpec/DNAMP3/PATH.hpp deleted file mode 100644 index f2b218055..000000000 --- a/DataSpec/DNAMP3/PATH.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include "DataSpec/DNACommon/PATH.hpp" - -namespace DataSpec::DNAMP3 { -using PATH = DNAPATH::PATH; -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/SAND.hpp b/DataSpec/DNAMP3/SAND.hpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/DataSpec/DNAMP3/SAVW.hpp b/DataSpec/DNAMP3/SAVW.hpp deleted file mode 100644 index 77c03914c..000000000 --- a/DataSpec/DNAMP3/SAVW.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/SAVWCommon.hpp" -#include "DNAMP3.hpp" - -namespace DataSpec::DNAMP3 { -struct Scan : BigDNA { - AT_DECL_DNA_YAML - UniqueID64 scanId; - Value category; -}; - -struct SavedState : BigDNA { - AT_DECL_DNA_YAML - struct ID : BigDNA { - AT_DECL_DNA_YAML - Value id[2]; - }; - ID id; - Value instance; -}; - -struct SAVW : BigDNA { - AT_DECL_DNA_YAML - SAVWCommon::Header header; - Value skippableCutsceneCount; - Vector skippableCutscenes; - Value relayCount; - Vector relays; - Value doorCount; - Vector doors; - Value scanCount; - Vector scans; - Value systemVarCount; - Vector systemVars; - Value gameVarCount; - Vector gameVars; - Value gameObjectCount; - Vector gameObjects; -}; -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/STRG.cpp b/DataSpec/DNAMP3/STRG.cpp deleted file mode 100644 index 9ac591919..000000000 --- a/DataSpec/DNAMP3/STRG.cpp +++ /dev/null @@ -1,228 +0,0 @@ -#include "STRG.hpp" -#include "DNAMP3.hpp" - -namespace DataSpec::DNAMP3 { - -void STRG::_read(athena::io::IStreamReader& reader) { - atUint32 langCount = reader.readUint32Big(); - atUint32 strCount = reader.readUint32Big(); - - atUint32 nameCount = reader.readUint32Big(); - atUint32 nameTableSz = reader.readUint32Big(); - if (nameTableSz) { - std::unique_ptr nameTableBuf(new uint8_t[nameTableSz]); - reader.readUBytesToBuf(nameTableBuf.get(), nameTableSz); - struct NameIdxEntry { - atUint32 nameOff; - atUint32 strIdx; - }* nameIndex = (NameIdxEntry*)nameTableBuf.get(); - for (atUint32 n = 0; n < nameCount; ++n) { - const char* name = (char*)(nameTableBuf.get() + hecl::SBig(nameIndex[n].nameOff)); - names[name] = hecl::SBig(nameIndex[n].strIdx); - } - } - - std::vector readLangs; - readLangs.reserve(langCount); - for (atUint32 l = 0; l < langCount; ++l) { - DNAFourCC lang; - lang.read(reader); - readLangs.emplace_back(lang); - } - std::unique_ptr strOffs(new atUint32[langCount * strCount]); - for (atUint32 l = 0; l < langCount; ++l) { - reader.readUint32Big(); - for (atUint32 s = 0; s < strCount; ++s) - strOffs[l * strCount + s] = reader.readUint32Big(); - } - - atUint64 strBase = reader.position(); - langs.clear(); - langs.reserve(langCount); - for (atUint32 l = 0; l < langCount; ++l) { - std::vector strs; - for (atUint32 s = 0; s < strCount; ++s) { - reader.seek(strBase + strOffs[l * strCount + s], athena::SeekOrigin::Begin); - atUint32 len = reader.readUint32Big(); - strs.emplace_back(reader.readString(len)); - } - langs.emplace_back(readLangs[l], strs); - } - - langMap.clear(); - langMap.reserve(langCount); - for (std::pair>& item : langs) - langMap.emplace(item.first, &item.second); -} - -template <> -void STRG::Enumerate(athena::io::IStreamReader& reader) { - atUint32 magic = reader.readUint32Big(); - if (magic != 0x87654321) { - Log.report(logvisor::Error, FMT_STRING("invalid STRG magic")); - return; - } - - atUint32 version = reader.readUint32Big(); - if (version != 3) { - Log.report(logvisor::Error, FMT_STRING("invalid STRG version")); - return; - } - - _read(reader); -} - -template <> -void STRG::Enumerate(athena::io::YAMLDocReader& reader) { - const athena::io::YAMLNode* root = reader.getRootNode(); - - /* Validate Pass */ - if (root->m_type == YAML_MAPPING_NODE) { - for (const auto& lang : root->m_mapChildren) { - if (lang.first == "names") - continue; - if (lang.first.size() != 4) { - Log.report(logvisor::Warning, FMT_STRING("STRG language string '{}' must be exactly 4 characters; skipping"), - lang.first); - return; - } - if (lang.second->m_type != YAML_SEQUENCE_NODE) { - Log.report(logvisor::Warning, FMT_STRING("STRG language string '{}' must contain a sequence; skipping"), - lang.first); - return; - } - for (const auto& str : lang.second->m_seqChildren) { - if (str->m_type != YAML_SCALAR_NODE) { - Log.report(logvisor::Warning, FMT_STRING("STRG language '{}' must contain all scalars; skipping"), - lang.first); - return; - } - } - } - } else { - Log.report(logvisor::Warning, FMT_STRING("STRG must have a mapping root node; skipping")); - return; - } - - const athena::io::YAMLNode* nameYAML = root->findMapChild("names"); - names.clear(); - if (nameYAML && nameYAML->m_type == YAML_MAPPING_NODE) - for (const auto& item : nameYAML->m_mapChildren) - if (item.second->m_type == YAML_SCALAR_NODE) - names[item.first] = athena::io::NodeToVal(item.second.get()); - - langs.clear(); - langs.reserve(root->m_mapChildren.size()); - for (const auto& item : root->m_mapChildren) { - if (item.first == "names" || item.first.size() != 4 || item.second->m_type != YAML_SEQUENCE_NODE) - continue; - - std::vector strs; - for (const auto& node : item.second->m_seqChildren) - if (node->m_type == YAML_SCALAR_NODE) - strs.emplace_back(node->m_scalarString); - langs.emplace_back(std::make_pair(DNAFourCC(item.first.c_str()), std::move(strs))); - } - - langMap.clear(); - langMap.reserve(langs.size()); - for (std::pair>& item : langs) - langMap.emplace(item.first, &item.second); -} - -template <> -void STRG::Enumerate(athena::io::IStreamWriter& writer) { - writer.writeUint32Big(0x87654321); - writer.writeUint32Big(3); - writer.writeUint32Big(langs.size()); - atUint32 strCount = STRG::count(); - writer.writeUint32Big(strCount); - - atUint32 nameTableSz = names.size() * 8; - for (const auto& name : names) - nameTableSz += name.first.size() + 1; - writer.writeUint32Big(names.size()); - writer.writeUint32Big(nameTableSz); - atUint32 offset = names.size() * 8; - for (const auto& name : names) { - writer.writeUint32Big(offset); - writer.writeInt32Big(name.second); - offset += name.first.size() + 1; - } - for (const auto& name : names) - writer.writeString(name.first); - - for (const auto& lang : langs) - lang.first.write(writer); - - offset = 0; - for (const auto& lang : langs) { - atUint32 langSz = 0; - for (const std::string& str : lang.second) - langSz += str.size() + 5; - writer.writeUint32Big(langSz); - - for (const std::string& str : lang.second) { - writer.writeUint32Big(offset); - offset += str.size() + 5; - } - } - - for (atUint32 s = 0; s < strCount; ++s) { - for (const auto& lang : langs) { - if (s >= lang.second.size()) { - writer.writeUint32Big(1); - writer.writeUByte(0); - } else { - const std::string& str = lang.second[s]; - writer.writeUint32Big(str.size() + 1); - writer.writeString(str); - } - } - } -} - -template <> -void STRG::Enumerate(size_t& __isz) { - __isz += 24; - __isz += names.size() * 8; - for (const auto& name : names) - __isz += name.first.size() + 1; - - __isz += langs.size() * 4; - - for (const auto& lang : langs) - __isz += 4 + lang.second.size() * 4; - - size_t strCount = STRG::count(); - for (atUint32 s = 0; s < strCount; ++s) { - for (const auto& lang : langs) { - if (s >= lang.second.size()) { - __isz += 5; - } else { - const std::string& str = lang.second[s]; - __isz += str.size() + 5; - } - } - } -} - -template <> -void STRG::Enumerate(athena::io::YAMLDocWriter& writer) { - for (const auto& item : langs) { - if (auto v = writer.enterSubVector(item.first.toString())) - for (const std::string& str : item.second) - writer.writeString(str); - } - - if (names.size()) { - if (auto rec = writer.enterSubRecord("names")) - for (const auto& item : names) - if (auto rec = writer.enterSubRecord(item.first)) - writer.writeInt32(item.second); - } -} - -std::string_view STRG::DNAType() { return "DNAMP3::STRG"sv; } - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/STRG.hpp b/DataSpec/DNAMP3/STRG.hpp deleted file mode 100644 index 211dc52c3..000000000 --- a/DataSpec/DNAMP3/STRG.hpp +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/STRG.hpp" - -namespace DataSpec::DNAMP3 { - -struct STRG : ISTRG { - AT_DECL_EXPLICIT_DNA_YAMLV - void _read(athena::io::IStreamReader& reader); - std::vector>> langs; - std::unordered_map*> langMap; - std::map names; - - int32_t lookupIdx(std::string_view name) const override { - // TODO: Heterogeneous lookup when C++20 available - auto search = names.find(name.data()); - if (search == names.end()) - return -1; - return search->second; - } - - size_t count() const override { - size_t retval = 0; - for (const auto& item : langs) { - size_t sz = item.second.size(); - if (sz > retval) - retval = sz; - } - return retval; - } - std::string getUTF8(const FourCC& lang, size_t idx) const override { - auto search = langMap.find(lang); - if (search != langMap.end()) - return search->second->at(idx); - return std::string(); - } - std::u16string getUTF16(const FourCC& lang, size_t idx) const override { - auto search = langMap.find(lang); - if (search != langMap.end()) - return hecl::UTF8ToChar16(search->second->at(idx)); - return std::u16string(); - } - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - std::unique_ptr strg = LoadSTRG(rs); - athena::io::TransactionalFileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(*strg, writer); - return true; - } - - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - STRG strg; - athena::io::FileReader reader(inPath.getAbsolutePath()); - athena::io::FromYAMLStream(strg, reader); - athena::io::TransactionalFileWriter ws(outPath.getAbsolutePath()); - strg.write(ws); - return true; - } -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/SpecBase.cpp b/DataSpec/SpecBase.cpp deleted file mode 100644 index 3cca8b98b..000000000 --- a/DataSpec/SpecBase.cpp +++ /dev/null @@ -1,1222 +0,0 @@ -#if _WIN32 -#define _CRT_RAND_S -#include -#endif - -#include "DataSpec/SpecBase.hpp" -#include "DataSpec/Blender/BlenderSupport.hpp" -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/TXTR.hpp" -#include "DataSpec/AssetNameMap.hpp" -#include "DataSpec/DNACommon/MetaforceVersionInfo.hpp" -#include "hecl/ClientProcess.hpp" -#include "nod/DiscBase.hpp" -#include "nod/nod.hpp" -#include "hecl/Blender/Connection.hpp" -#include "hecl/Blender/SDNARead.hpp" -#include "hecl/MultiProgressPrinter.hpp" - -#include - -#define DUMP_CACHE_FILL 1 - -namespace DataSpec { - -static logvisor::Module Log("DataSpec::SpecBase"); - -static const char* MomErr[] = {"Your metroid is in another castle", - "HECL is experiencing a PTSD attack", - "Unable to freeze metroids", - "Ridley ate your homework", - "Expected 0 maternal symbolisms, found 2147483647", - "Contradictive narratives unsupported", - "Wiimote profile \"NES + Zapper\" not recognized", - "Unable to find Waldo", - "Expected Ridley, found furby", - "Adam has not authorized this, please do not bug the developers", - "Lady returned objection", - "Unterminated plot thread 'Deleter' detected"}; - -constexpr uint32_t MomErrCount = std::extent::value; - -static ERegion g_CurRegion = ERegion::Invalid; -static bool g_CurSpecIsWii = false; - -ERegion getCurrentRegion() { return g_CurRegion; } -bool isCurrentSpecWii() { return g_CurSpecIsWii; } - -SpecBase::SpecBase(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc) -: hecl::Database::IDataSpec(specEntry) -, m_project(project) -, m_pc(pc) -, m_masterShader(project.getProjectWorkingPath(), ".hecl/RetroMasterShader.blend") -, m_region(ERegion::Invalid) -, m_game(EGame::Invalid) { - AssetNameMap::InitAssetNameMap(); - SpecBase::setThreadProject(); -} - -SpecBase::~SpecBase() { cancelBackgroundIndex(); } - -static const std::string regNONE = ""; -static const std::string regE = "NTSC"; -static const std::string regJ = "NTSC-J"; -static const std::string regP = "PAL"; - -void SpecBase::setThreadProject() { UniqueIDBridge::SetThreadProject(m_project); } - -bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector& reps) { - m_disc = nod::OpenDiscFromImage(info.srcpath, m_isWii); - if (!m_disc) - return false; - const char* gameID = m_disc->getHeader().m_gameID; - - if (!memcmp(gameID, "R3O", 3)) { - std::srand(std::time(0)); - int r = std::rand() % MomErrCount; - Log.report(logvisor::Fatal, FMT_STRING("{}"), MomErr[r]); - } - - m_standalone = true; - if (m_isWii && (!memcmp(gameID, "R3M", 3) || !memcmp(gameID, "R3I", 3) || !memcmp(gameID, "R32", 3))) - m_standalone = false; - - if (m_standalone && !checkStandaloneID(gameID)) - return false; - - m_region = ERegion(m_disc->getHeader().m_gameID[3]); - const std::string* regstr = ®NONE; - switch (m_region) { - case ERegion::NTSC_U: - regstr = ®E; - break; - case ERegion::NTSC_J: - regstr = ®J; - break; - case ERegion::PAL: - regstr = ®P; - break; - default: - break; - } - - setCurRegion(m_region); - setCurSpecIsWii(m_isWii); - - if (m_standalone) - return checkFromStandaloneDisc(*m_disc, *regstr, info.extractArgs, reps); - else - return checkFromTrilogyDisc(*m_disc, *regstr, info.extractArgs, reps); -} - -void SpecBase::doExtract(const ExtractPassInfo& info, const hecl::MultiProgressPrinter& progress) { - setThreadProject(); - DataSpec::g_curSpec.reset(this); - if (!Blender::BuildMasterShader(m_masterShader)) - Log.report(logvisor::Fatal, FMT_STRING("Unable to build master shader blend")); - if (m_isWii) { - /* Extract root files for repacking later */ - hecl::ProjectPath outDir(m_project.getProjectWorkingPath(), "out"); - outDir.makeDirChain(true); - nod::ExtractionContext ctx = {info.force, nullptr}; - - if (!m_standalone) { - progress.print("Trilogy Files", "", 0.0); - nod::IPartition* data = m_disc->getDataPartition(); - const nod::Node& root = data->getFSTRoot(); - for (const nod::Node& child : root) - if (child.getKind() == nod::Node::Kind::File) - child.extractToDirectory(outDir.getAbsolutePath(), ctx); - progress.print("Trilogy Files", "", 1.0); - } - } - extractFromDisc(*m_disc, info.force, progress); -} - -bool IsPathAudioGroup(const hecl::ProjectPath& path) { - return (path.getPathType() == hecl::ProjectPath::Type::Directory && - hecl::ProjectPath(path, "!project.yaml").isFile() && - hecl::ProjectPath(path, "!pool.yaml").isFile()); -} - -static bool IsPathSong(const hecl::ProjectPath& path) { - if (path.getPathType() != hecl::ProjectPath::Type::Glob || !path.getWithExtension(".mid", true).isFile() || - !path.getWithExtension(".yaml", true).isFile()) { - return path.isFile() && path.getLastComponentExt() == "mid" && - path.getWithExtension(".yaml", true).isFile(); - } - return true; -} - -bool SpecBase::canCook(const hecl::ProjectPath& path, hecl::blender::Token& btok) { - if (!checkPathPrefix(path)) - return false; - - hecl::ProjectPath asBlend; - if (path.getPathType() == hecl::ProjectPath::Type::Glob) - asBlend = path.getWithExtension(".blend", true); - else - asBlend = path; - - if (hecl::IsPathBlend(asBlend)) { - hecl::blender::BlendType type = hecl::blender::GetBlendType(asBlend.getAbsolutePath()); - return type != hecl::blender::BlendType::None; - } - - if (hecl::IsPathPNG(path)) { - return true; - } else if (hecl::IsPathYAML(path)) { - athena::io::FileReader reader(path.getAbsolutePath()); - bool retval = validateYAMLDNAType(reader); - return retval; - } else if (IsPathAudioGroup(path)) { - return true; - } else if (IsPathSong(path)) { - return true; - } - return false; -} - -const hecl::Database::DataSpecEntry* SpecBase::overrideDataSpec(const hecl::ProjectPath& path, - const hecl::Database::DataSpecEntry* oldEntry) const { - if (!checkPathPrefix(path)) - return nullptr; - - hecl::ProjectPath asBlend; - if (path.getPathType() == hecl::ProjectPath::Type::Glob) - asBlend = path.getWithExtension(".blend", true); - else - asBlend = path; - - if (hecl::IsPathBlend(asBlend)) { - if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".CSKR") || - hecl::StringUtils::EndsWith(path.getAuxInfo(), ".ANIM")) - return oldEntry; - - hecl::blender::BlendType type = hecl::blender::GetBlendType(asBlend.getAbsolutePath()); - if (type == hecl::blender::BlendType::None) { - Log.report(logvisor::Error, FMT_STRING("unable to cook '{}'"), path.getAbsolutePath()); - return nullptr; - } - if (type == hecl::blender::BlendType::Mesh || type == hecl::blender::BlendType::Area) - return oldEntry; - } else if (hecl::IsPathPNG(path)) { - return oldEntry; - } - return &getOriginalSpec(); -} - -void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, bool fast, - hecl::blender::Token& btok, FCookProgress progress) { - cookedPath.makeDirChain(false); - DataSpec::g_curSpec.reset(this); - - hecl::ProjectPath asBlend; - if (path.getPathType() == hecl::ProjectPath::Type::Glob) - asBlend = path.getWithExtension(".blend", true); - else - asBlend = path; - - if (hecl::IsPathBlend(asBlend)) { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.openBlend(asBlend)) - return; - switch (conn.getBlendType()) { - case hecl::blender::BlendType::Mesh: { - hecl::blender::DataStream ds = conn.beginData(); - cookMesh(cookedPath, path, ds, fast, btok, progress); - break; - } - case hecl::blender::BlendType::ColMesh: { - hecl::blender::DataStream ds = conn.beginData(); - cookColMesh(cookedPath, path, ds, fast, btok, progress); - break; - } - case hecl::blender::BlendType::Armature: { - hecl::blender::DataStream ds = conn.beginData(); - cookArmature(cookedPath, path, ds, fast, btok, progress); - break; - } - case hecl::blender::BlendType::PathMesh: { - hecl::blender::DataStream ds = conn.beginData(); - cookPathMesh(cookedPath, path, ds, fast, btok, progress); - break; - } - case hecl::blender::BlendType::Actor: { - hecl::blender::DataStream ds = conn.beginData(); - cookActor(cookedPath, path, ds, fast, btok, progress); - break; - } - case hecl::blender::BlendType::Area: { - hecl::blender::DataStream ds = conn.beginData(); - cookArea(cookedPath, path, ds, fast, btok, progress); - break; - } - case hecl::blender::BlendType::World: { - hecl::blender::DataStream ds = conn.beginData(); - cookWorld(cookedPath, path, ds, fast, btok, progress); - break; - } - case hecl::blender::BlendType::Frame: { - hecl::blender::DataStream ds = conn.beginData(); - cookGuiFrame(cookedPath, path, ds, btok, progress); - break; - } - case hecl::blender::BlendType::MapArea: { - hecl::blender::DataStream ds = conn.beginData(); - cookMapArea(cookedPath, path, ds, btok, progress); - break; - } - case hecl::blender::BlendType::MapUniverse: { - hecl::blender::DataStream ds = conn.beginData(); - cookMapUniverse(cookedPath, path, ds, btok, progress); - break; - } - default: - break; - } - } else if (hecl::IsPathPNG(path)) { - if (m_pc) - TXTR::CookPC(path, cookedPath); - else - TXTR::Cook(path, cookedPath); - } else if (hecl::IsPathYAML(path)) { - athena::io::FileReader reader(path.getAbsolutePath()); - cookYAML(cookedPath, path, reader, btok, progress); - } else if (IsPathAudioGroup(path)) { - cookAudioGroup(cookedPath, path, progress); - } else if (IsPathSong(path)) { - cookSong(cookedPath, path, progress); - } -} - -void SpecBase::flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector& pathsOut, - hecl::blender::Token& btok, int charIdx) { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.openBlend(in)) - return; - switch (conn.getBlendType()) { - case hecl::blender::BlendType::Mesh: - case hecl::blender::BlendType::Area: { - hecl::blender::DataStream ds = conn.beginData(); - std::vector texs = ds.getTextures(); - pathsOut.insert(pathsOut.end(), std::make_move_iterator(texs.begin()), std::make_move_iterator(texs.end())); - break; - } - case hecl::blender::BlendType::Actor: { - hecl::ProjectPath asGlob = in.getWithExtension(".*", true); - hecl::ProjectPath parentPath = asGlob.getParentPath(); - hecl::DirectoryEnumerator dEnum(parentPath.getAbsolutePath()); - hecl::blender::DataStream ds = conn.beginData(); - hecl::blender::Actor actor = ds.compileActorCharacterOnly(); - auto actNames = ds.getActionNames(); - ds.close(); - - auto doSubtype = [&](Actor::Subtype& sub) { - if (sub.armature >= 0) { - if (hecl::IsPathBlend(sub.mesh)) { - flattenDependenciesBlend(sub.mesh, pathsOut, btok); - pathsOut.push_back(sub.mesh); - } - - if (!sub.cskrId.empty()) { - pathsOut.push_back( - asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.CSKR"), sub.name, sub.cskrId))); - } else { - pathsOut.push_back(asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}.CSKR"), sub.name))); - } - - const auto& arm = actor.armatures[sub.armature]; - if (hecl::IsPathBlend(arm.path)) - pathsOut.push_back(arm.path); - - for (const auto& overlay : sub.overlayMeshes) { - if (hecl::IsPathBlend(overlay.mesh)) { - flattenDependenciesBlend(overlay.mesh, pathsOut, btok); - pathsOut.push_back(overlay.mesh); - } - pathsOut.push_back(asGlob.ensureAuxInfo( - fmt::format(FMT_STRING("{}.{}_{}.CSKR"), sub.name, overlay.name, overlay.cskrId))); - } - } - }; - if (charIdx < 0) - for (auto& sub : actor.subtypes) - doSubtype(sub); - else if (charIdx < actor.subtypes.size()) - doSubtype(actor.subtypes[charIdx]); - - for (const Actor::Attachment& att : actor.attachments) { - if (hecl::IsPathBlend(att.mesh)) { - flattenDependenciesBlend(att.mesh, pathsOut, btok); - pathsOut.push_back(att.mesh); - } - - pathsOut.push_back( - asGlob.ensureAuxInfo(fmt::format(FMT_STRING("ATTACH.{}_{}.CSKR"), att.name, att.cskrId))); - - if (att.armature >= 0) { - const auto& arm = actor.armatures[att.armature]; - if (hecl::IsPathBlend(arm.path)) - pathsOut.push_back(arm.path); - } - } - - for (const auto& act : actNames) { - pathsOut.push_back(asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.ANIM"), act.first, act.second))); - std::string searchPrefix( - asGlob.getWithExtension(fmt::format(FMT_STRING(".{}_"), act.first).c_str(), true) - .getLastComponent()); - hecl::ProjectPath evntPath; - for (const auto& ent : dEnum) { - if (hecl::StringUtils::BeginsWith(ent.m_name, searchPrefix.c_str()) && - hecl::StringUtils::EndsWith(ent.m_name, ".evnt.yaml")) { - evntPath = hecl::ProjectPath(parentPath, ent.m_name); - break; - } - } - if (evntPath.isFile()) - pathsOut.push_back(evntPath); - } - - hecl::ProjectPath yamlPath = asGlob.getWithExtension(".yaml", true); - if (yamlPath.isFile()) { - athena::io::FileReader reader(yamlPath.getAbsolutePath()); - flattenDependenciesANCSYAML(reader, pathsOut, charIdx); - } - - pathsOut.push_back(asGlob); - return; - } - default: - break; - } -} - -void SpecBase::flattenDependencies(const hecl::ProjectPath& path, std::vector& pathsOut, - hecl::blender::Token& btok, int charIdx) { - DataSpec::g_curSpec.reset(this); - g_ThreadBlenderToken.reset(&btok); - - hecl::ProjectPath asBlend; - if (path.getPathType() == hecl::ProjectPath::Type::Glob) - asBlend = path.getWithExtension(".blend", true); - else - asBlend = path; - - if (hecl::IsPathBlend(asBlend)) { - flattenDependenciesBlend(asBlend, pathsOut, btok, charIdx); - } else if (hecl::IsPathYAML(path)) { - athena::io::FileReader reader(path.getAbsolutePath()); - flattenDependenciesYAML(reader, pathsOut); - } - - pathsOut.push_back(path); -} - -void SpecBase::flattenDependencies(const UniqueID32& id, std::vector& pathsOut, int charIdx) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id); - if (path) - flattenDependencies(path, pathsOut, *g_ThreadBlenderToken.get(), charIdx); -} - -void SpecBase::flattenDependencies(const UniqueID64& id, std::vector& pathsOut, int charIdx) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id); - if (path) - flattenDependencies(path, pathsOut, *g_ThreadBlenderToken.get(), charIdx); -} - -bool SpecBase::canPackage(const hecl::ProjectPath& path) { - auto components = path.getPathComponents(); - if (components.size() <= 1) - return false; - return path.isFile() || path.isDirectory(); -} - -void SpecBase::recursiveBuildResourceList(std::vector& listOut, - std::unordered_set& addedTags, - const hecl::ProjectPath& path, hecl::blender::Token& btok) { - hecl::DirectoryEnumerator dEnum(path.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsThenFilesSorted, false, - false, true); - for (const auto& ent : dEnum) { - hecl::ProjectPath childPath(path, ent.m_name); - if (ent.m_isDir) { - if (hecl::ProjectPath(childPath, "!project.yaml").isFile() && - hecl::ProjectPath(childPath, "!pool.yaml").isFile()) { - /* Handle AudioGroup case */ - if (metaforce::SObjectTag tag = tagFromPath(childPath)) { - if (addedTags.find(tag) != addedTags.end()) - continue; - addedTags.insert(tag); - listOut.push_back(tag); - } - continue; - } - - recursiveBuildResourceList(listOut, addedTags, childPath, btok); - } else { - std::vector subPaths; - flattenDependencies(childPath, subPaths, btok); - for (const auto& subPath : subPaths) { - if (metaforce::SObjectTag tag = tagFromPath(subPath)) { - if (addedTags.find(tag) != addedTags.end()) - continue; - addedTags.insert(tag); - listOut.push_back(tag); - } - } - } - } -} - -void SpecBase::copyBuildListData(std::vector>& fileIndex, - const std::vector& buildList, - const hecl::Database::DataSpecEntry* entry, bool fast, - const hecl::MultiProgressPrinter& progress, athena::io::FileWriter& pakOut, - const std::unordered_map>& mlvlData) { - fileIndex.reserve(buildList.size()); - int loadIdx = 0; - for (const auto& tag : buildList) { - std::string str = fmt::format(FMT_STRING("Copying {}"), tag); - progress.print(str, std::nullopt, ++loadIdx / float(buildList.size())); - - auto& [positionOut, sizeOut, compressedOut] = fileIndex.emplace_back(); - - if (tag.type.toUint32() == FOURCC('MLVL')) { - auto search = mlvlData.find(tag.id); - if (search == mlvlData.end()) - Log.report(logvisor::Fatal, FMT_STRING("Unable to find MLVL {}"), tag.id); - - positionOut = pakOut.position(); - sizeOut = ROUND_UP_32(search->second.size()); - compressedOut = false; - pakOut.writeUBytes(search->second.data(), search->second.size()); - for (atUint64 i = search->second.size(); i < sizeOut; ++i) - pakOut.writeUByte(0xff); - - continue; - } - - hecl::ProjectPath path = pathFromTag(tag); - hecl::ProjectPath cooked = getCookedPath(path, true); - athena::io::FileReader r(cooked.getAbsolutePath()); - if (r.hasError()) - Log.report(logvisor::Fatal, FMT_STRING("Unable to open resource {}"), cooked.getRelativePath()); - atUint64 size = r.length(); - auto data = r.readUBytes(size); - auto compData = compressPakData(tag, data.get(), size); - if (compData.first) { - positionOut = pakOut.position(); - sizeOut = ROUND_UP_32(compData.second + 4); - compressedOut = true; - pakOut.writeUint32Big(atUint32(size)); - pakOut.writeUBytes(compData.first.get(), compData.second); - for (atUint64 i = compData.second + 4; i < sizeOut; ++i) - pakOut.writeUByte(0xff); - } else { - positionOut = pakOut.position(); - sizeOut = ROUND_UP_32(size); - compressedOut = false; - pakOut.writeUBytes(data.get(), size); - for (atUint64 i = size; i < sizeOut; ++i) - pakOut.writeUByte(0xff); - } - } - progress.startNewLine(); -} - -static bool IsWorldBlend(const hecl::ProjectPath& path) { - if (path.isFile()) { - auto lastComp = path.getLastComponent(); - return hecl::StringUtils::BeginsWith(lastComp, "!world") && - hecl::StringUtils::EndsWith(lastComp, ".blend"); - } - return false; -} - -void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::DataSpecEntry* entry, bool fast, - hecl::blender::Token& btok, const hecl::MultiProgressPrinter& progress, - hecl::ClientProcess* cp) { - /* Prepare complete resource index */ - if (!m_backgroundRunning && m_tagToPath.empty()) - beginBackgroundIndex(); - waitForIndexComplete(); - - /* Name pak based on root-relative components */ - auto components = path.getWithExtension("", true).getPathComponents(); - if (components.size() <= 1) - return; - hecl::ProjectPath outPath; - if (hecl::ProjectPath(m_project.getProjectWorkingPath(), "out/files/" + components[0]).isDirectory()) - outPath.assign(m_project.getProjectWorkingPath(), - "out/files/" + components[0] + "/" + components[1] + entry->m_pakExt.data()); - else - outPath.assign(m_project.getProjectWorkingPath(), "out/files/" + components[1] + entry->m_pakExt.data()); - outPath.makeDirChain(false); - - /* Output file */ - athena::io::FileWriter pakOut(outPath.getAbsolutePath()); - std::vector buildList; - atUint64 resTableOffset = 0; - std::unordered_map> mlvlData; - - if (IsWorldBlend(path)) /* World PAK */ - { - /* Force-cook MLVL and write resource list structure */ - m_project.cookPath(path, progress, false, true, fast, entry, cp); - if (cp) - cp->waitUntilComplete(); - progress.startNewLine(); - hecl::ProjectPath cooked = getCookedPath(path, true); - buildWorldPakList(path, cooked, btok, pakOut, buildList, resTableOffset, mlvlData); - if (int64_t rem = pakOut.position() % 32) - for (int64_t i = 0; i < 32 - rem; ++i) - pakOut.writeUByte(0xff); - } else if (path.getPathType() == hecl::ProjectPath::Type::Directory) /* General PAK */ - { - /* Build resource list */ - std::unordered_set addedTags; - recursiveBuildResourceList(buildList, addedTags, path, btok); - std::vector> nameList; - - /* Build name list */ - for (const auto& item : buildList) { - auto search = m_catalogTagToNames.find(item); - if (search != m_catalogTagToNames.end()) - for (const auto& name : search->second) - nameList.emplace_back(item, name); - } - - /* Write resource list structure */ - buildPakList(btok, pakOut, buildList, nameList, resTableOffset); - if (int64_t rem = pakOut.position() % 32) - for (int64_t i = 0; i < 32 - rem; ++i) - pakOut.writeUByte(0xff); - } else if (path.getPathType() == hecl::ProjectPath::Type::File) /* One-file General PAK */ - { - /* Build resource list */ - std::vector subPaths; - flattenDependencies(path, subPaths, btok); - std::unordered_set addedTags; - std::vector> nameList; - for (const auto& subPath : subPaths) { - if (metaforce::SObjectTag tag = tagFromPath(subPath)) { - if (addedTags.find(tag) != addedTags.end()) - continue; - addedTags.insert(tag); - buildList.push_back(tag); - } - } - - /* Build name list */ - for (const auto& item : buildList) { - auto search = m_catalogTagToNames.find(item); - if (search != m_catalogTagToNames.end()) - for (const auto& name : search->second) - nameList.emplace_back(item, name); - } - - /* Write resource list structure */ - buildPakList(btok, pakOut, buildList, nameList, resTableOffset); - if (int64_t rem = pakOut.position() % 32) - for (int64_t i = 0; i < 32 - rem; ++i) - pakOut.writeUByte(0xff); - } - - /* Async cook resource list if using ClientProcess */ - if (cp) { - Log.report(logvisor::Info, FMT_STRING("Validating resources")); - progress.setMainIndeterminate(true); - std::vector cookTags; - cookTags.reserve(buildList.size()); - - /* Ensure CMDLs are enqueued first to minimize synchronous dependency cooking */ - for (int i = 0; i < 2; ++i) { - std::unordered_set addedTags; - addedTags.reserve(buildList.size()); - for (auto& tag : buildList) { - if ((i == 0 && tag.type.toUint32() == FOURCC('CMDL')) || (i == 1 && tag.type.toUint32() != FOURCC('CMDL'))) { - if (addedTags.find(tag) != addedTags.end()) - continue; - addedTags.insert(tag); - cookTags.push_back(tag); - } - } - } - - /* Cook ordered tags */ - for (auto& tag : cookTags) { - hecl::ProjectPath depPath = pathFromTag(tag); - if (!depPath) - Log.report(logvisor::Fatal, FMT_STRING("Unable to resolve {}"), tag); - m_project.cookPath(depPath, progress, false, false, fast, entry, cp); - } - progress.setMainIndeterminate(false); - cp->waitUntilComplete(); - progress.startNewLine(); - } - - /* Write resource data and build file index */ - std::vector> fileIndex; - Log.report(logvisor::Info, FMT_STRING("Copying data into {}"), outPath.getRelativePath()); - copyBuildListData(fileIndex, buildList, entry, fast, progress, pakOut, mlvlData); - - /* Write file index */ - writePakFileIndex(pakOut, buildList, fileIndex, resTableOffset); - pakOut.close(); -} - -void SpecBase::interruptCook() { cancelBackgroundIndex(); } - -std::optional SpecBase::compileWorldFromDir(const hecl::ProjectPath& dir, - hecl::blender::Token& btok) const { - hecl::ProjectPath asBlend; - for (const auto& ent : hecl::DirectoryEnumerator(dir.getAbsolutePath())) { - if (hecl::StringUtils::BeginsWith(ent.m_name, "!world")) { - asBlend = hecl::ProjectPath(dir, ent.m_name).getWithExtension(".blend", true); - break; - } - } - if (hecl::IsPathBlend(asBlend)) { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.openBlend(asBlend)) - return {}; - hecl::blender::DataStream ds = conn.beginData(); - return {ds.compileWorld()}; - } - return {}; -} - -hecl::ProjectPath SpecBase::getCookedPath(const hecl::ProjectPath& working, bool pcTarget) const { - const hecl::Database::DataSpecEntry* spec = &getOriginalSpec(); - if (pcTarget) - spec = overrideDataSpec(working, getDataSpecEntry()); - if (!spec) - return {}; - return working.getCookedPath(*spec); -} - -static void PNGErr(png_structp png, png_const_charp msg) { Log.report(logvisor::Error, FMT_STRING("{}"), msg); } - -static void PNGWarn(png_structp png, png_const_charp msg) { Log.report(logvisor::Warning, FMT_STRING("{}"), msg); } - -constexpr uint8_t Convert4To8(uint8_t v) { - /* Swizzle bits: 00001234 -> 12341234 */ - return (v << 4) | v; -} - -void SpecBase::extractRandomStaticEntropy(const uint8_t* buf, const hecl::ProjectPath& pakPath) { - hecl::ProjectPath entropyPath(pakPath, "RandomStaticEntropy.png"); - hecl::ProjectPath catalogPath(pakPath, "!catalog.yaml"); - entropyPath.makeDirChain(false); - - if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), "a")) { - fmt::print(fp.get(), FMT_STRING("RandomStaticEntropy: {}\n"), entropyPath.getRelativePath()); - } - - auto fp = hecl::FopenUnique(entropyPath.getAbsolutePath().data(), "wb"); - if (fp == nullptr) { - Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for writing"), entropyPath.getAbsolutePath()); - return; - } - png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, PNGErr, PNGWarn); - png_init_io(png, fp.get()); - png_infop info = png_create_info_struct(png); - - png_text textStruct = {}; - textStruct.key = png_charp("meta_nomip"); - png_set_text(png, info, &textStruct, 1); - - png_set_IHDR(png, info, 1024, 512, 8, PNG_COLOR_TYPE_GRAY_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - - std::unique_ptr rowbuf(new uint8_t[1024 * 2]); - for (int y = 0; y < 512; ++y) { - for (int x = 0; x < 1024; ++x) { - uint8_t texel = buf[y * 1024 + x]; - rowbuf[x * 2] = Convert4To8(texel >> 4 & 0xf); - rowbuf[x * 2 + 1] = Convert4To8(texel & 0xf); - } - png_write_row(png, rowbuf.get()); - } - - png_write_end(png, info); - png_write_flush(png); - png_destroy_write_struct(&png, &info); -} - -void SpecBase::clearTagCache() { - m_tagToPath.clear(); - m_pathToTag.clear(); - m_catalogNameToTag.clear(); - m_catalogTagToNames.clear(); -} - -hecl::ProjectPath SpecBase::pathFromTag(const metaforce::SObjectTag& tag) const { - std::unique_lock lk(m_backgroundIndexMutex); - auto search = m_tagToPath.find(tag); - if (search != m_tagToPath.cend()) - return search->second; - return {}; -} - -metaforce::SObjectTag SpecBase::tagFromPath(const hecl::ProjectPath& path) const { - auto search = m_pathToTag.find(path.hash()); - if (search != m_pathToTag.cend()) - return search->second; - return buildTagFromPath(path); -} - -bool SpecBase::waitForTagReady(const metaforce::SObjectTag& tag, const hecl::ProjectPath*& pathOut) { - std::unique_lock lk(m_backgroundIndexMutex); - auto search = m_tagToPath.find(tag); - if (search == m_tagToPath.end()) { - if (m_backgroundRunning) { - while (m_backgroundRunning) { - lk.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(2)); - lk.lock(); - search = m_tagToPath.find(tag); - if (search != m_tagToPath.end()) - break; - } - if (search == m_tagToPath.end()) - return false; - } else - return false; - } - lk.unlock(); - pathOut = &search->second; - return true; -} - -const metaforce::SObjectTag* SpecBase::getResourceIdByName(std::string_view name) const { - std::string lower(name); - std::transform(lower.cbegin(), lower.cend(), lower.begin(), tolower); - - std::unique_lock lk(m_backgroundIndexMutex); - auto search = m_catalogNameToTag.find(lower); - if (search == m_catalogNameToTag.end()) { - if (m_backgroundRunning) { - while (m_backgroundRunning) { - lk.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(2)); - lk.lock(); - search = m_catalogNameToTag.find(lower); - if (search != m_catalogNameToTag.end()) - break; - } - if (search == m_catalogNameToTag.end()) - return nullptr; - } else - return nullptr; - } - return &search->second; -} - -FourCC SpecBase::getResourceTypeById(metaforce::CAssetId id) const { - if (!id.IsValid()) - return {}; - - std::unique_lock lk(m_backgroundIndexMutex); - metaforce::SObjectTag searchTag = {metaforce::FourCC(), id}; - auto search = m_tagToPath.find(searchTag); - if (search == m_tagToPath.end()) { - if (m_backgroundRunning) { - while (m_backgroundRunning) { - lk.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(2)); - lk.lock(); - search = m_tagToPath.find(searchTag); - if (search != m_tagToPath.end()) - break; - } - if (search == m_tagToPath.end()) - return {}; - } else - return {}; - } - - return search->first.type.toUint32(); -} - -void SpecBase::enumerateResources(const std::function& lambda) const { - waitForIndexComplete(); - for (const auto& pair : m_tagToPath) { - if (!lambda(pair.first)) - break; - } -} - -void SpecBase::enumerateNamedResources( - const std::function& lambda) const { - waitForIndexComplete(); - for (const auto& pair : m_catalogNameToTag) { - if (!lambda(pair.first, pair.second)) - break; - } -} - -static void WriteTag(athena::io::YAMLDocWriter& cacheWriter, const metaforce::SObjectTag& pathTag, - const hecl::ProjectPath& path) { - auto key = fmt::format(FMT_STRING("{}"), pathTag.id); - if (auto* existing = cacheWriter.getCurNode()->findMapChild(key)) { - existing->m_seqChildren.emplace_back(athena::io::ValToNode(path.getEncodableString())); - } else if (auto v = cacheWriter.enterSubVector(key)) { - cacheWriter.writeString(pathTag.type.toString()); - cacheWriter.writeString(path.getEncodableString()); - } -} - -static void WriteNameTag(athena::io::YAMLDocWriter& nameWriter, const metaforce::SObjectTag& pathTag, - std::string_view name) { - nameWriter.writeString(name.data(), fmt::format(FMT_STRING("{}"), pathTag.id)); -} - -void SpecBase::readCatalog(const hecl::ProjectPath& catalogPath, athena::io::YAMLDocWriter& nameWriter) { - athena::io::FileReader freader(catalogPath.getAbsolutePath()); - if (!freader.isOpen()) - return; - - athena::io::YAMLDocReader reader; - bool res = reader.parse(&freader); - if (!res) - return; - - const athena::io::YAMLNode* root = reader.getRootNode(); - for (const auto& p : root->m_mapChildren) { - /* Hash as lowercase since lookup is case-insensitive */ - std::string pLower = p.first; - std::transform(pLower.cbegin(), pLower.cend(), pLower.begin(), tolower); - - /* Avoid redundant filesystem access for re-caches */ - if (m_catalogNameToTag.find(pLower) != m_catalogNameToTag.cend()) - continue; - - athena::io::YAMLNode& node = *p.second; - hecl::ProjectPath path; - if (node.m_type == YAML_SCALAR_NODE) { - path = hecl::ProjectPath(m_project.getProjectWorkingPath(), node.m_scalarString); - } else if (node.m_type == YAML_SEQUENCE_NODE) { - if (node.m_seqChildren.size() >= 2) - path = hecl::ProjectPath(m_project.getProjectWorkingPath(), node.m_seqChildren[0]->m_scalarString) - .ensureAuxInfo(node.m_seqChildren[1]->m_scalarString); - else if (node.m_seqChildren.size() == 1) - path = hecl::ProjectPath(m_project.getProjectWorkingPath(), node.m_seqChildren[0]->m_scalarString); - } - if (path.isNone()) - continue; - metaforce::SObjectTag pathTag = tagFromPath(path); - if (pathTag) { - std::unique_lock lk(m_backgroundIndexMutex); - m_catalogNameToTag[pLower] = pathTag; - m_catalogTagToNames[pathTag].insert(p.first); - - WriteNameTag(nameWriter, pathTag, p.first); -#if 0 - fmt::print(stderr, FMT_STRING("{} {} {:08X}\n"), p.first, pathTag.type.toString(), pathTag.id.Value()); -#endif - } - } -} - -void SpecBase::backgroundIndexRecursiveCatalogs(const hecl::ProjectPath& dir, athena::io::YAMLDocWriter& nameWriter, - int level) { - hecl::DirectoryEnumerator dEnum(dir.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsThenFilesSorted, false, - false, true); - - /* Enumerate all items */ - for (const hecl::DirectoryEnumerator::Entry& ent : dEnum) { - hecl::ProjectPath path(dir, ent.m_name); - if (ent.m_isDir && level < 1) - backgroundIndexRecursiveCatalogs(path, nameWriter, level + 1); - else { - if (!path.isFile()) - continue; - - /* Read catalog.yaml for .pak directory if exists */ - if (level == 1 && ent.m_name == "!catalog.yaml") { - readCatalog(path, nameWriter); - continue; - } - } - - /* bail if cancelled by client */ - if (!m_backgroundRunning) - break; - } -} - -void SpecBase::insertPathTag(athena::io::YAMLDocWriter& cacheWriter, const metaforce::SObjectTag& tag, - const hecl::ProjectPath& path, bool dump) { -#if 0 - auto search = m_tagToPath.find(tag); - /* ANCS subresources are allowed to be weak-linked */ - if (search != m_tagToPath.end() && search->second != path && - tag.type != FOURCC('CINF') && tag.type != FOURCC('CSKR') && - tag.type != FOURCC('ANIM') && tag.type != FOURCC('EVNT')) { - Log.report(logvisor::Fatal, FMT_STRING("'{}|{}' already exists for tag {} as '{}|{}'"), - path.getRelativePath(), path.getAuxInfo(), tag, - search->second.getRelativePath(), search->second.getAuxInfo()); - } -#endif - m_tagToPath.insert(std::make_pair(tag, path)); - m_pathToTag[path.hash()] = tag; - WriteTag(cacheWriter, tag, path); -#if DUMP_CACHE_FILL - if (dump) - fmt::print(stderr, FMT_STRING("{} {}\n"), tag, path.getRelativePath()); -#endif -} - -bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter) { - /* Avoid redundant filesystem access for re-caches */ - if (m_pathToTag.find(path.hash()) != m_pathToTag.cend()) - return true; - - /* Try as glob */ - hecl::ProjectPath asGlob = path.getWithExtension(".*", true); - if (m_pathToTag.find(asGlob.hash()) != m_pathToTag.cend()) - return true; - - /* Classify intermediate into tag */ - metaforce::SObjectTag pathTag = buildTagFromPath(path); - if (pathTag) { - std::unique_lock lk{m_backgroundIndexMutex}; - bool useGlob = false; - - /* Special multi-resource intermediates */ - if (pathTag.type == SBIG('ANCS')) { - hecl::blender::Connection& conn = m_backgroundBlender.getBlenderConnection(); - if (!conn.openBlend(path) || conn.getBlendType() != hecl::blender::BlendType::Actor) - return false; - - /* Transform tag to glob */ - pathTag = {SBIG('ANCS'), asGlob.parsedHash32()}; - useGlob = true; - - hecl::blender::DataStream ds = conn.beginData(); - std::vector> subtypeNames = ds.getSubtypeNames(); - std::vector> actionNames = ds.getActionNames(); - - for (const auto& sub : subtypeNames) { - hecl::ProjectPath subPath; - if (!sub.second.empty()) { - subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.CSKR"), sub.first, sub.second)); - } else { - subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}.CSKR"), sub.first)); - } - insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath); - - std::vector> overlayNames = ds.getSubtypeOverlayNames(sub.first); - for (const auto& overlay : overlayNames) { - if (!overlay.second.empty()) { - subPath = asGlob.ensureAuxInfo( - fmt::format(FMT_STRING("{}.{}_{}.CSKR"), sub.first, overlay.first, overlay.second)); - } else { - subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}.{}.CSKR"), sub.first, overlay.first)); - } - insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath); - } - } - - std::vector> attachmentNames = ds.getAttachmentNames(); - for (const auto& attachment : attachmentNames) { - hecl::ProjectPath subPath; - if (!attachment.second.empty()) { - subPath = asGlob.ensureAuxInfo( - fmt::format(FMT_STRING("ATTACH.{}_{}.CSKR"), attachment.first, attachment.second)); - } else { - subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("ATTACH.{}.CSKR"), attachment.first)); - } - insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath); - } - - for (const auto& act : actionNames) { - hecl::ProjectPath subPath; - if (!act.second.empty()) { - subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.ANIM"), act.first, act.second)); - } else { - subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}.ANIM"), act.first)); - } - insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath); - } - } - - /* Cache in-memory */ - const hecl::ProjectPath& usePath = useGlob ? asGlob : path; - insertPathTag(cacheWriter, pathTag, usePath); - } - - return true; -} - -void SpecBase::backgroundIndexRecursiveProc(const hecl::ProjectPath& dir, athena::io::YAMLDocWriter& cacheWriter, - athena::io::YAMLDocWriter& nameWriter, int level) { - hecl::DirectoryEnumerator dEnum(dir.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsThenFilesSorted, false, - false, true); - - /* Enumerate all items */ - for (const hecl::DirectoryEnumerator::Entry& ent : dEnum) { - /* bail if cancelled by client */ - if (!m_backgroundRunning) - break; - - hecl::ProjectPath path(dir, ent.m_name); - if (ent.m_isDir) { - /* Index AGSC here */ - if (hecl::ProjectPath(path, "!project.yaml").isFile() && hecl::ProjectPath(path, "!pool.yaml").isFile()) { - /* Avoid redundant filesystem access for re-caches */ - if (m_pathToTag.find(path.hash()) == m_pathToTag.cend()) { - metaforce::SObjectTag pathTag(SBIG('AGSC'), path.parsedHash32()); - insertPathTag(cacheWriter, pathTag, path); - } - } else { - backgroundIndexRecursiveProc(path, cacheWriter, nameWriter, level + 1); - } - } else { - if (!path.isFile()) - continue; - - /* Read catalog.yaml for .pak directory if exists */ - if (level == 1 && ent.m_name == "!catalog.yaml") { - readCatalog(path, nameWriter); - continue; - } - - /* Index the regular file */ - addFileToIndex(path, cacheWriter); - } - } -} - -void SpecBase::backgroundIndexProc() { - logvisor::RegisterThreadName("Resource Index"); - - hecl::ProjectPath tagCachePath(m_project.getProjectCookedPath(getOriginalSpec()), "tag_cache.yaml"); - hecl::ProjectPath nameCachePath(m_project.getProjectCookedPath(getOriginalSpec()), "name_cache.yaml"); - hecl::ProjectPath specRoot(m_project.getProjectWorkingPath(), getOriginalSpec().m_name); - - /* Cache will be overwritten with validated entries afterwards */ - athena::io::YAMLDocWriter cacheWriter; - athena::io::YAMLDocWriter nameWriter; - - /* Read in tag cache */ - if (tagCachePath.isFile()) { - athena::io::FileReader reader(tagCachePath.getAbsolutePath()); - if (reader.isOpen()) { - Log.report(logvisor::Info, FMT_STRING("Cache index of '{}' loading"), getOriginalSpec().m_name); - athena::io::YAMLDocReader cacheReader; - if (cacheReader.parse(&reader)) { - std::unique_lock lk(m_backgroundIndexMutex); - size_t tagCount = cacheReader.getRootNode()->m_mapChildren.size(); - m_tagToPath.reserve(tagCount); - m_pathToTag.reserve(tagCount); - size_t loadIdx = 0; - for (const auto& child : cacheReader.getRootNode()->m_mapChildren) { - if (!m_backgroundRunning) - return; - - const athena::io::YAMLNode& node = *child.second; - if (node.m_seqChildren.size() >= 2) { - unsigned long id = strtoul(child.first.c_str(), nullptr, 16); - metaforce::FourCC type(node.m_seqChildren[0]->m_scalarString.c_str()); - metaforce::SObjectTag pathTag(type, id); - for (auto I = node.m_seqChildren.begin() + 1, E = node.m_seqChildren.end(); I != E; ++I) { - hecl::ProjectPath path(m_project.getProjectWorkingPath(), (*I)->m_scalarString); - if (!path.isNone()) - insertPathTag(cacheWriter, pathTag, path, false); - } - } - - ++loadIdx; - if (!(loadIdx % 100)) - fmt::print(stderr, FMT_STRING("\r {} / {}"), loadIdx, tagCount); - } - fmt::print(stderr, FMT_STRING("\r {} / {}\n"), loadIdx, tagCount); - } - Log.report(logvisor::Info, FMT_STRING("Cache index of '{}' loaded; {} tags"), getOriginalSpec().m_name, - m_tagToPath.size()); - - if (nameCachePath.isFile()) { - /* Read in name cache */ - Log.report(logvisor::Info, FMT_STRING("Name index of '{}' loading"), getOriginalSpec().m_name); - athena::io::FileReader nreader(nameCachePath.getAbsolutePath()); - athena::io::YAMLDocReader nameReader; - if (nameReader.parse(&nreader)) { - std::unique_lock lk(m_backgroundIndexMutex); - m_catalogNameToTag.reserve(nameReader.getRootNode()->m_mapChildren.size()); - m_catalogTagToNames.reserve(nameReader.getRootNode()->m_mapChildren.size()); - for (const auto& child : nameReader.getRootNode()->m_mapChildren) { - unsigned long id = strtoul(child.second->m_scalarString.c_str(), nullptr, 16); - auto search = m_tagToPath.find(metaforce::SObjectTag(metaforce::FourCC(), uint32_t(id))); - if (search != m_tagToPath.cend()) { - std::string chLower = child.first; - std::transform(chLower.cbegin(), chLower.cend(), chLower.begin(), tolower); - m_catalogNameToTag[chLower] = search->first; - m_catalogTagToNames[search->first].insert(child.first); - WriteNameTag(nameWriter, search->first, child.first); - } - } - } - Log.report(logvisor::Info, FMT_STRING("Name index of '{}' loaded; {} names"), - getOriginalSpec().m_name, m_catalogNameToTag.size()); - } - } - } - - Log.report(logvisor::Info, FMT_STRING("Background index of '{}' started"), getOriginalSpec().m_name); - backgroundIndexRecursiveProc(specRoot, cacheWriter, nameWriter, 0); - - tagCachePath.makeDirChain(false); - athena::io::FileWriter twriter(tagCachePath.getAbsolutePath()); - cacheWriter.finish(&twriter); - - athena::io::FileWriter nwriter(nameCachePath.getAbsolutePath()); - nameWriter.finish(&nwriter); - - m_backgroundBlender.shutdown(); - Log.report(logvisor::Info, FMT_STRING("Background index of '{}' complete; {} tags, {} names"), - getOriginalSpec().m_name, m_tagToPath.size(), m_catalogNameToTag.size()); - m_backgroundRunning = false; -} - -void SpecBase::cancelBackgroundIndex() { - m_backgroundRunning = false; - if (m_backgroundIndexTh.joinable()) - m_backgroundIndexTh.join(); -} - -void SpecBase::beginBackgroundIndex() { - cancelBackgroundIndex(); - clearTagCache(); - m_backgroundRunning = true; - m_backgroundIndexTh = std::thread(&SpecBase::backgroundIndexProc, this); -} - -void SpecBase::waitForIndexComplete() const { - std::unique_lock lk(m_backgroundIndexMutex); - while (m_backgroundRunning) { - lk.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(2)); - lk.lock(); - } -} - -void SpecBase::WriteVersionInfo(hecl::Database::Project& project, const hecl::ProjectPath& pakPath) { - hecl::ProjectPath versionPath(pakPath, "version.yaml"); - versionPath.makeDirChain(false); - - MetaforceVersionInfo info; - info.version = m_version; - info.region = m_region; - info.game = m_game; - info.isTrilogy = !m_standalone; - athena::io::FileWriter writer(versionPath.getAbsolutePath()); - athena::io::ToYAMLStream(info, writer); -} -void SpecBase::setCurRegion(ERegion region) { g_CurRegion = region; } -void SpecBase::setCurSpecIsWii(bool isWii) { g_CurSpecIsWii = isWii; } - -} // namespace DataSpec diff --git a/DataSpec/SpecBase.hpp b/DataSpec/SpecBase.hpp deleted file mode 100644 index f7a02763d..000000000 --- a/DataSpec/SpecBase.hpp +++ /dev/null @@ -1,219 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include "hecl/Database.hpp" -#include "hecl/Blender/Token.hpp" -#include "Runtime/RetroTypes.hpp" - -namespace nod { -class DiscBase; -class Node; -} // namespace nod - -namespace athena::io { -class FileWriter; -class YAMLDocWriter; -} // namespace athena::io - -namespace DataSpec { -enum class ERegion; -enum class EGame; -ERegion getCurrentRegion(); -bool isCurrentSpecWii(); - -struct SpecBase : hecl::Database::IDataSpec { - /* HECL Adaptors */ - void setThreadProject() override; - bool canExtract(const ExtractPassInfo& info, std::vector& reps) override; - void doExtract(const ExtractPassInfo& info, const hecl::MultiProgressPrinter& progress) override; - - bool canCook(const hecl::ProjectPath& path, hecl::blender::Token& btok) override; - const hecl::Database::DataSpecEntry* overrideDataSpec(const hecl::ProjectPath& path, - const hecl::Database::DataSpecEntry* oldEntry) const override; - void doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, bool fast, hecl::blender::Token& btok, - FCookProgress progress) override; - - bool canPackage(const hecl::ProjectPath& path) override; - void doPackage(const hecl::ProjectPath& path, const hecl::Database::DataSpecEntry* entry, bool fast, - hecl::blender::Token& btok, const hecl::MultiProgressPrinter& progress, - hecl::ClientProcess* cp) override; - - void interruptCook() override; - - /* Extract handlers */ - virtual bool checkStandaloneID(const char* id) const = 0; - virtual bool checkFromStandaloneDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, - std::vector& reps) = 0; - virtual bool checkFromTrilogyDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, std::vector& reps) = 0; - virtual bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) = 0; - - /* Convert path to object tag */ - virtual metaforce::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const = 0; - - /* Even if PC spec is being cooked, this will return the vanilla GCN spec */ - virtual const hecl::Database::DataSpecEntry& getOriginalSpec() const = 0; - - /* This will return a pseudo-spec for unmodified resources */ - virtual const hecl::Database::DataSpecEntry& getUnmodifiedSpec() const = 0; - - /* Basic path check (game directory matching) */ - virtual bool checkPathPrefix(const hecl::ProjectPath& path) const = 0; - - /* Pre-cook handlers */ - virtual bool validateYAMLDNAType(athena::io::IStreamReader& fp) const = 0; - - std::optional compileWorldFromDir(const hecl::ProjectPath& dir, - hecl::blender::Token& btok) const; - - /* Cook handlers */ - using BlendStream = hecl::blender::DataStream; - using Mesh = hecl::blender::Mesh; - using Armature = hecl::blender::Armature; - using ColMesh = hecl::blender::ColMesh; - using PathMesh = hecl::blender::PathMesh; - using Light = hecl::blender::Light; - using Actor = hecl::blender::Actor; - - virtual void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookColMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookArmature(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookWorld(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) = 0; - virtual void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) = 0; - virtual void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) = 0; - - /* Dependency flatteners */ - void flattenDependencies(const hecl::ProjectPath& in, std::vector& pathsOut, - hecl::blender::Token& btok, int charIdx = -1); - void flattenDependencies(const class UniqueID32& id, std::vector& pathsOut, int charIdx = -1); - void flattenDependencies(const class UniqueID64& id, std::vector& pathsOut, int charIdx = -1); - void flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector& pathsOut, - hecl::blender::Token& btok, int charIdx = -1); - virtual void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector& pathsOut) = 0; - virtual void flattenDependenciesANCSYAML(athena::io::IStreamReader& fin, std::vector& pathsOut, - int charIdx = -1) = 0; - - virtual void buildWorldPakList(const hecl::ProjectPath& worldPath, const hecl::ProjectPath& worldPathCooked, - hecl::blender::Token& btok, athena::io::FileWriter& w, - std::vector& listOut, atUint64& resTableOffset, - std::unordered_map>& mlvlData) {} - virtual void buildPakList(hecl::blender::Token& btok, athena::io::FileWriter& w, - const std::vector& list, - const std::vector>& nameList, - atUint64& resTableOffset) {} - virtual void writePakFileIndex(athena::io::FileWriter& w, const std::vector& tags, - const std::vector>& index, atUint64 resTableOffset) {} - virtual std::pair, size_t> compressPakData(const metaforce::SObjectTag& tag, - const uint8_t* data, size_t len) { - return {}; - } - - const hecl::ProjectPath& getMasterShaderPath() const { return m_masterShader; } - - /* Support functions for resolving paths from IDs */ - virtual hecl::ProjectPath getWorking(class UniqueID32&) { return hecl::ProjectPath(); } - virtual hecl::ProjectPath getWorking(class UniqueID64&) { return hecl::ProjectPath(); } - - hecl::ProjectPath getCookedPath(const hecl::ProjectPath& working, bool pcTarget) const; - - /* Project accessor */ - hecl::Database::Project& getProject() const { return m_project; } - - /* Extract RandomStatic entropy */ - void extractRandomStaticEntropy(const uint8_t* buf, const hecl::ProjectPath& pakPath); - - /* Tag cache functions */ - metaforce::SObjectTag tagFromPath(const hecl::ProjectPath& path) const; - hecl::ProjectPath pathFromTag(const metaforce::SObjectTag& tag) const; - bool waitForTagReady(const metaforce::SObjectTag& tag, const hecl::ProjectPath*& pathOut); - const metaforce::SObjectTag* getResourceIdByName(std::string_view name) const; - hecl::FourCC getResourceTypeById(metaforce::CAssetId id) const; - void enumerateResources(const std::function& lambda) const; - void enumerateNamedResources(const std::function& lambda) const; - void cancelBackgroundIndex(); - void beginBackgroundIndex(); - bool backgroundIndexRunning() const { return m_backgroundRunning; } - void waitForIndexComplete() const; - - virtual void getTagListForFile(const char* pakName, std::vector& out) const {} - - SpecBase(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc); - ~SpecBase(); - -protected: - hecl::Database::Project& m_project; - bool m_pc; - hecl::ProjectPath m_masterShader; - - std::unordered_multimap m_tagToPath; - std::unordered_map m_pathToTag; - std::unordered_map m_catalogNameToTag; - std::unordered_map> m_catalogTagToNames; - void clearTagCache(); - - hecl::blender::Token m_backgroundBlender; - std::thread m_backgroundIndexTh; - mutable std::mutex m_backgroundIndexMutex; - bool m_backgroundRunning = false; - - void readCatalog(const hecl::ProjectPath& catalogPath, athena::io::YAMLDocWriter& nameWriter); - void insertPathTag(athena::io::YAMLDocWriter& cacheWriter, const metaforce::SObjectTag& tag, - const hecl::ProjectPath& path, bool dump = true); - bool addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter); - void backgroundIndexRecursiveProc(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter, - athena::io::YAMLDocWriter& nameWriter, int level); - void backgroundIndexRecursiveCatalogs(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& nameWriter, - int level); - void backgroundIndexProc(); - - void recursiveBuildResourceList(std::vector& listOut, - std::unordered_set& addedTags, const hecl::ProjectPath& path, - hecl::blender::Token& btok); - void copyBuildListData(std::vector>& fileIndex, - const std::vector& buildList, - const hecl::Database::DataSpecEntry* entry, bool fast, - const hecl::MultiProgressPrinter& progress, athena::io::FileWriter& pakOut, - const std::unordered_map>& mlvlData); - - std::unique_ptr m_disc; - bool m_isWii{}; - bool m_standalone{}; - ERegion m_region; - EGame m_game; - std::string m_version; - - void WriteVersionInfo(hecl::Database::Project& project, const hecl::ProjectPath& pakPath); - - static void setCurRegion(ERegion region); - static void setCurSpecIsWii(bool isWii); -}; - -bool IsPathAudioGroup(const hecl::ProjectPath& path); - -} // namespace DataSpec diff --git a/DataSpec/SpecMP1.cpp b/DataSpec/SpecMP1.cpp deleted file mode 100644 index 8fa336584..000000000 --- a/DataSpec/SpecMP1.cpp +++ /dev/null @@ -1,1273 +0,0 @@ -#include -#include -#include - -#include "SpecBase.hpp" -#include "DNAMP1/DNAMP1.hpp" - -#include "DNAMP1/HINT.hpp" -#include "DNAMP1/MLVL.hpp" -#include "DNAMP1/STRG.hpp" -#include "DNAMP1/SCAN.hpp" -#include "DNAMP1/CMDL.hpp" -#include "DNAMP1/DCLN.hpp" -#include "DNAMP1/MREA.hpp" -#include "DNAMP1/ANCS.hpp" -#include "DNAMP1/AGSC.hpp" -#include "DNAMP1/CSNG.hpp" -#include "DNAMP1/MAPA.hpp" -#include "DNAMP1/PATH.hpp" -#include "DNAMP1/FRME.hpp" -#include "DNAMP1/AFSM.hpp" -#include "DNACommon/ATBL.hpp" -#include "DNACommon/FONT.hpp" -#include "DNACommon/PART.hpp" -#include "DNACommon/SWHC.hpp" -#include "DNACommon/ELSC.hpp" -#include "DNACommon/WPSC.hpp" -#include "DNACommon/CRSC.hpp" -#include "DNACommon/DPSC.hpp" -#include "DNACommon/DGRP.hpp" -#include "DNACommon/MAPU.hpp" -#include "DNACommon/MetaforceVersionInfo.hpp" -#include "DNACommon/Tweaks/TweakWriter.hpp" -#include "DNAMP1/Tweaks/CTweakPlayerRes.hpp" -#include "DNAMP1/Tweaks/CTweakGunRes.hpp" -#include "DNAMP1/Tweaks/CTweakSlideShow.hpp" -#include "DNAMP1/Tweaks/CTweakPlayer.hpp" -#include "DNAMP1/Tweaks/CTweakCameraBob.hpp" -#include "DNAMP1/Tweaks/CTweakGame.hpp" -#include "DNAMP1/Tweaks/CTweakTargeting.hpp" -#include "DNAMP1/Tweaks/CTweakAutoMapper.hpp" -#include "DNAMP1/Tweaks/CTweakGui.hpp" -#include "DNAMP1/Tweaks/CTweakPlayerControl.hpp" -#include "DNAMP1/Tweaks/CTweakBall.hpp" -#include "DNAMP1/Tweaks/CTweakParticle.hpp" -#include "DNAMP1/Tweaks/CTweakGuiColors.hpp" -#include "DNAMP1/Tweaks/CTweakPlayerGun.hpp" -#include "DNAMP1/MazeSeeds.hpp" -#include "DNAMP1/SnowForces.hpp" -#include "hecl/ClientProcess.hpp" -#include "hecl/MultiProgressPrinter.hpp" -#include "hecl/Blender/Connection.hpp" -#include "hecl/Blender/SDNARead.hpp" -#include "nod/nod.hpp" -#include -#include - -namespace DataSpec { - -using namespace std::literals; - -static logvisor::Module Log("DataSpec::SpecMP1"); -extern hecl::Database::DataSpecEntry SpecEntMP1; -extern hecl::Database::DataSpecEntry SpecEntMP1PC; -extern hecl::Database::DataSpecEntry SpecEntMP1ORIG; - -struct TextureCache { - static void Generate(PAKRouter& pakRouter, hecl::Database::Project& project, - const hecl::ProjectPath& pakPath) { - hecl::ProjectPath texturePath(pakPath, "texture_cache.yaml"); - hecl::ProjectPath catalogPath(pakPath, "!catalog.yaml"); - texturePath.makeDirChain(false); - - if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), "a")) { - fmt::print(fp.get(), FMT_STRING("TextureCache: {}\n"), texturePath.getRelativePath()); - } - - Log.report(logvisor::Level::Info, FMT_STRING("Gathering Texture metadata (this can take up to 10 seconds)...")); - std::unordered_map metaMap; - - pakRouter.enumerateResources([&](const DNAMP1::PAK::Entry* ent) { - if (ent->type == FOURCC('TXTR') && metaMap.find(ent->id) == metaMap.end()) { - PAKEntryReadStream rs = pakRouter.beginReadStreamForId(ent->id); - metaMap[ent->id] = TXTR::GetMetaData(rs); - } - return true; - }); - - athena::io::YAMLDocWriter yamlW("MP1TextureCache"); - for (const auto& pair : metaMap) { - hecl::ProjectPath path = pakRouter.getWorking(pair.first); - auto rec = yamlW.enterSubRecord(path.getRelativePath()); - pair.second.write(yamlW); - } - - athena::io::FileWriter fileW(texturePath.getAbsolutePath()); - yamlW.finish(&fileW); - Log.report(logvisor::Level::Info, FMT_STRING("Done...")); - } - - static void Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - hecl::Database::Project& project = inPath.getProject(); - athena::io::YAMLDocReader r; - athena::io::FileReader fr(inPath.getAbsolutePath()); - if (!fr.isOpen() || !r.parse(&fr)) - return; - - std::vector> metaPairs; - metaPairs.reserve(r.getRootNode()->m_mapChildren.size()); - for (const auto& node : r.getRootNode()->m_mapChildren) { - hecl::ProjectPath projectPath(project, node.first); - auto rec = r.enterSubRecord(node.first.c_str()); - TXTR::Meta meta; - meta.read(r); - metaPairs.emplace_back(projectPath.parsedHash32(), meta); - } - - std::sort(metaPairs.begin(), metaPairs.end(), - [](const auto& a, const auto& b) -> bool { return a.first < b.first; }); - - athena::io::FileWriter w(outPath.getAbsolutePath()); - w.writeUint32Big(metaPairs.size()); - for (const auto& pair : metaPairs) { - pair.first.write(w); - pair.second.write(w); - } - } -}; - -struct SpecMP1 : SpecBase { - bool checkStandaloneID(const char* id) const override { return !memcmp(id, "GM8", 3); } - - std::vector m_nonPaks; - std::vector m_paks; - std::map m_orderedPaks; - - hecl::ProjectPath m_workPath; - hecl::ProjectPath m_cookPath; - PAKRouter m_pakRouter; - - std::unique_ptr m_dolBuf; - - std::unordered_map m_mreaPathToXF; - - SpecMP1(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc) - : SpecBase(specEntry, project, pc) - , m_workPath(project.getProjectWorkingPath(), "MP1") - , m_cookPath(project.getProjectCookedPath(SpecEntMP1), "MP1") - , m_pakRouter(*this, m_workPath, m_cookPath) { - m_game = EGame::MetroidPrime1; - SpecBase::setThreadProject(); - } - - void buildPaks(nod::Node& root, const std::vector& args, ExtractReport& rep) { - m_nonPaks.clear(); - m_paks.clear(); - for (const nod::Node& child : root) { - bool isPak = false; - auto name = child.getName(); - std::string lowerName(name); - hecl::ToLower(lowerName); - if (name.size() > 4) { - std::string::iterator extit = lowerName.end() - 4; - if (std::string(extit, lowerName.end()) == ".pak") { - /* This is a pak */ - isPak = true; - std::string lowerBase(lowerName.begin(), extit); - - /* Needs filter */ - bool good = true; - if (args.size()) { - good = false; - if (!lowerName.compare(0, 7, "metroid")) { - char idxChar = lowerName[7]; - for (const std::string& arg : args) { - if (arg.size() == 1 && iswdigit(arg[0])) - if (arg[0] == idxChar) - good = true; - } - } else - good = true; - - if (!good) { - for (const std::string& arg : args) { - std::string lowerArg(arg); - hecl::ToLower(lowerArg); - if (!lowerArg.compare(0, lowerBase.size(), lowerBase)) - good = true; - } - } - } - - m_paks.emplace_back(child, good); - } - } - - if (!isPak) - m_nonPaks.push_back(&child); - } - - /* Sort PAKs alphabetically */ - m_orderedPaks.clear(); - for (DNAMP1::PAKBridge& dpak : m_paks) { - m_orderedPaks[std::string(dpak.getName())] = &dpak; - } - - /* Assemble extract report */ - rep.childOpts.reserve(m_orderedPaks.size()); - for (const auto& item : m_orderedPaks) { - if (!item.second->m_doExtract) { - continue; - } - - ExtractReport& childRep = rep.childOpts.emplace_back(); - childRep.name = item.first; - childRep.desc = item.second->getLevelString(); - } - } - - bool checkFromStandaloneDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, std::vector& reps) override { - nod::IPartition* partition = disc.getDataPartition(); - m_dolBuf = partition->getDOLBuf(); - const char* buildInfo = - static_cast(memmem(m_dolBuf.get(), partition->getDOLSize(), "MetroidBuildInfo", 16)) + 19; - - if (buildInfo == nullptr) - return false; - - m_version = std::string(buildInfo); - /* Root Report */ - ExtractReport& rep = reps.emplace_back(); - rep.name = "MP1"; - rep.desc = "Metroid Prime " + regstr; - if (buildInfo) { - rep.desc += " (" + m_version + ")"; - } - - /* Iterate PAKs and build level options */ - nod::Node& root = partition->getFSTRoot(); - buildPaks(root, args, rep); - - return true; - } - - bool checkFromTrilogyDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, std::vector& reps) override { - std::vector mp1args; - bool doExtract = false; - if (args.size()) { - /* Needs filter */ - for (const std::string& arg : args) { - std::string lowerArg = arg; - hecl::ToLower(lowerArg); - if (!lowerArg.compare(0, 3, "mp1")) { - doExtract = true; - mp1args.reserve(args.size()); - size_t slashPos = arg.find('/'); - if (slashPos == std::string::npos) - slashPos = arg.find('\\'); - if (slashPos != std::string::npos) - mp1args.emplace_back(std::string(arg.begin() + slashPos + 1, arg.end())); - } - } - } else - doExtract = true; - - if (!doExtract) - return false; - - nod::IPartition* partition = disc.getDataPartition(); - nod::Node& root = partition->getFSTRoot(); - nod::Node::DirectoryIterator dolIt = root.find("rs5mp1_p.dol"); - if (dolIt == root.end()) { - dolIt = root.find("rs5mp1jpn_p.dol"); - if (dolIt == root.end()) - return false; - } - - m_dolBuf = dolIt->getBuf(); - const char* buildInfo = static_cast(memmem(m_dolBuf.get(), dolIt->size(), "MetroidBuildInfo", 16)) + 19; - - /* Root Report */ - ExtractReport& rep = reps.emplace_back(); - rep.name = "MP1"; - rep.desc = "Metroid Prime " + regstr; - if (buildInfo != nullptr) { - m_version = std::string(buildInfo); - rep.desc += " (" + m_version + ")"; - } - - /* Iterate PAKs and build level options */ - nod::Node::DirectoryIterator mp1It = root.find("MP1"); - if (mp1It == root.end()) { - mp1It = root.find("MP1JPN"); - if (mp1It == root.end()) - return false; - } - buildPaks(*mp1It, mp1args, rep); - - return true; - } - - bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) override { - m_project.enableDataSpecs({"MP1-PC"}); - - nod::ExtractionContext ctx = {force, nullptr}; - - m_workPath.makeDir(); - - progress.startNewLine(); - progress.print("Indexing PAKs", "", 0.0); - m_pakRouter.build(m_paks, - [&progress](float factor) { progress.print("Indexing PAKs", "", factor); }); - progress.print("Indexing PAKs", "", 1.0); - - hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), "out"); - outPath.makeDir(); - disc.getDataPartition()->extractSysFiles(outPath.getAbsolutePath(), ctx); - hecl::ProjectPath mp1OutPath(outPath, "files/MP1"); - mp1OutPath.makeDirChain(true); - - /* Extract non-pak files */ - progress.startNewLine(); - progress.print("MP1 Root", "", 0.0); - int prog = 0; - ctx.progressCB = [&](std::string_view name, float) { - progress.print("MP1 Root", name, prog / (float)m_nonPaks.size()); - }; - for (const nod::Node* node : m_nonPaks) { - node->extractToDirectory(mp1OutPath.getAbsolutePath(), ctx); - prog++; - } - progress.print("MP1 Root", "", 1.0); - - /* Extract unique resources */ - hecl::ClientProcess process; - progress.startNewLine(); - for (std::pair& pair : m_orderedPaks) { -#if 0 - const DNAMP1::PAK::Entry* ent = pair.second->getPAK().lookupEntry(UniqueID32(0xE39FC9A1)); - if (ent) { - PAKEntryReadStream rs = ent->beginReadStream(pair.second->getNode()); - DNAMP1::CMDL::Extract(*this, rs, hecl::ProjectPath(m_project.getProjectWorkingPath(), "MP1/Metroid1/!1IntroLevel1027/CMDL_E39FC9A1.blend"), m_pakRouter, *ent, true, hecl::blender::SharedBlenderToken, {}); - - ent = pair.second->getPAK().lookupEntry(UniqueID32(0xC1AE2B4A)); - rs = ent->beginReadStream(pair.second->getNode()); - DNAMP1::CMDL::Extract(*this, rs, hecl::ProjectPath(m_project.getProjectWorkingPath(), "MP1/Metroid1/!1IntroLevel1027/CMDL_C1AE2B4A.blend"), m_pakRouter, *ent, true, hecl::blender::SharedBlenderToken, {}); - - exit(0); - } - else - continue; -#endif - - DNAMP1::PAKBridge& pak = *pair.second; - if (!pak.m_doExtract) - continue; - - auto pakName = std::string(pak.getName()); - process.addLambdaTransaction([this, &progress, &pak, pakName, force](hecl::blender::Token& btok) { - int threadIdx = hecl::ClientProcess::GetThreadWorkerIdx(); - m_pakRouter.extractResources(pak, force, btok, - [&progress, &pakName, threadIdx](const char* substr, float factor) { - progress.print(pakName, substr, factor, threadIdx); - }); - }); - } - - process.waitUntilComplete(); - - /* Extract part of .dol for RandomStatic entropy */ - hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), "MP1/URDE"); - extractRandomStaticEntropy(m_dolBuf.get() + 0x4f60, noAramPath); - - /* Generate Texture Cache containing meta data for every texture file */ - TextureCache::Generate(m_pakRouter, m_project, noAramPath); - - /* Write version data */ - hecl::ProjectPath versionPath = hecl::ProjectPath(m_project.getProjectWorkingPath(), "out/files/MP1"); - WriteVersionInfo(m_project, versionPath); - return true; - } - - const hecl::Database::DataSpecEntry& getOriginalSpec() const override { return SpecEntMP1; } - - const hecl::Database::DataSpecEntry& getUnmodifiedSpec() const override { return SpecEntMP1ORIG; } - - hecl::ProjectPath getWorking(class UniqueID32& id) override { return m_pakRouter.getWorking(id); } - - bool checkPathPrefix(const hecl::ProjectPath& path) const override { - return path.getRelativePath().compare(0, 4, "MP1/") == 0; - } - - bool validateYAMLDNAType(athena::io::IStreamReader& fp) const override { - athena::io::YAMLDocReader reader; - yaml_parser_set_input(reader.getParser(), (yaml_read_handler_t*)athena::io::YAMLAthenaReader, &fp); - return reader.ClassTypeOperation([](std::string_view classType) { - if (classType == DNAMP1::MLVL::DNAType()) - return true; - else if (classType == DNAMP1::STRG::DNAType()) - return true; - else if (classType == DNAMP1::SCAN::DNAType()) - return true; - else if (classType == DNAParticle::GPSM::DNAType()) - return true; - else if (classType == DNAParticle::SWSH::DNAType()) - return true; - else if (classType == DNAParticle::ELSM::DNAType()) - return true; - else if (classType == DNAParticle::WPSM::DNAType()) - return true; - else if (classType == DNAParticle::CRSM::DNAType()) - return true; - else if (classType == DNAParticle::DPSM::DNAType()) - return true; - else if (classType == DNADGRP::DGRP::DNAType()) - return true; - else if (classType == DNAFont::FONT::DNAType()) - return true; - else if (classType == DNAMP1::CTweakPlayerRes::DNAType()) - return true; - else if (classType == DNAMP1::CTweakPlayerRes::DNAType()) - return true; - else if (classType == DNAMP1::CTweakGunRes::DNAType()) - return true; - else if (classType == DNAMP1::CTweakSlideShow::DNAType()) - return true; - else if (classType == DNAMP1::CTweakPlayer::DNAType()) - return true; - else if (classType == DNAMP1::CTweakCameraBob::DNAType()) - return true; - else if (classType == DNAMP1::CTweakGame::DNAType()) - return true; - else if (classType == DNAMP1::CTweakAutoMapper::DNAType()) - return true; - else if (classType == DNAMP1::CTweakTargeting::DNAType()) - return true; - else if (classType == DNAMP1::CTweakTargeting::DNAType()) - return true; - else if (classType == DNAMP1::CTweakGui::DNAType()) - return true; - else if (classType == DNAMP1::CTweakPlayerControl::DNAType()) - return true; - else if (classType == DNAMP1::CTweakBall::DNAType()) - return true; - else if (classType == DNAMP1::CTweakParticle::DNAType()) - return true; - else if (classType == DNAMP1::CTweakGuiColors::DNAType()) - return true; - else if (classType == DNAMP1::CTweakPlayerGun::DNAType()) - return true; - else if (classType == DNAMP1::HINT::DNAType()) - return true; - else if (classType == DNAMP1::EVNT::DNAType()) - return true; - else if (classType == DNAMP1::MazeSeeds::DNAType()) - return true; - else if (classType == DNAMP1::SnowForces::DNAType()) - return true; - else if (classType == "ATBL") - return true; - else if (classType == DNAMP1::AFSM::DNAType()) - return true; - else if (classType == "MP1TextureCache") - return true; - return false; - }); - } - - metaforce::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const override { - if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".CSKR")) - return {SBIG('CSKR'), path.parsedHash32()}; - else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".ANIM")) - return {SBIG('ANIM'), path.parsedHash32()}; - else if (const char* ext = path.getLastComponentExt().data()) { - if (ext[0] == '*' || !hecl::StrCmp(ext, "mid")) { - if (path.getWithExtension(".mid", true).isFile() && - path.getWithExtension(".yaml", true).isFile()) { - hecl::ProjectPath glob = path.getWithExtension(".*", true); - return {SBIG('CSNG'), glob.parsedHash32()}; - } - } - } - - if (path.getPathType() == hecl::ProjectPath::Type::Directory) { - if (hecl::ProjectPath(path, "!project.yaml").isFile() && - hecl::ProjectPath(path, "!pool.yaml").isFile()) - return {SBIG('AGSC'), path.parsedHash32()}; - } - - hecl::ProjectPath asBlend; - if (path.getPathType() == hecl::ProjectPath::Type::Glob) - asBlend = path.getWithExtension(".blend", true); - else - asBlend = path; - - if (hecl::IsPathBlend(asBlend)) { - switch (hecl::blender::GetBlendType(asBlend.getAbsolutePath())) { - case hecl::blender::BlendType::Mesh: - return {SBIG('CMDL'), path.parsedHash32()}; - case hecl::blender::BlendType::ColMesh: - return {SBIG('DCLN'), path.parsedHash32()}; - case hecl::blender::BlendType::Armature: - return {SBIG('CINF'), path.parsedHash32()}; - case hecl::blender::BlendType::PathMesh: - return {SBIG('PATH'), path.parsedHash32()}; - case hecl::blender::BlendType::Actor: - if (path.getAuxInfo().size()) { - if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".CSKR")) - return {SBIG('CSKR'), path.getWithExtension(".*", true).parsedHash32()}; - else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".ANIM")) - return {SBIG('ANIM'), path.getWithExtension(".*", true).parsedHash32()}; - } - return {SBIG('ANCS'), path.getWithExtension(".*", true).parsedHash32()}; - case hecl::blender::BlendType::Area: - return {SBIG('MREA'), path.parsedHash32()}; - case hecl::blender::BlendType::World: - return {SBIG('MLVL'), path.getWithExtension(".*", true).parsedHash32()}; - case hecl::blender::BlendType::MapArea: - return {SBIG('MAPA'), path.parsedHash32()}; - case hecl::blender::BlendType::MapUniverse: - return {SBIG('MAPU'), path.parsedHash32()}; - case hecl::blender::BlendType::Frame: - return {SBIG('FRME'), path.parsedHash32()}; - default: - return {}; - } - } else if (hecl::IsPathPNG(path)) { - return {SBIG('TXTR'), path.parsedHash32()}; - } else if (hecl::IsPathYAML(path)) { - auto fp = hecl::FopenUnique(path.getAbsolutePath().data(), "r"); - if (fp == nullptr) { - return {}; - } - - athena::io::YAMLDocReader reader; - yaml_parser_set_input_file(reader.getParser(), fp.get()); - - metaforce::SObjectTag resTag; - if (reader.ClassTypeOperation([&](std::string_view className) { - if (className == DNAParticle::GPSM::DNAType()) { - resTag.type = SBIG('PART'); - return true; - } - if (className == DNAParticle::SWSH::DNAType()) { - resTag.type = SBIG('SWHC'); - return true; - } - if (className == DNAParticle::ELSM::DNAType()) { - resTag.type = SBIG('ELSC'); - return true; - } - if (className == DNAParticle::WPSM::DNAType()) { - resTag.type = SBIG('WPSC'); - return true; - } - if (className == DNAParticle::CRSM::DNAType()) { - resTag.type = SBIG('CRSC'); - return true; - } - if (className == DNAParticle::DPSM::DNAType()) { - resTag.type = SBIG('DPSC'); - return true; - } else if (className == DNAFont::FONT::DNAType()) { - resTag.type = SBIG('FONT'); - return true; - } else if (className == DNAMP1::EVNT::DNAType()) { - resTag.type = SBIG('EVNT'); - return true; - } else if (className == DNADGRP::DGRP::DNAType()) { - resTag.type = SBIG('DGRP'); - return true; - } else if (className == DataSpec::DNAMP1::STRG::DNAType()) { - resTag.type = SBIG('STRG'); - return true; - } else if (className == DataSpec::DNAMP1::SCAN::DNAType()) { - resTag.type = SBIG('SCAN'); - return true; - } else if (className == DataSpec::DNAMP1::CTweakPlayerRes::DNAType() || - className == DataSpec::DNAMP1::CTweakPlayerRes::DNAType() || - className == DataSpec::DNAMP1::CTweakGunRes::DNAType() || - className == DataSpec::DNAMP1::CTweakSlideShow::DNAType() || - className == DataSpec::DNAMP1::CTweakPlayer::DNAType() || - className == DataSpec::DNAMP1::CTweakCameraBob::DNAType() || - className == DataSpec::DNAMP1::CTweakGame::DNAType() || - className == DataSpec::DNAMP1::CTweakTargeting::DNAType() || - className == DataSpec::DNAMP1::CTweakTargeting::DNAType() || - className == DataSpec::DNAMP1::CTweakAutoMapper::DNAType() || - className == DataSpec::DNAMP1::CTweakGui::DNAType() || - className == DataSpec::DNAMP1::CTweakPlayerControl::DNAType() || - className == DataSpec::DNAMP1::CTweakBall::DNAType() || - className == DataSpec::DNAMP1::CTweakParticle::DNAType() || - className == DataSpec::DNAMP1::CTweakGuiColors::DNAType() || - className == DataSpec::DNAMP1::CTweakPlayerGun::DNAType()) { - resTag.type = SBIG('CTWK'); - return true; - } else if (className == DataSpec::DNAMP1::MazeSeeds::DNAType() || - className == DataSpec::DNAMP1::SnowForces::DNAType()) { - resTag.type = SBIG('DUMB'); - return true; - } else if (className == DataSpec::DNAMP1::HINT::DNAType()) { - resTag.type = SBIG('HINT'); - return true; - } else if (className == "ATBL") { - resTag.type = SBIG('ATBL'); - return true; - } else if (className == DataSpec::DNAMP1::AFSM::DNAType()) { - resTag.type = SBIG('AFSM'); - return true; - } else if (className == "MP1TextureCache") { - resTag.type = SBIG('TMET'); - return true; - } else if (className == "DataSpec::DNAMP1::SAVW") { - resTag.type = SBIG('SAVW'); - return true; - } else if (className == "DataSpec::DNAMP1::MAPW") { - resTag.type = SBIG('MAPW'); - return true; - } - - return false; - })) { - resTag.id = path.parsedHash32(); - fp.reset(); - return resTag; - } - } - return {}; - } - - void getTagListForFile(const char* pakName, std::vector& out) const override { - std::string pathPrefix("MP1/"); - pathPrefix += pakName; - pathPrefix += '/'; - - std::unique_lock lk(m_backgroundIndexMutex); - for (const auto& tag : m_tagToPath) - if (!tag.second.getRelativePath().compare(0, pathPrefix.size(), pathPrefix)) - out.push_back(tag.first); - } - - void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - Mesh mesh = ds.compileMesh(fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, m_pc ? 16 : -1); - - if (m_pc) - DNAMP1::CMDL::HMDLCook(out, in, mesh); - else - DNAMP1::CMDL::Cook(out, in, mesh); - } - - void cookColMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - std::vector mesh = ds.compileColMeshes(); - ds.close(); - DNAMP1::DCLN::Cook(out, mesh); - } - - void cookArmature(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - Armature armature = ds.compileArmature(); - ds.close(); - DNAMP1::CINF::Cook(out, in, armature); - } - - void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - PathMesh mesh = ds.compilePathMesh(); - ds.close(); - DNAMP1::PATH::Cook(out, in, mesh, btok); - } - - void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - if (hecl::StringUtils::EndsWith(in.getAuxInfo(), ".CSKR")) { - Actor actor = ds.compileActorCharacterOnly(); - ds.close(); - if (m_pc) { - DNAMP1::ANCS::CookCSKRPC(out, in, actor, [&](const hecl::ProjectPath& modelPath) { - hecl::ProjectPath cooked = modelPath.getCookedPath(SpecEntMP1PC); - doCook(modelPath, cooked, fast, btok, progress); - return true; - }); - } else { - DNAMP1::ANCS::CookCSKR(out, in, actor, [&](const hecl::ProjectPath& modelPath) { - hecl::ProjectPath cooked = modelPath.getCookedPath(SpecEntMP1); - doCook(modelPath, cooked, fast, btok, progress); - return true; - }); - } - } else if (hecl::StringUtils::EndsWith(in.getAuxInfo(), ".ANIM")) { - Actor actor = ds.compileActorCharacterOnly(); - DNAMP1::ANCS::CookANIM(out, in, actor, ds, m_pc); - } else { - Actor actor = ds.compileActor(); - DNAMP1::ANCS::Cook(out, in, actor); - } - } - - void buildAreaXFs(hecl::blender::Token& btok) { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - for (const auto& ent : m_workPath.enumerateDir()) { - if (ent.m_isDir) { - hecl::ProjectPath pakPath(m_workPath, ent.m_name); - for (const auto& ent2 : pakPath.enumerateDir()) { - if (ent2.m_isDir) { - hecl::ProjectPath wldDir(pakPath, ent2.m_name); - for (const auto& ent3 : wldDir.enumerateDir()) { - if (hecl::StringUtils::BeginsWith(ent3.m_name, "!world") && - hecl::StringUtils::EndsWith(ent3.m_name, ".blend")) { - hecl::ProjectPath wldPath(wldDir, ent3.m_name); - if (wldPath.isFile()) { - if (!conn.openBlend(wldPath)) - continue; - hecl::blender::DataStream ds = conn.beginData(); - hecl::blender::World world = ds.compileWorld(); - for (const auto& area : world.areas) - m_mreaPathToXF[area.path.hash()] = area.transform; - } - break; - } - } - } - } - } - } - } - - void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - std::vector meshes = ds.getMeshList(); - std::vector meshCompiles; - meshCompiles.reserve(meshes.size()); - - std::optional colMesh; - - for (const std::string& mesh : meshes) { - if (mesh == "CMESH") { - colMesh = ds.compileColMesh(mesh); - progress("Collision Mesh"); - continue; - } - meshCompiles.push_back( - ds.compileMesh(mesh, fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, -1, !m_pc)); - } - - if (!colMesh) - Log.report(logvisor::Fatal, FMT_STRING("unable to find mesh named 'CMESH' in {}"), - in.getAbsolutePath()); - - std::vector lights = ds.compileLights(); - - ds.close(); - - if (m_mreaPathToXF.empty()) - buildAreaXFs(btok); - - const hecl::blender::Matrix4f* xf = nullptr; - auto xfSearch = m_mreaPathToXF.find(in.getParentPath().hash()); - if (xfSearch != m_mreaPathToXF.cend()) - xf = &xfSearch->second; - DNAMP1::MREA::Cook(out, in, meshCompiles, *colMesh, lights, btok, xf, m_pc); - } - - void cookWorld(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - hecl::blender::World world = ds.compileWorld(); - ds.close(); - DNAMP1::MLVL::Cook(out, in, world, btok); - } - - void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override { - auto data = ds.compileGuiFrame(0); - athena::io::MemoryReader r(data.data(), data.size()); - DNAMP1::FRME frme; - frme.read(r); - athena::io::FileWriter w(out.getAbsolutePath()); - frme.write(w); - } - - void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin, - hecl::blender::Token& btok, FCookProgress progress) override { - athena::io::YAMLDocReader reader; - if (reader.parse(&fin)) { - std::string classStr = reader.readString("DNAType"); - if (classStr.empty()) - return; - - if (classStr == DNAMP1::STRG::DNAType()) { - DNAMP1::STRG strg; - strg.read(reader); - DNAMP1::STRG::Cook(strg, out); - } else if (classStr == DNAMP1::SCAN::DNAType()) { - DNAMP1::SCAN scan; - scan.read(reader); - DNAMP1::SCAN::Cook(scan, out); - } else if (classStr == DNAParticle::GPSM::DNAType()) { - DNAParticle::GPSM gpsm; - gpsm.read(reader); - DNAParticle::WriteGPSM(gpsm, out); - } else if (classStr == DNAParticle::SWSH::DNAType()) { - DNAParticle::SWSH swsh; - swsh.read(reader); - DNAParticle::WriteSWSH(swsh, out); - } else if (classStr == DNAParticle::ELSM::DNAType()) { - DNAParticle::ELSM elsm; - elsm.read(reader); - DNAParticle::WriteELSM(elsm, out); - } else if (classStr == DNAParticle::WPSM::DNAType()) { - DNAParticle::WPSM wpsm; - wpsm.read(reader); - DNAParticle::WriteWPSM(wpsm, out); - } else if (classStr == DNAParticle::CRSM::DNAType()) { - DNAParticle::CRSM crsm; - crsm.read(reader); - DNAParticle::WriteCRSM(crsm, out); - } else if (classStr == DNAParticle::DPSM::DNAType()) { - DNAParticle::DPSM dpsm; - dpsm.read(reader); - DNAParticle::WriteDPSM(dpsm, out); - } else if (classStr == DNADGRP::DGRP::DNAType()) { - DNADGRP::DGRP dgrp; - dgrp.read(reader); - dgrp.validateDeps(); - DNADGRP::WriteDGRP(dgrp, out); - } else if (classStr == DNAFont::FONT::DNAType()) { - DNAFont::FONT font; - font.read(reader); - DNAFont::WriteFONT(font, out); - } else if (classStr == DNAMP1::CTweakPlayerRes::DNAType()) { - DNAMP1::CTweakPlayerRes playerRes; - playerRes.read(reader); - WriteTweak(playerRes, out); - } else if (classStr == DNAMP1::CTweakPlayerRes::DNAType()) { - DNAMP1::CTweakPlayerRes playerRes; - playerRes.read(reader); - WriteTweak(playerRes, out); - } else if (classStr == DNAMP1::CTweakGunRes::DNAType()) { - DNAMP1::CTweakGunRes gunRes; - gunRes.read(reader); - WriteTweak(gunRes, out); - } else if (classStr == DNAMP1::CTweakSlideShow::DNAType()) { - DNAMP1::CTweakSlideShow slideShow; - slideShow.read(reader); - WriteTweak(slideShow, out); - } else if (classStr == DNAMP1::CTweakPlayer::DNAType()) { - DNAMP1::CTweakPlayer player; - player.read(reader); - WriteTweak(player, out); - } else if (classStr == DNAMP1::CTweakCameraBob::DNAType()) { - DNAMP1::CTweakCameraBob cBob; - cBob.read(reader); - WriteTweak(cBob, out); - } else if (classStr == DNAMP1::CTweakGame::DNAType()) { - DNAMP1::CTweakGame cGame; - cGame.read(reader); - WriteTweak(cGame, out); - } else if (classStr == DNAMP1::CTweakAutoMapper::DNAType()) { - DNAMP1::CTweakAutoMapper autoMapper; - autoMapper.read(reader); - WriteTweak(autoMapper, out); - } else if (classStr == DNAMP1::CTweakTargeting::DNAType()) { - DNAMP1::CTweakTargeting targeting; - targeting.read(reader); - WriteTweak(targeting, out); - } else if (classStr == DNAMP1::CTweakTargeting::DNAType()) { - DNAMP1::CTweakTargeting targeting; - targeting.read(reader); - WriteTweak(targeting, out); - } else if (classStr == DNAMP1::CTweakGui::DNAType()) { - DNAMP1::CTweakGui gui; - gui.read(reader); - WriteTweak(gui, out); - } else if (classStr == DNAMP1::CTweakPlayerControl::DNAType()) { - DNAMP1::CTweakPlayerControl pc; - pc.read(reader); - WriteTweak(pc, out); - } else if (classStr == DNAMP1::CTweakBall::DNAType()) { - DNAMP1::CTweakBall ball; - ball.read(reader); - WriteTweak(ball, out); - } else if (classStr == DNAMP1::CTweakParticle::DNAType()) { - DNAMP1::CTweakParticle part; - part.read(reader); - WriteTweak(part, out); - } else if (classStr == DNAMP1::CTweakGuiColors::DNAType()) { - DNAMP1::CTweakGuiColors gColors; - gColors.read(reader); - WriteTweak(gColors, out); - } else if (classStr == DNAMP1::CTweakPlayerGun::DNAType()) { - DNAMP1::CTweakPlayerGun pGun; - pGun.read(reader); - WriteTweak(pGun, out); - } else if (classStr == DNAMP1::CTweakPlayerControl::DNAType()) { - DNAMP1::CTweakPlayerControl pControl; - pControl.read(reader); - WriteTweak(pControl, out); - } else if (classStr == DNAMP1::MazeSeeds::DNAType()) { - DNAMP1::MazeSeeds mSeeds; - mSeeds.read(reader); - WriteTweak(mSeeds, out); - } else if (classStr == DNAMP1::SnowForces::DNAType()) { - DNAMP1::SnowForces sForces; - sForces.read(reader); - WriteTweak(sForces, out); - } else if (classStr == DNAMP1::HINT::DNAType()) { - DNAMP1::HINT::Cook(in, out); - } else if (classStr == DNAMP1::EVNT::DNAType()) { - DNAMP1::EVNT::Cook(in, out); - } else if (classStr == "ATBL") { - DNAAudio::ATBL::Cook(in, out); - } else if (classStr == DNAMP1::AFSM::DNAType()) { - DNAMP1::AFSM::Cook(in, out); - } else if (classStr == "MP1TextureCache") { - TextureCache::Cook(in, out); - } - } - progress("Done"); - } - - void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector& pathsOut) override { - athena::io::YAMLDocReader reader; - if (reader.parse(&fin)) { - std::string classStr = reader.readString("DNAType"sv); - if (classStr.empty()) - return; - - if (classStr == DNAMP1::STRG::DNAType()) { - DNAMP1::STRG strg; - strg.read(reader); - strg.gatherDependencies(pathsOut); - } - if (classStr == DNAMP1::SCAN::DNAType()) { - DNAMP1::SCAN scan; - scan.read(reader); - scan.gatherDependencies(pathsOut); - } else if (classStr == DNAParticle::GPSM::DNAType()) { - DNAParticle::GPSM gpsm; - gpsm.read(reader); - gpsm.gatherDependencies(pathsOut); - } else if (classStr == DNAParticle::SWSH::DNAType()) { - DNAParticle::SWSH swsh; - swsh.read(reader); - swsh.gatherDependencies(pathsOut); - } else if (classStr == DNAParticle::ELSM::DNAType()) { - DNAParticle::ELSM elsm; - elsm.read(reader); - elsm.gatherDependencies(pathsOut); - } else if (classStr == DNAParticle::WPSM::DNAType()) { - DNAParticle::WPSM wpsm; - wpsm.read(reader); - wpsm.gatherDependencies(pathsOut); - } else if (classStr == DNAParticle::CRSM::DNAType()) { - DNAParticle::CRSM crsm; - crsm.read(reader); - crsm.gatherDependencies(pathsOut); - } else if (classStr == DNAParticle::DPSM::DNAType()) { - DNAParticle::DPSM dpsm; - dpsm.read(reader); - dpsm.gatherDependencies(pathsOut); - } else if (classStr == DNAFont::FONT::DNAType()) { - DNAFont::FONT font; - font.read(reader); - font.gatherDependencies(pathsOut); - } else if (classStr == DNAMP1::EVNT::DNAType()) { - DNAMP1::EVNT evnt; - evnt.read(reader); - evnt.gatherDependencies(pathsOut); - } - } - } - - void flattenDependenciesANCSYAML(athena::io::IStreamReader& fin, std::vector& pathsOut, - int charIdx) override { - athena::io::YAMLDocReader reader; - if (reader.parse(&fin)) { - std::string classStr = reader.readString("DNAType"); - if (classStr == DNAMP1::ANCS::DNAType()) { - DNAMP1::ANCS ancs; - ancs.read(reader); - ancs.gatherDependencies(pathsOut, charIdx); - } - } - } - - void buildWorldPakList(const hecl::ProjectPath& worldPath, const hecl::ProjectPath& worldPathCooked, - hecl::blender::Token& btok, athena::io::FileWriter& w, - std::vector& listOut, atUint64& resTableOffset, - std::unordered_map>& mlvlData) override { - DNAMP1::MLVL mlvl; - { - athena::io::FileReader r(worldPathCooked.getAbsolutePath()); - if (r.hasError()) - Log.report(logvisor::Fatal, FMT_STRING("Unable to open world {}"), worldPathCooked.getRelativePath()); - mlvl.read(r); - } - - size_t count = 5; - for (const auto& area : mlvl.areas) { - auto lazyIt = area.lazyDeps.cbegin(); - auto it = area.deps.cbegin(); - while (it != area.deps.cend()) { - if (it->id != lazyIt->id) - ++count; - ++lazyIt; - ++it; - } - } - listOut.reserve(count); - - metaforce::SObjectTag worldTag = tagFromPath(worldPath.getWithExtension(".*", true)); - - w.writeUint32Big(m_pc ? 0x80030005 : 0x00030005); - w.writeUint32Big(0); - - w.writeUint32Big(1); - DNAMP1::PAK::NameEntry nameEnt; - hecl::ProjectPath parentDir = worldPath.getParentPath(); - nameEnt.type = worldTag.type.toUint32(); - nameEnt.id = worldTag.id.Value(); - nameEnt.nameLen = atUint32(parentDir.getLastComponent().size()); - nameEnt.name = parentDir.getLastComponent(); - nameEnt.write(w); - - std::unordered_set addedTags; - for (auto& area : mlvl.areas) { - metaforce::SObjectTag areaTag(metaforce::FOURCC('MREA'), area.areaMREAId.toUint64()); - - bool dupeRes = false; - if (hecl::ProjectPath areaDir = pathFromTag(areaTag).getParentPath()) - dupeRes = hecl::ProjectPath(areaDir, "!duperes").isFile(); - - metaforce::SObjectTag nameTag(metaforce::FOURCC('STRG'), area.areaNameId.toUint64()); - if (nameTag) - listOut.push_back(nameTag); - for (const auto& dep : area.deps) { - metaforce::CAssetId newId = dep.id.toUint64(); - if (dupeRes || addedTags.find(newId) == addedTags.end()) { - listOut.emplace_back(dep.type.toUint32(), newId); - addedTags.insert(newId); - } - } - if (areaTag) - listOut.push_back(areaTag); - - std::vector strippedDeps; - strippedDeps.reserve(area.deps.size()); - std::vector strippedDepLayers; - strippedDepLayers.reserve(area.depLayers.size()); - auto lazyIt = area.lazyDeps.cbegin(); - auto it = area.deps.cbegin(); - auto layerIt = area.depLayers.cbegin(); - while (it != area.deps.cend()) { - while (layerIt != area.depLayers.cend() && it - area.deps.cbegin() == *layerIt) { - strippedDepLayers.push_back(atUint32(strippedDeps.size())); - ++layerIt; - } - if (it->id != lazyIt->id) - strippedDeps.push_back(*it); - ++lazyIt; - ++it; - } - - area.lazyDepCount = 0; - area.lazyDeps.clear(); - area.depCount = strippedDeps.size(); - area.deps = std::move(strippedDeps); - area.depLayerCount = strippedDepLayers.size(); - area.depLayers = std::move(strippedDepLayers); - } - - metaforce::SObjectTag nameTag(metaforce::FOURCC('STRG'), mlvl.worldNameId.toUint64()); - if (nameTag) - listOut.push_back(nameTag); - - metaforce::SObjectTag savwTag(metaforce::FOURCC('SAVW'), mlvl.saveWorldId.toUint64()); - if (savwTag) { - if (hecl::ProjectPath savwPath = pathFromTag(savwTag)) - m_project.cookPath(savwPath, {}, false, true); - listOut.push_back(savwTag); - } - - metaforce::SObjectTag mapTag(metaforce::FOURCC('MAPW'), mlvl.worldMap.toUint64()); - if (mapTag) { - if (hecl::ProjectPath mapPath = pathFromTag(mapTag)) { - m_project.cookPath(mapPath, {}, false, true); - if (hecl::ProjectPath mapCookedPath = getCookedPath(mapPath, true)) { - athena::io::FileReader r(mapCookedPath.getAbsolutePath()); - if (r.hasError()) - Log.report(logvisor::Fatal, FMT_STRING("Unable to open {}"), mapCookedPath.getRelativePath()); - - if (r.readUint32Big() != 0xDEADF00D) - Log.report(logvisor::Fatal, FMT_STRING("Corrupt MAPW {}"), mapCookedPath.getRelativePath()); - r.readUint32Big(); - atUint32 mapaCount = r.readUint32Big(); - for (atUint32 i = 0; i < mapaCount; ++i) { - UniqueID32 id; - id.read(r); - listOut.emplace_back(metaforce::FOURCC('MAPA'), id.toUint64()); - } - } - } - listOut.push_back(mapTag); - } - - metaforce::SObjectTag skyboxTag(metaforce::FOURCC('CMDL'), mlvl.worldSkyboxId.toUint64()); - if (skyboxTag) { - listOut.push_back(skyboxTag); - hecl::ProjectPath skyboxPath = pathFromTag(skyboxTag); - if (btok.getBlenderConnection().openBlend(skyboxPath)) { - auto data = btok.getBlenderConnection().beginData(); - std::vector textures = data.getTextures(); - for (const auto& tex : textures) { - metaforce::SObjectTag texTag = tagFromPath(tex); - if (!texTag) - Log.report(logvisor::Fatal, FMT_STRING("Unable to resolve {}"), tex.getRelativePath()); - listOut.push_back(texTag); - } - } - } - - listOut.push_back(worldTag); - - w.writeUint32Big(atUint32(listOut.size())); - resTableOffset = w.position(); - for (const auto& item : listOut) { - DNAMP1::PAK::Entry ent; - ent.compressed = 0; - ent.type = item.type.toUint32(); - ent.id = item.id.Value(); - ent.size = 0; - ent.offset = 0; - ent.write(w); - } - - { - std::vector& mlvlOut = mlvlData[worldTag.id]; - size_t mlvlSize = 0; - mlvl.binarySize(mlvlSize); - mlvlOut.resize(mlvlSize); - athena::io::MemoryWriter mw(&mlvlOut[0], mlvlSize); - mlvl.write(mw); - } - } - - void buildPakList(hecl::blender::Token& btok, athena::io::FileWriter& w, - const std::vector& list, - const std::vector>& nameList, - atUint64& resTableOffset) override { - w.writeUint32Big(m_pc ? 0x80030005 : 0x00030005); - w.writeUint32Big(0); - - w.writeUint32Big(atUint32(nameList.size())); - for (const auto& item : nameList) { - DNAMP1::PAK::NameEntry nameEnt; - nameEnt.type = item.first.type.toUint32(); - nameEnt.id = item.first.id.Value(); - nameEnt.nameLen = atUint32(item.second.size()); - nameEnt.name = item.second; - nameEnt.write(w); - } - - w.writeUint32Big(atUint32(list.size())); - resTableOffset = w.position(); - for (const auto& item : list) { - DNAMP1::PAK::Entry ent; - ent.compressed = 0; - ent.type = item.type.toUint32(); - ent.id = item.id.Value(); - ent.size = 0; - ent.offset = 0; - ent.write(w); - } - } - - void writePakFileIndex(athena::io::FileWriter& w, const std::vector& tags, - const std::vector>& index, atUint64 resTableOffset) override { - w.seek(resTableOffset, athena::SeekOrigin::Begin); - - auto it = tags.begin(); - for (const auto& item : index) { - const metaforce::SObjectTag& tag = *it++; - DNAMP1::PAK::Entry ent; - ent.compressed = atUint32(std::get<2>(item)); - ent.type = tag.type.toUint32(); - ent.id = tag.id.Value(); - ent.size = atUint32(std::get<1>(item)); - ent.offset = atUint32(std::get<0>(item)); - ent.write(w); - } - } - - std::pair, size_t> compressPakData(const metaforce::SObjectTag& tag, const uint8_t* data, - size_t len) override { - bool doCompress = false; - switch (tag.type.toUint32()) { - case SBIG('TXTR'): - case SBIG('CMDL'): - case SBIG('CSKR'): - case SBIG('ANCS'): - case SBIG('ANIM'): - case SBIG('FONT'): - doCompress = true; - break; - case SBIG('PART'): - case SBIG('ELSC'): - case SBIG('SWHC'): - case SBIG('WPSC'): - case SBIG('DPSC'): - case SBIG('CRSC'): - doCompress = len >= 0x400; - break; - default: - break; - } - if (!doCompress) - return {}; - - uLong destLen = compressBound(len); - std::pair, size_t> ret; - ret.first.reset(new uint8_t[destLen]); - compress2(ret.first.get(), &destLen, data, len, Z_BEST_COMPRESSION); - ret.second = destLen; - return ret; - }; - - void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override { - DNAMP1::AGSC::Cook(in, out); - progress("Done"); - } - - void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override { - DNAMP1::CSNG::Cook(in, out); - progress("Done"); - } - - void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override { - hecl::blender::MapArea mapa = ds.compileMapArea(); - ds.close(); - DNAMP1::MAPA::Cook(mapa, out); - progress("Done"); - } - - void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override { - hecl::blender::MapUniverse mapu = ds.compileMapUniverse(); - ds.close(); - DNAMAPU::MAPU::Cook(mapu, out); - progress("Done"); - } -}; - -hecl::Database::DataSpecEntry SpecEntMP1 = { - "MP1"sv, "Data specification for original Metroid Prime engine"sv, ".pak"sv, - [](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr { - return std::make_unique(&SpecEntMP1, project, false); - }}; - -hecl::Database::DataSpecEntry SpecEntMP1PC = { - "MP1-PC"sv, "Data specification for PC-optimized Metroid Prime engine"sv, ".upak"sv, - [](hecl::Database::Project& project, - hecl::Database::DataSpecTool tool) -> std::unique_ptr { - if (tool != hecl::Database::DataSpecTool::Extract) - return std::make_unique(&SpecEntMP1PC, project, true); - return {}; - }}; - -hecl::Database::DataSpecEntry SpecEntMP1ORIG = { - "MP1-ORIG"sv, "Data specification for unmodified Metroid Prime resources"sv, {}, {}}; -} // namespace DataSpec diff --git a/DataSpec/SpecMP2.cpp b/DataSpec/SpecMP2.cpp deleted file mode 100644 index 94438362c..000000000 --- a/DataSpec/SpecMP2.cpp +++ /dev/null @@ -1,430 +0,0 @@ -#include - -#include "SpecBase.hpp" -#include "DNAMP2/DNAMP2.hpp" - -#include "DNAMP2/MLVL.hpp" -#include "DNAMP2/STRG.hpp" -#include "DNAMP2/AGSC.hpp" -#include "DNAMP2/PATH.hpp" -#include "DNAMP2/MAPA.hpp" -#include "DNAMP1/CSNG.hpp" -#include "DNACommon/MAPU.hpp" -#include "DNACommon/PATH.hpp" -#include "DNACommon/TXTR.hpp" -#include "DNACommon/MetaforceVersionInfo.hpp" - -#include "hecl/ClientProcess.hpp" -#include "hecl/Blender/Connection.hpp" -#include "hecl/MultiProgressPrinter.hpp" - -#include "Runtime/RetroTypes.hpp" -#include "nod/nod.hpp" - -namespace DataSpec { - -using namespace std::literals; - -static logvisor::Module Log("DataSpec::SpecMP2"); -extern hecl::Database::DataSpecEntry SpecEntMP2; -extern hecl::Database::DataSpecEntry SpecEntMP2ORIG; - -struct TextureCache { - static void Generate(PAKRouter& pakRouter, hecl::Database::Project& project, - const hecl::ProjectPath& pakPath) { - hecl::ProjectPath texturePath(pakPath, "texture_cache.yaml"); - hecl::ProjectPath catalogPath(pakPath, "!catalog.yaml"); - texturePath.makeDirChain(false); - - if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), "a")) { - fmt::print(fp.get(), FMT_STRING("TextureCache: {}\n"), texturePath.getRelativePath()); - } - - Log.report(logvisor::Level::Info, FMT_STRING("Gathering Texture metadata (this can take up to 10 seconds)...")); - std::unordered_map metaMap; - - pakRouter.enumerateResources([&](const DNAMP2::PAK::Entry* ent) { - if (ent->type == FOURCC('TXTR') && metaMap.find(ent->id) == metaMap.end()) { - PAKEntryReadStream rs = pakRouter.beginReadStreamForId(ent->id); - metaMap[ent->id] = TXTR::GetMetaData(rs); - } - return true; - }); - - athena::io::YAMLDocWriter yamlW("MP2TextureCache"); - for (const auto& pair : metaMap) { - hecl::ProjectPath path = pakRouter.getWorking(pair.first); - auto rec = yamlW.enterSubRecord(path.getRelativePath()); - pair.second.write(yamlW); - } - - athena::io::FileWriter fileW(texturePath.getAbsolutePath()); - yamlW.finish(&fileW); - Log.report(logvisor::Level::Info, FMT_STRING("Done...")); - } - - static void Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - hecl::Database::Project& project = inPath.getProject(); - athena::io::YAMLDocReader r; - athena::io::FileReader fr(inPath.getAbsolutePath()); - if (!fr.isOpen() || !r.parse(&fr)) - return; - - std::vector> metaPairs; - metaPairs.reserve(r.getRootNode()->m_mapChildren.size()); - for (const auto& node : r.getRootNode()->m_mapChildren) { - hecl::ProjectPath projectPath(project, node.first); - auto rec = r.enterSubRecord(node.first.c_str()); - TXTR::Meta meta; - meta.read(r); - metaPairs.emplace_back(projectPath.parsedHash32(), meta); - } - - std::sort(metaPairs.begin(), metaPairs.end(), - [](const auto& a, const auto& b) -> bool { return a.first < b.first; }); - - athena::io::FileWriter w(outPath.getAbsolutePath()); - w.writeUint32Big(metaPairs.size()); - for (const auto& pair : metaPairs) { - pair.first.write(w); - pair.second.write(w); - } - } -}; - -struct SpecMP2 : SpecBase { - bool checkStandaloneID(const char* id) const override { - if (!memcmp(id, "G2M", 3)) - return true; - return false; - } - - std::vector m_nonPaks; - std::vector m_paks; - std::map m_orderedPaks; - - hecl::ProjectPath m_workPath; - hecl::ProjectPath m_cookPath; - PAKRouter m_pakRouter; - - SpecMP2(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc) - : SpecBase(specEntry, project, pc) - , m_workPath(project.getProjectWorkingPath(), "MP2") - , m_cookPath(project.getProjectCookedPath(SpecEntMP2), "MP2") - , m_pakRouter(*this, m_workPath, m_cookPath) { - m_game = EGame::MetroidPrime2; - SpecBase::setThreadProject(); - } - - void buildPaks(nod::Node& root, const std::vector& args, ExtractReport& rep) { - m_nonPaks.clear(); - m_paks.clear(); - for (const nod::Node& child : root) { - bool isPak = false; - auto name = child.getName(); - std::string lowerName(name); - hecl::ToLower(lowerName); - if (name.size() > 4) { - std::string::iterator extit = lowerName.end() - 4; - if (std::string(extit, lowerName.end()) == ".pak") { - /* This is a pak */ - isPak = true; - std::string lowerBase(lowerName.begin(), extit); - - /* Needs filter */ - bool good = true; - if (args.size()) { - good = false; - if (!lowerName.compare(0, 7, "metroid")) { - char idxChar = lowerName[7]; - for (const std::string& arg : args) { - if (arg.size() == 1 && iswdigit(arg[0])) - if (arg[0] == idxChar) - good = true; - } - } else - good = true; - - if (!good) { - for (const std::string& arg : args) { - std::string lowerArg(arg); - hecl::ToLower(lowerArg); - if (!lowerArg.compare(0, lowerBase.size(), lowerBase)) - good = true; - } - } - } - - m_paks.emplace_back(child, good); - } - } - - if (!isPak) - m_nonPaks.push_back(&child); - } - - /* Sort PAKs alphabetically */ - m_orderedPaks.clear(); - for (DNAMP2::PAKBridge& dpak : m_paks) - m_orderedPaks[std::string(dpak.getName())] = &dpak; - - /* Assemble extract report */ - for (const auto& item : m_orderedPaks) { - if (!item.second->m_doExtract) { - continue; - } - - ExtractReport& childRep = rep.childOpts.emplace_back(); - childRep.name = item.first; - childRep.desc = item.second->getLevelString(); - } - } - - bool checkFromStandaloneDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, std::vector& reps) override { - nod::IPartition* partition = disc.getDataPartition(); - std::unique_ptr dolBuf = partition->getDOLBuf(); - const char* buildInfo = - static_cast(memmem(dolBuf.get(), partition->getDOLSize(), "MetroidBuildInfo", 16)) + 19; - if (buildInfo == nullptr) { - return false; - } - - m_version = std::string(buildInfo); - /* Root Report */ - ExtractReport& rep = reps.emplace_back(); - rep.name = "MP2"; - rep.desc = "Metroid Prime 2 " + regstr; - rep.desc += " (" + m_version + ")"; - - /* Iterate PAKs and build level options */ - nod::Node& root = partition->getFSTRoot(); - buildPaks(root, args, rep); - - return true; - } - - bool checkFromTrilogyDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, std::vector& reps) override { - std::vector mp2args; - bool doExtract = false; - if (!args.empty()) { - /* Needs filter */ - for (const std::string& arg : args) { - std::string lowerArg = arg; - hecl::ToLower(lowerArg); - if (!lowerArg.compare(0, 3, "mp2")) { - doExtract = true; - mp2args.reserve(args.size()); - size_t slashPos = arg.find('/'); - if (slashPos == std::string::npos) - slashPos = arg.find('\\'); - if (slashPos != std::string::npos) - mp2args.emplace_back(std::string(arg.begin() + slashPos + 1, arg.end())); - } - } - } else - doExtract = true; - - if (!doExtract) - return false; - - nod::IPartition* partition = disc.getDataPartition(); - nod::Node& root = partition->getFSTRoot(); - nod::Node::DirectoryIterator dolIt = root.find("rs5mp2_p.dol"); - if (dolIt == root.end()) { - dolIt = root.find("rs5mp2jpn_p.dol"); - if (dolIt == root.end()) - return false; - } - - std::unique_ptr dolBuf = dolIt->getBuf(); - const char* buildInfo = static_cast(memmem(dolBuf.get(), dolIt->size(), "MetroidBuildInfo", 16)) + 19; - - /* Root Report */ - ExtractReport& rep = reps.emplace_back(); - rep.name = "MP2"; - rep.desc = "Metroid Prime 2 " + regstr; - if (buildInfo != nullptr) { - m_version = std::string(buildInfo); - rep.desc += " (" + m_version + ")"; - } - - /* Iterate PAKs and build level options */ - nod::Node::DirectoryIterator mp2It = root.find("MP2"); - if (mp2It == root.end()) { - mp2It = root.find("MP2JPN"); - if (mp2It == root.end()) - return false; - } - buildPaks(*mp2It, mp2args, rep); - - return true; - } - - bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) override { - nod::ExtractionContext ctx = {force, nullptr}; - - m_workPath.makeDir(); - - progress.startNewLine(); - progress.print("Indexing PAKs", "", 0.0); - m_pakRouter.build(m_paks, - [&progress](float factor) { progress.print("Indexing PAKs", "", factor); }); - progress.print("Indexing PAKs", "", 1.0); - - hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), "out"); - outPath.makeDir(); - disc.getDataPartition()->extractSysFiles(outPath.getAbsolutePath(), ctx); - hecl::ProjectPath mp2OutPath(outPath, "files/MP2"); - mp2OutPath.makeDirChain(true); - - progress.startNewLine(); - progress.print("MP2 Root", "", 0.0); - int prog = 0; - ctx.progressCB = [&prog, &progress](std::string_view name, float) { - progress.print("MP2 Root", name, prog); - }; - for (const nod::Node* node : m_nonPaks) { - node->extractToDirectory(mp2OutPath.getAbsolutePath(), ctx); - prog++; - } - progress.print("MP2 Root", "", 1.0); - - hecl::ClientProcess process; - progress.startNewLine(); - for (std::pair& pair : m_orderedPaks) { - DNAMP2::PAKBridge& pak = *pair.second; - if (!pak.m_doExtract) - continue; - - auto pakName = std::string(pak.getName()); - process.addLambdaTransaction([this, &progress, &pak, pakName, force](hecl::blender::Token& btok) { - int threadIdx = hecl::ClientProcess::GetThreadWorkerIdx(); - m_pakRouter.extractResources(pak, force, btok, - [&progress, &pakName, threadIdx](const char* substr, float factor) { - progress.print(pakName, substr, factor, threadIdx); - }); - }); - } - - process.waitUntilComplete(); - - /* Generate Texture Cache containing meta data for every texture file */ - hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), "MP2/URDE"); - TextureCache::Generate(m_pakRouter, m_project, noAramPath); - - /* Write version data */ - hecl::ProjectPath versionPath = hecl::ProjectPath(m_project.getProjectWorkingPath(), "out/files/MP2"); - WriteVersionInfo(m_project, versionPath); - return true; - } - - const hecl::Database::DataSpecEntry& getOriginalSpec() const override { return SpecEntMP2; } - - const hecl::Database::DataSpecEntry& getUnmodifiedSpec() const override { return SpecEntMP2ORIG; } - - hecl::ProjectPath getWorking(class UniqueID32& id) override { return m_pakRouter.getWorking(id); } - - bool checkPathPrefix(const hecl::ProjectPath& path) const override { - return path.getRelativePath().compare(0, 4, "MP2/") == 0; - } - - bool validateYAMLDNAType(athena::io::IStreamReader& fp) const override { - athena::io::YAMLDocReader reader; - yaml_parser_set_input(reader.getParser(), (yaml_read_handler_t*)athena::io::YAMLAthenaReader, &fp); - return reader.ClassTypeOperation([](std::string_view classType) { - if (classType == DNAMP2::MLVL::DNAType()) - return true; - else if (classType == DNAMP2::STRG::DNAType()) - return true; - else if (classType == "ATBL") - return true; - return false; - }); - } - - metaforce::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const override { return {}; } - - void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookColMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookArmature(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - PathMesh mesh = ds.compilePathMesh(); - ds.close(); - DNAMP2::PATH::Cook(out, in, mesh, btok); - } - - void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookWorld(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector& pathsOut) override {} - - void flattenDependenciesANCSYAML(athena::io::IStreamReader& fin, std::vector& pathsOut, - int charIdx) override {} - - void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override { - DNAMP2::AGSC::Cook(in, out); - progress("Done"); - } - - void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override { - DNAMP1::CSNG::Cook(in, out); - progress("Done"); - } - - void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override { - hecl::blender::MapArea mapa = ds.compileMapArea(); - ds.close(); - DNAMP2::MAPA::Cook(mapa, out); - progress("Done"); - } - - void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override { - hecl::blender::MapUniverse mapu = ds.compileMapUniverse(); - ds.close(); - DNAMAPU::MAPU::Cook(mapu, out); - progress("Done"); - } -}; - -hecl::Database::DataSpecEntry SpecEntMP2( - "MP2"sv, "Data specification for original Metroid Prime 2 engine"sv, ".pak"sv, - [](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr { - return std::make_unique(&SpecEntMP2, project, false); - }); - -hecl::Database::DataSpecEntry SpecEntMP2PC = { - "MP2-PC"sv, "Data specification for PC-optimized Metroid Prime 2 engine"sv, ".upak"sv, - [](hecl::Database::Project& project, - hecl::Database::DataSpecTool tool) -> std::unique_ptr { - if (tool != hecl::Database::DataSpecTool::Extract) - return std::make_unique(&SpecEntMP2PC, project, true); - return {}; - }}; - -hecl::Database::DataSpecEntry SpecEntMP2ORIG = { - "MP2-ORIG"sv, "Data specification for unmodified Metroid Prime 2 resources"sv, {}, {}}; - -} // namespace DataSpec diff --git a/DataSpec/SpecMP3.cpp b/DataSpec/SpecMP3.cpp deleted file mode 100644 index 8b44dc857..000000000 --- a/DataSpec/SpecMP3.cpp +++ /dev/null @@ -1,577 +0,0 @@ -#include -#include - -#include "DataSpec/SpecBase.hpp" -#include "DataSpec/DNAMP3/DNAMP3.hpp" - -#include "DataSpec/DNAMP3/MLVL.hpp" -#include "DataSpec/DNAMP3/STRG.hpp" -#include "DataSpec/DNAMP3/MAPA.hpp" -#include "DataSpec/DNAMP2/STRG.hpp" -#include "DataSpec/DNACommon/TXTR.hpp" -#include "DataSpec/DNACommon/MetaforceVersionInfo.hpp" - -#include "hecl/ClientProcess.hpp" -#include "hecl/Blender/Connection.hpp" -#include "hecl/MultiProgressPrinter.hpp" - -#include "Runtime/RetroTypes.hpp" -#include "nod/nod.hpp" - -namespace DataSpec { - -using namespace std::literals; - -static logvisor::Module Log("DataSpec::SpecMP3"); -extern hecl::Database::DataSpecEntry SpecEntMP3; -extern hecl::Database::DataSpecEntry SpecEntMP3ORIG; - -struct TextureCache { - static void Generate(PAKRouter& pakRouter, hecl::Database::Project& project, - const hecl::ProjectPath& pakPath) { - hecl::ProjectPath texturePath(pakPath, "texture_cache.yaml"); - hecl::ProjectPath catalogPath(pakPath, "!catalog.yaml"); - texturePath.makeDirChain(false); - - if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), "a")) { - fmt::print(fp.get(), FMT_STRING("TextureCache: {}\n"), texturePath.getRelativePath()); - } - - Log.report(logvisor::Level::Info, FMT_STRING("Gathering Texture metadata (this can take up to 10 seconds)...")); - std::unordered_map metaMap; - - pakRouter.enumerateResources([&](const DNAMP3::PAK::Entry* ent) { - if (ent->type == FOURCC('TXTR') && metaMap.find(ent->id) == metaMap.end()) { - PAKEntryReadStream rs = pakRouter.beginReadStreamForId(ent->id); - metaMap[ent->id] = TXTR::GetMetaData(rs); - } - return true; - }); - - athena::io::YAMLDocWriter yamlW("MP3TextureCache"); - for (const auto& pair : metaMap) { - hecl::ProjectPath path = pakRouter.getWorking(pair.first); - auto rec = yamlW.enterSubRecord(path.getRelativePath()); - pair.second.write(yamlW); - } - - athena::io::FileWriter fileW(texturePath.getAbsolutePath()); - yamlW.finish(&fileW); - Log.report(logvisor::Level::Info, FMT_STRING("Done...")); - } - - static void Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - hecl::Database::Project& project = inPath.getProject(); - athena::io::YAMLDocReader r; - athena::io::FileReader fr(inPath.getAbsolutePath()); - if (!fr.isOpen() || !r.parse(&fr)) - return; - - std::vector> metaPairs; - metaPairs.reserve(r.getRootNode()->m_mapChildren.size()); - for (const auto& node : r.getRootNode()->m_mapChildren) { - hecl::ProjectPath projectPath(project, node.first); - auto rec = r.enterSubRecord(node.first.c_str()); - TXTR::Meta meta; - meta.read(r); - metaPairs.emplace_back(projectPath.parsedHash32(), meta); - } - - std::sort(metaPairs.begin(), metaPairs.end(), - [](const auto& a, const auto& b) -> bool { return a.first < b.first; }); - - athena::io::FileWriter w(outPath.getAbsolutePath()); - w.writeUint32Big(metaPairs.size()); - for (const auto& pair : metaPairs) { - pair.first.write(w); - pair.second.write(w); - } - } -}; - -struct SpecMP3 : SpecBase { - bool checkStandaloneID(const char* id) const override { return memcmp(id, "RM3", 3) == 0; } - - bool doMP3 = false; - std::vector m_nonPaks; - std::vector m_paks; - std::map m_orderedPaks; - - hecl::ProjectPath m_workPath; - hecl::ProjectPath m_cookPath; - hecl::ProjectPath m_outPath; - PAKRouter m_pakRouter; - - /* These are populated when extracting MPT's frontend (uses MP3's DataSpec) */ - bool doMPTFE = false; - std::vector m_feNonPaks; - std::vector m_fePaks; - std::map m_feOrderedPaks; - - hecl::ProjectPath m_feWorkPath; - hecl::ProjectPath m_feCookPath; - hecl::ProjectPath m_feOutPath; - PAKRouter m_fePakRouter; - - SpecMP3(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc) - : SpecBase(specEntry, project, pc) - , m_workPath(project.getProjectWorkingPath(), "MP3") - , m_cookPath(project.getProjectCookedPath(SpecEntMP3), "MP3") - , m_pakRouter(*this, m_workPath, m_cookPath) - , m_feWorkPath(project.getProjectWorkingPath(), "fe") - , m_feCookPath(project.getProjectCookedPath(SpecEntMP3), "fe") - , m_fePakRouter(*this, m_feWorkPath, m_feCookPath) { - m_game = EGame::MetroidPrime3; - SpecBase::setThreadProject(); - } - - void buildPaks(nod::Node& root, const std::vector& args, ExtractReport& rep, bool fe) { - if (fe) { - m_feNonPaks.clear(); - m_fePaks.clear(); - } else { - m_nonPaks.clear(); - m_paks.clear(); - } - for (const nod::Node& child : root) { - bool isPak = false; - auto name = child.getName(); - std::string lowerName(name); - hecl::ToLower(lowerName); - if (name.size() > 4) { - std::string::iterator extit = lowerName.end() - 4; - if (std::string(extit, lowerName.end()) == ".pak") { - /* This is a pak */ - isPak = true; - std::string lowerBase(lowerName.begin(), extit); - - /* Needs filter */ - bool good = true; - if (args.size()) { - good = false; - if (!lowerName.compare(0, 7, "metroid")) { - char idxChar = lowerName[7]; - for (const std::string& arg : args) { - if (arg.size() == 1 && iswdigit(arg[0])) - if (arg[0] == idxChar) - good = true; - } - } else - good = true; - - if (!good) { - for (const std::string& arg : args) { - std::string lowerArg(arg); - hecl::ToLower(lowerArg); - if (!lowerArg.compare(0, lowerBase.size(), lowerBase)) - good = true; - } - } - } - - if (fe) - m_fePaks.emplace_back(child, good); - else - m_paks.emplace_back(child, good); - } - } - - if (!isPak) { - if (fe) - m_feNonPaks.push_back(&child); - else - m_nonPaks.push_back(&child); - } - } - - /* Sort PAKs alphabetically */ - if (fe) { - m_feOrderedPaks.clear(); - for (DNAMP3::PAKBridge& dpak : m_fePaks) - m_feOrderedPaks[std::string(dpak.getName())] = &dpak; - } else { - m_orderedPaks.clear(); - for (DNAMP3::PAKBridge& dpak : m_paks) - m_orderedPaks[std::string(dpak.getName())] = &dpak; - } - - /* Assemble extract report */ - for (const auto& item : fe ? m_feOrderedPaks : m_orderedPaks) { - if (!item.second->m_doExtract) - continue; - - ExtractReport& childRep = rep.childOpts.emplace_back(); - childRep.name = item.first; - if (item.first == "Worlds.pak") - continue; - else if (item.first == "Metroid6.pak") { - /* Phaaze doesn't have a world name D: */ - childRep.desc = "Phaaze"; - continue; - } else if (item.first == "Metroid8.pak") { - /* Space world is misnamed */ - childRep.desc = "Space"; - continue; - } - childRep.desc = item.second->getLevelString(); - } - } - - bool checkFromStandaloneDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, std::vector& reps) override { - doMP3 = true; - nod::IPartition* partition = disc.getDataPartition(); - std::unique_ptr dolBuf = partition->getDOLBuf(); - const char* buildInfo = - static_cast(memmem(dolBuf.get(), partition->getDOLSize(), "MetroidBuildInfo", 16)) + 19; - if (buildInfo == nullptr) { - return false; - } - - /* We don't want no stinking demo dammit */ - if (strcmp(buildInfo, "Build v3.068 3/2/2006 14:55:13") == 0) { - return false; - } - - m_version = std::string(buildInfo); - /* Root Report */ - ExtractReport& rep = reps.emplace_back(); - rep.name = "MP3"; - rep.desc = "Metroid Prime 3 " + regstr; - rep.desc += " (" + m_version + ")"; - - /* Iterate PAKs and build level options */ - nod::Node& root = partition->getFSTRoot(); - buildPaks(root, args, rep, false); - - return true; - } - - bool checkFromTrilogyDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, std::vector& reps) override { - std::vector mp3args; - std::vector feargs; - if (args.size()) { - /* Needs filter */ - for (const std::string& arg : args) { - std::string lowerArg = arg; - hecl::ToLower(lowerArg); - if (!lowerArg.compare(0, 3, "mp3")) { - doMP3 = true; - mp3args.reserve(args.size()); - size_t slashPos = arg.find('/'); - if (slashPos == std::string::npos) - slashPos = arg.find('\\'); - if (slashPos != std::string::npos) - mp3args.emplace_back(std::string(arg.begin() + slashPos + 1, arg.end())); - } - } - - for (const std::string& arg : args) { - std::string lowerArg = arg; - hecl::ToLower(lowerArg); - if (!lowerArg.compare(0, 2, "fe")) { - doMPTFE = true; - feargs.reserve(args.size()); - size_t slashPos = arg.find('/'); - if (slashPos == std::string::npos) - slashPos = arg.find('\\'); - if (slashPos != std::string::npos) - feargs.emplace_back(std::string(arg.begin() + slashPos + 1, arg.end())); - } - } - } else { - doMP3 = true; - doMPTFE = true; - } - - if (!doMP3 && !doMPTFE) - return false; - - nod::IPartition* partition = disc.getDataPartition(); - nod::Node& root = partition->getFSTRoot(); - - /* MP3 extract */ - while (doMP3) { - nod::Node::DirectoryIterator dolIt = root.find("rs5mp3_p.dol"); - if (dolIt == root.end()) { - doMP3 = false; - break; - } - - std::unique_ptr dolBuf = dolIt->getBuf(); - const char* buildInfo = (char*)memmem(dolBuf.get(), dolIt->size(), "MetroidBuildInfo", 16) + 19; - - if (!buildInfo) { - doMP3 = false; - break; - } - - /* We don't want no stinking demo dammit */ - if (!strcmp(buildInfo, "Build v3.068 3/2/2006 14:55:13")) { - doMP3 = false; - break; - } - - /* Root Report */ - ExtractReport& rep = reps.emplace_back(); - rep.name = "MP3"; - rep.desc = "Metroid Prime 3 " + regstr; - - m_version = std::string(buildInfo); - rep.desc += " (" + m_version + ")"; - - /* Iterate PAKs and build level options */ - nod::Node::DirectoryIterator mp3It = root.find("MP3"); - if (mp3It == root.end()) { - doMP3 = false; - break; - } - buildPaks(*mp3It, mp3args, rep, false); - break; - } - - /* MPT Frontend extract */ - while (doMPTFE) { - nod::Node::DirectoryIterator dolIt = root.find("rs5fe_p.dol"); - if (dolIt == root.end()) { - doMPTFE = false; - break; - } - - std::unique_ptr dolBuf = dolIt->getBuf(); - const char* buildInfo = (char*)memmem(dolBuf.get(), dolIt->size(), "MetroidBuildInfo", 16) + 19; - - /* Root Report */ - ExtractReport& rep = reps.emplace_back(); - rep.name = "fe"; - rep.desc = "Metroid Prime Trilogy Frontend " + regstr; - if (buildInfo) { - std::string buildStr(buildInfo); - rep.desc += " (" + buildStr + ")"; - } - - /* Iterate PAKs and build level options */ - nod::Node::DirectoryIterator feIt = root.find("fe"); - if (feIt == root.end()) { - doMPTFE = false; - break; - } - buildPaks(*feIt, feargs, rep, true); - break; - } - - return doMP3 || doMPTFE; - } - - bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) override { - std::string currentTarget; - size_t nodeCount = 0; - int prog = 0; - nod::ExtractionContext ctx = {force, [&](std::string_view name, float) { - progress.print(currentTarget, name, prog / (float)nodeCount); - }}; - if (doMP3) { - m_workPath.makeDir(); - - progress.startNewLine(); - progress.print("Indexing PAKs", "", 0.0); - m_pakRouter.build(m_paks, - [&progress](float factor) { progress.print("Indexing PAKs", "", factor); }); - progress.print("Indexing PAKs", "", 1.0); - progress.startNewLine(); - - hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), "out"); - outPath.makeDir(); - disc.getDataPartition()->extractSysFiles(outPath.getAbsolutePath(), ctx); - m_outPath = {outPath, "files/MP3"}; - m_outPath.makeDirChain(true); - - currentTarget = "MP3 Root"; - progress.print(currentTarget.c_str(), "", 0.0); - prog = 0; - - nodeCount = m_nonPaks.size(); - // TODO: Make this more granular - for (const nod::Node* node : m_nonPaks) { - node->extractToDirectory(m_outPath.getAbsolutePath(), ctx); - prog++; - } - ctx.progressCB = nullptr; - - progress.print(currentTarget.c_str(), "", 1.0); - progress.startNewLine(); - - hecl::ClientProcess process; - for (std::pair& pair : m_orderedPaks) { - DNAMP3::PAKBridge& pak = *pair.second; - if (!pak.m_doExtract) - continue; - - auto pakName = std::string(pak.getName()); - process.addLambdaTransaction([this, &progress, &pak, pakName, force](hecl::blender::Token& btok) { - m_pakRouter.extractResources(pak, force, btok, - [&progress, &pakName](const char* substr, float factor) { - progress.print(pakName, substr, factor); - }); - }); - } - - process.waitUntilComplete(); - } - - if (doMPTFE) { - m_feWorkPath.makeDir(); - - progress.startNewLine(); - progress.print("Indexing PAKs", "", 0.0); - m_fePakRouter.build( - m_fePaks, [&progress](float factor) { progress.print("Indexing PAKs", "", factor); }); - progress.print("Indexing PAKs", "", 1.0); - progress.startNewLine(); - - hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), "out"); - outPath.makeDir(); - disc.getDataPartition()->extractSysFiles(outPath.getAbsolutePath(), ctx); - m_feOutPath = {outPath, "files/fe"}; - m_feOutPath.makeDirChain(true); - - currentTarget = "fe Root"; - progress.print(currentTarget.c_str(), "", 0.0); - prog = 0; - nodeCount = m_feNonPaks.size(); - - // TODO: Make this more granular - for (const nod::Node* node : m_feNonPaks) { - node->extractToDirectory(m_feOutPath.getAbsolutePath(), ctx); - prog++; - } - progress.print(currentTarget.c_str(), "", 1.0); - progress.startNewLine(); - - hecl::ClientProcess process; - for (auto& pair : m_feOrderedPaks) { - DNAMP3::PAKBridge& pak = *pair.second; - if (!pak.m_doExtract) - continue; - - std::string pakName(pak.getName()); - process.addLambdaTransaction([this, &progress, &pak, pakName, force](hecl::blender::Token& btok) { - m_fePakRouter.extractResources(pak, force, btok, - [&progress, &pakName](const char* substr, float factor) { - progress.print(pakName, substr, factor); - }); - }); - } - - process.waitUntilComplete(); - } - - /* Generate Texture Cache containing meta data for every texture file */ - if (doMP3) { - hecl::ProjectPath noAramPath(m_workPath, "URDE"); - TextureCache::Generate(m_pakRouter, m_project, noAramPath); - } - if (doMPTFE) { - hecl::ProjectPath noAramPath(m_feWorkPath, "URDE"); - TextureCache::Generate(m_fePakRouter, m_project, noAramPath); - } - /* Write version data */ - if (doMP3) { - WriteVersionInfo(m_project, m_outPath); - } - if (doMPTFE) { - WriteVersionInfo(m_project, m_feOutPath); - } - return true; - } - - const hecl::Database::DataSpecEntry& getOriginalSpec() const override { return SpecEntMP3; } - - const hecl::Database::DataSpecEntry& getUnmodifiedSpec() const override { return SpecEntMP3ORIG; } - - hecl::ProjectPath getWorking(class UniqueID64& id) override { return m_pakRouter.getWorking(id); } - - bool checkPathPrefix(const hecl::ProjectPath& path) const override { - return path.getRelativePath().compare(0, 4, "MP3/") == 0; - } - - bool validateYAMLDNAType(athena::io::IStreamReader& fp) const override { - if (athena::io::ValidateFromYAMLStream(fp)) - return true; - if (athena::io::ValidateFromYAMLStream(fp)) - return true; - if (athena::io::ValidateFromYAMLStream(fp)) - return true; - return false; - } - - metaforce::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const override { return {}; } - - void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookColMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookArmature(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookWorld(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector& pathsOut) override {} - - void flattenDependenciesANCSYAML(athena::io::IStreamReader& fin, std::vector& pathsOut, - int charIdx) override {} - - void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override {} - - void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override {} - - void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override { - hecl::blender::MapArea mapa = ds.compileMapArea(); - ds.close(); - DNAMP3::MAPA::Cook(mapa, out); - progress("Done"); - } - - void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override {} -}; - -hecl::Database::DataSpecEntry SpecEntMP3( - "MP3"sv, "Data specification for original Metroid Prime 3 engine"sv, ".pak"sv, - [](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr { - return std::make_unique(&SpecEntMP3, project, false); - }); - -hecl::Database::DataSpecEntry SpecEntMP3PC = { - "MP3-PC"sv, "Data specification for PC-optimized Metroid Prime 3 engine"sv, ".upak"sv, - [](hecl::Database::Project& project, - hecl::Database::DataSpecTool tool) -> std::unique_ptr { - if (tool != hecl::Database::DataSpecTool::Extract) - return std::make_unique(&SpecEntMP3PC, project, true); - return nullptr; - }}; - -hecl::Database::DataSpecEntry SpecEntMP3ORIG = { - "MP3-ORIG"sv, "Data specification for unmodified Metroid Prime 3 resources"sv, {}, {}}; - -} // namespace DataSpec diff --git a/NESEmulator/CMakeLists.txt b/NESEmulator/CMakeLists.txt index 7f04a9d94..92fcfbf15 100644 --- a/NESEmulator/CMakeLists.txt +++ b/NESEmulator/CMakeLists.txt @@ -1,5 +1,5 @@ file(GLOB MAPPER_SRCS ../extern/fixNES/mapper/*.c) -add_library(NESEmulator CNESEmulator.hpp CNESEmulator.cpp CNESShader.hpp CNESShader.cpp malloc.h +add_library(NESEmulator CNESEmulator.hpp CNESEmulator.cpp malloc.h apu.c ../extern/fixNES/audio_fds.c ../extern/fixNES/audio_mmc5.c ../extern/fixNES/audio_vrc6.c ../extern/fixNES/audio_vrc7.c ../extern/fixNES/audio_n163.c ../extern/fixNES/audio_s5b.c ../extern/fixNES/cpu.c ppu.c ../extern/fixNES/mem.c ../extern/fixNES/input.c ../extern/fixNES/mapper.c diff --git a/NESEmulator/CNESEmulator.cpp b/NESEmulator/CNESEmulator.cpp index 4bb9cf32c..fccae5b0f 100644 --- a/NESEmulator/CNESEmulator.cpp +++ b/NESEmulator/CNESEmulator.cpp @@ -1,5 +1,4 @@ #include "CNESEmulator.hpp" -#include "CNESShader.hpp" #include "CGameState.hpp" #include "Input/CFinalInput.hpp" #include "logvisor/logvisor.hpp" diff --git a/NESEmulator/CNESShader.cpp b/NESEmulator/CNESShader.cpp deleted file mode 100644 index b1b040ccf..000000000 --- a/NESEmulator/CNESShader.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "CNESShader.hpp" -#include "Graphics/CGraphics.hpp" -//#include "hecl/Pipeline.hpp" - -namespace metaforce::MP1 { - -//boo::ObjToken CNESShader::g_Pipeline; - -void CNESShader::Initialize() { -// g_Pipeline = hecl::conv->convert(Shader_CNESShader{}); -} - -//boo::ObjToken CNESShader::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, -// boo::ObjToken vbo, -// boo::ObjToken uniBuf, -// boo::ObjToken tex) { -// boo::ObjToken bufs[] = {uniBuf.get()}; -// boo::PipelineStage stages[] = {boo::PipelineStage::Vertex}; -// boo::ObjToken texs[] = {tex.get()}; -// return ctx.newShaderDataBinding(g_Pipeline, vbo.get(), nullptr, nullptr, 1, bufs, stages, nullptr, nullptr, 1, texs, -// nullptr, nullptr); -//} - -void CNESShader::Shutdown() { -// g_Pipeline.reset(); -} - -} // namespace metaforce::MP1 diff --git a/NESEmulator/CNESShader.hpp b/NESEmulator/CNESShader.hpp deleted file mode 100644 index a00014257..000000000 --- a/NESEmulator/CNESShader.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -//#include "boo/graphicsdev/IGraphicsDataFactory.hpp" - -namespace metaforce::MP1 { - -class CNESShader { -public: - static void Initialize(); - static void Shutdown(); - -// static boo::ObjToken BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, -// boo::ObjToken vbo, -// boo::ObjToken uniBuf, -// boo::ObjToken tex); -// -// static boo::ObjToken g_Pipeline; -}; - -} // namespace metaforce::MP1 diff --git a/Runtime/CMakeLists.txt b/Runtime/CMakeLists.txt index 048fbd34c..dcc22e0e5 100644 --- a/Runtime/CMakeLists.txt +++ b/Runtime/CMakeLists.txt @@ -24,8 +24,6 @@ add_subdirectory(Particle) if (WIN32) list(APPEND PLAT_SRCS CMemoryCardSysWin.cpp) -#elseif (APPLE) - #list(APPEND PLAT_SRCS CMemoryCardSysOSX.cpp) else () list(APPEND PLAT_SRCS CMemoryCardSysNix.cpp) endif () @@ -143,17 +141,15 @@ set(RUNTIME_SOURCES_B function(add_runtime_common_library name) add_library(${name} ${ARGN}) target_compile_definitions(${name} PUBLIC "-DMETAFORCE_TARGET_BYTE_ORDER=__BYTE_ORDER__") - if (COMMAND add_sanitizers) - add_sanitizers(${name}) - endif () - if (WINDOWS_STORE) set_property(TARGET ${name} PROPERTY VS_WINRT_COMPONENT TRUE) endif () endfunction() set(RUNTIME_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) -set(RUNTIME_LIBRARIES amuse zeus nod NESEmulator libjpeg-turbo jbus kabufuda discord-rpc logvisor OptickCore imgui aurora SDL2-static) +set(RUNTIME_LIBRARIES amuse zeus nod NESEmulator libjpeg-turbo jbus kabufuda discord-rpc logvisor OptickCore imgui aurora SDL2-static + boo # TODO move audiodev + ) add_runtime_common_library(RuntimeCommon ${RUNTIME_SOURCES_A}) target_include_directories(RuntimeCommon PUBLIC ${RUNTIME_INCLUDES}) @@ -216,9 +212,6 @@ if (WIN32) elseif (APPLE) # nothing elseif (UNIX) - add_subdirectory(platforms/freedesktop) - declare_wmicon_target() - set(PLAT_SRCS mainicon_netwm.cpp) set(PLAT_LIBS rt) endif () @@ -232,13 +225,7 @@ if (TARGET nativefiledialog) endif() target_compile_definitions(metaforce PUBLIC "-DMETAFORCE_TARGET_BYTE_ORDER=__BYTE_ORDER__") -if (COMMAND add_sanitizers) - add_sanitizers(metaforce) -endif () - -if (NOT WINDOWS_STORE) - #add_dependencies(metaforce hecl) # visigen -else () +if (WINDOWS_STORE) set_property(TARGET metaforce PROPERTY VS_WINRT_COMPONENT TRUE) # This should match the Package.appxmanifest set_property(TARGET metaforce PROPERTY VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION "10.0.14393.0") diff --git a/Runtime/platforms/freedesktop/CMakeLists.txt b/Runtime/platforms/freedesktop/CMakeLists.txt deleted file mode 100644 index d458df5a1..000000000 --- a/Runtime/platforms/freedesktop/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -add_executable(mkwmicon mkwmicon.c) -target_link_libraries(mkwmicon ${PNG_LIBRARIES} ${ZLIB_LIBRARIES}) - -macro(declare_wmicon_target) - add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/Runtime/platforms/freedesktop/mainicon_netwm.bin - COMMAND $ - ARGS ${CMAKE_BINARY_DIR}/Runtime/platforms/freedesktop/mainicon_netwm.bin - DEPENDS - ${CMAKE_SOURCE_DIR}/Runtime/platforms/freedesktop/128x128/apps/metaforce.png - ${CMAKE_SOURCE_DIR}/Runtime/platforms/freedesktop/64x64/apps/metaforce.png - ${CMAKE_SOURCE_DIR}/Runtime/platforms/freedesktop/48x48/apps/metaforce.png - ${CMAKE_SOURCE_DIR}/Runtime/platforms/freedesktop/32x32/apps/metaforce.png - ${CMAKE_SOURCE_DIR}/Runtime/platforms/freedesktop/16x16/apps/metaforce.png - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Runtime/platforms/freedesktop - COMMENT "Generating mainicon_netwm.bin") - bintoc(mainicon_netwm.cpp ${CMAKE_BINARY_DIR}/Runtime/platforms/freedesktop/mainicon_netwm.bin MAINICON_NETWM) -endmacro() diff --git a/assetnameparser/CMakeLists.txt b/assetnameparser/CMakeLists.txt deleted file mode 100644 index 5249d8428..000000000 --- a/assetnameparser/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -cmake_minimum_required(VERSION 3.10 FATAL_ERROR) # because of c++17 - -set(TINYXML_LIB_VERSION "5.0.1") -set(TINYXML_LIB_SOVERSION "5") -add_library(tinyxml2_static STATIC - "${CMAKE_SOURCE_DIR}/extern/tinyxml2/tinyxml2.cpp" - "${CMAKE_SOURCE_DIR}/extern/tinyxml2/tinyxml2.h") -target_include_directories(tinyxml2_static INTERFACE "${CMAKE_SOURCE_DIR}/extern") -set_target_properties(tinyxml2_static PROPERTIES - COMPILE_DEFINITONS "TINYXML2_EXPORT" - VERSION "${TINYXML_LIB_VERSION}" - SOVERSION "${TINYXML_LIB_SOVERSION}") -set_target_properties(tinyxml2_static PROPERTIES OUTPUT_NAME tinyxml2) -if (NOT MSVC) - target_compile_options(tinyxml2_static PRIVATE -Wno-implicit-fallthrough) -endif() - -add_executable(assetnameparser "main.cpp") - -set(AN_PARSER_LIBS "") -if (UNIX) - list(APPEND AN_PARSER_LIBS pthread) - if(UNIX AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux") - list(APPEND AN_PARSER_LIBS dl) - endif() -endif() - -target_link_libraries(assetnameparser tinyxml2_static logvisor ${AN_PARSER_LIBS}) diff --git a/assetnameparser/main.cpp b/assetnameparser/main.cpp deleted file mode 100644 index 290ec1b85..000000000 --- a/assetnameparser/main.cpp +++ /dev/null @@ -1,358 +0,0 @@ -#include -#include -#include -#include -#include - -#include "tinyxml2/tinyxml2.h" -#include - -#ifndef _WIN32 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#else -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN 1 -#endif -#ifndef NOMINMAX -#define NOMINMAX -#endif -#include -#include -#define strncasecmp _strnicmp -#define strcasecmp _stricmp -#endif - -namespace { - -uint32_t crc32(const uint8_t * data, uint64_t length, uint32_t seed, uint32_t final) { - static const uint32_t crc32Table[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, - 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, - 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, - 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, - 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, - 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, - 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, - 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, - 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, - 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, - 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, - 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, - 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, - 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, - 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, - 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, - 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, - 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, - 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, - 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, - 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, - 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D}; - - if (!data) - return seed; - - uint32_t checksum = seed; - int pos = 0; - - while (length--) - checksum = (checksum >> 8) ^ crc32Table[(checksum & 0xFF) ^ data[pos++]]; - - return checksum ^ final; -} - -logvisor::Module Log("AssetNameParser"); - -// TODO: Clean this up -#undef bswap16 -#undef bswap32 -#undef bswap64 - -/* Type-sensitive byte swappers */ -template -constexpr T bswap16(T val) { -#if __GNUC__ - return __builtin_bswap16(val); -#elif _WIN32 - return _byteswap_ushort(val); -#else - return (val = (val << 8) | ((val >> 8) & 0xFF)); -#endif -} - -template -constexpr T bswap32(T val) { -#if __GNUC__ - return __builtin_bswap32(val); -#elif _WIN32 - return _byteswap_ulong(val); -#else - val = (val & 0x0000FFFF) << 16 | (val & 0xFFFF0000) >> 16; - val = (val & 0x00FF00FF) << 8 | (val & 0xFF00FF00) >> 8; - return val; -#endif -} - -template -constexpr T bswap64(T val) { -#if __GNUC__ - return __builtin_bswap64(val); -#elif _WIN32 - return _byteswap_uint64(val); -#else - return ((val & 0xFF00000000000000ULL) >> 56) | ((val & 0x00FF000000000000ULL) >> 40) | - ((val & 0x0000FF0000000000ULL) >> 24) | ((val & 0x000000FF00000000ULL) >> 8) | - ((val & 0x00000000FF000000ULL) << 8) | ((val & 0x0000000000FF0000ULL) << 24) | - ((val & 0x000000000000FF00ULL) << 40) | ((val & 0x00000000000000FFULL) << 56); -#endif -} - -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -constexpr uint32_t SBig(uint32_t val) { return bswap32(val); } -constexpr uint64_t SBig(uint64_t val) { return bswap64(val); } -#ifndef SBIG -#define SBIG(q) (((q)&0x000000FF) << 24 | ((q)&0x0000FF00) << 8 | ((q)&0x00FF0000) >> 8 | ((q)&0xFF000000) >> 24) -#endif - -#ifndef SLITTLE -#define SLITTLE(q) (q) -#endif -#else -#ifndef SLITTLE -#define SLITTLE(q) (((q)&0x000000FF) << 24 | ((q)&0x0000FF00) << 8 | ((q)&0x00FF0000) >> 8 | ((q)&0xFF000000) >> 24) -#endif - -constexpr uint32_t SBig(uint32_t val) { return val; } -constexpr uint64_t SBig(uint64_t val) { return val; } -#ifndef SBIG -#define SBIG(q) (q) -#endif -#endif - -class FourCC { -protected: - union { - char fcc[4]; - uint32_t num; - }; - -public: - FourCC() /* Sentinel FourCC */ - : num(0) {} - FourCC(const FourCC& other) { num = other.num; } - FourCC(const char* name) : num(*(uint32_t*)name) {} - FourCC(uint32_t n) : num(n) {} - bool operator==(const FourCC& other) const { return num == other.num; } - bool operator!=(const FourCC& other) const { return num != other.num; } - bool operator==(const char* other) const { return num == *(uint32_t*)other; } - bool operator!=(const char* other) const { return num != *(uint32_t*)other; } - bool operator==(int32_t other) const { return num == other; } - bool operator!=(int32_t other) const { return num != other; } - bool operator==(uint32_t other) const { return num == other; } - bool operator!=(uint32_t other) const { return num != other; } - std::string toString() const { return std::string(fcc, 4); } - uint32_t toUint32() const { return num; } - operator uint32_t() const { return num; } -}; - -struct SAsset { - FourCC type; - uint64_t id; - std::string name; - std::string dir; -}; - -enum class FileLockType { None = 0, Read, Write }; - -#if _WIN32 -using Sstat = struct ::_stat64; -#else -using Sstat = struct stat; -#endif - -struct FILEDeleter { - void operator()(FILE* file) const { std::fclose(file); } -}; -using FILEPtr = std::unique_ptr; - -FILEPtr Fopen(const char* path, const char* mode, FileLockType lock = FileLockType::None) { -#if _WIN32 - const nowide::wstackstring wpath(path); - const nowide::wshort_stackstring wmode(mode); - FILEPtr fp{_wfopen(wpath.get(), wmode.get())}; - if (!fp) { - return nullptr; - } -#else - FILEPtr fp{std::fopen(path, mode)}; - if (!fp) { - return nullptr; - } -#endif - - if (lock != FileLockType::None) { -#if _WIN32 - OVERLAPPED ov = {}; - LockFileEx((HANDLE)(uintptr_t)_fileno(fp.get()), (lock == FileLockType::Write) ? LOCKFILE_EXCLUSIVE_LOCK : 0, 0, 0, - 1, &ov); -#else - if (flock(fileno(fp.get()), ((lock == FileLockType::Write) ? LOCK_EX : LOCK_SH) | LOCK_NB)) { - std::fprintf(stderr, "flock %s: %s", path, strerror(errno)); - } -#endif - } - - return fp; -} -} // Anonymous namespace - -std::string getValidExtension(const std::string& type) { - if (type == "ANIM") { - return "ani"; - } - if (type == "ANCS") { - return "acs"; - } - if (type == "PART") { - return "gpsm.part"; - } - if (type == "ELSC") { - return "elsm.elsc"; - } - if (type == "SWHC") { - return "swsh.swhc"; - } - if (type == "DPSC") { - return "dpsm.dpsc"; - } - if (type == "CRSC") { - return "crsm.crsc"; - } - if (type == "WPSC") { - return "wpsm.wpsc"; - } - if (type == "FONT") { - return "rpff"; - } - if (type == "MLVL") { - return "mwld"; - } - if (type == "CINF") { - return "cin"; - } - return type; -} - -int main(int argc, char* argv[]) { -#if _WIN32 - nowide::args _(argc, argv); -#endif - - logvisor::RegisterStandardExceptions(); - logvisor::RegisterConsoleLogger(); - if (argc < 3) { - Log.report(logvisor::Error, FMT_STRING("Usage: {} "), argv[0]); - return 1; - } - - std::string inPath = argv[1]; - std::string outPath = argv[2]; - - tinyxml2::XMLDocument doc; - std::vector assets; - FILEPtr docF = Fopen(inPath.c_str(), "rb"); - if (doc.LoadFile(docF.get()) == tinyxml2::XML_SUCCESS) { - const tinyxml2::XMLElement* elm = doc.RootElement(); - if (strcmp(elm->Name(), "AssetNameMap") != 0) { - Log.report(logvisor::Fatal, FMT_STRING("Invalid database supplied")); - return 1; - } - - elm = elm->FirstChildElement("AssetNameMap"); - if (elm == nullptr) { - Log.report(logvisor::Fatal, FMT_STRING("Malformed AssetName database")); - return 1; - } - - elm = elm->FirstChildElement("Asset"); - - while (elm != nullptr ) { - const tinyxml2::XMLElement* keyElm = elm->FirstChildElement("Key"); - const tinyxml2::XMLElement* valueElm = elm->FirstChildElement("Value"); - - if (keyElm == nullptr || valueElm == nullptr) { - Log.report(logvisor::Fatal, FMT_STRING("Malformed Asset entry, [Key,Value] required")); - return 0; - } - - const tinyxml2::XMLElement* nameElm = valueElm->FirstChildElement("Name"); - const tinyxml2::XMLElement* dirElm = valueElm->FirstChildElement("Directory"); - const tinyxml2::XMLElement* typeElm = valueElm->FirstChildElement("Type"); - const tinyxml2::XMLElement* autoGenNameElm = valueElm->FirstChildElement("AutoGenName"); - const tinyxml2::XMLElement* autoGenDirElm = valueElm->FirstChildElement("AutoGenDir"); - - if (nameElm == nullptr || dirElm == nullptr || typeElm == nullptr) { - Log.report(logvisor::Fatal, FMT_STRING("Malformed Value entry, [Name,Directory,Type] required")); - return 0; - } - bool autoGen = strncasecmp(autoGenNameElm->GetText(), "true", 4) == 0 && strncasecmp(autoGenDirElm->GetText(), "true", 4) == 0; - uint64_t id = strtoull(keyElm->GetText(), nullptr, 16); - std::string dir = dirElm->GetText(); - std::string name = nameElm->GetText(); - std::string type = typeElm->GetText(); - std::string projPath = "$/" + dir + name + "." + getValidExtension(type); - std::transform(projPath.begin(), projPath.end(), projPath.begin(), [](unsigned char c) -> unsigned char { return std::tolower(c); }); - uint32_t tmpId = crc32(reinterpret_cast(projPath.c_str()), projPath.length(), 0xFFFFFFFF, 0); - if (!autoGen || tmpId == id) { - SAsset& asset = assets.emplace_back(); - asset.type = typeElm->GetText(); - asset.id = id; - asset.name = nameElm->GetText(); - asset.dir = dirElm->GetText(); - } - elm = elm->NextSiblingElement("Asset"); - } - - FILEPtr f = Fopen(outPath.c_str(), "wb"); - if (f == nullptr) { - Log.report(logvisor::Fatal, FMT_STRING("Unable to open destination")); - return 0; - } - - uint32_t assetCount = SBig(uint32_t(assets.size())); - FourCC sentinel(SBIG('AIDM')); - fwrite(&sentinel, sizeof(FourCC), 1, f.get()); - fwrite(&assetCount, sizeof(uint32_t), 1, f.get()); - for (const SAsset& asset : assets) { - fwrite(&asset.type, sizeof(asset.type), 1, f.get()); - uint64_t id = SBig(asset.id); - fwrite(&id, sizeof(uint64_t), 1, f.get()); - uint32_t tmp = SBig(uint32_t(asset.name.length())); - fwrite(&tmp, sizeof(tmp), 1, f.get()); - fwrite(asset.name.c_str(), 1, SBig(tmp), f.get()); - tmp = SBig(uint32_t(asset.dir.length())); - fwrite(&tmp, sizeof(tmp), 1, f.get()); - fwrite(asset.dir.c_str(), SBig(tmp), 1, f.get()); - } - fflush(f.get()); - return 0; - } - - Log.report(logvisor::Fatal, FMT_STRING("failed to load")); - return 1; -} diff --git a/aurora/CMakeLists.txt b/aurora/CMakeLists.txt index 9077f4171..2c54e4625 100644 --- a/aurora/CMakeLists.txt +++ b/aurora/CMakeLists.txt @@ -1,20 +1,3 @@ -if (WIN32) - set(SDL_LIBC ON CACHE BOOL "Use the system C library" FORCE) -endif () -add_subdirectory(../extern/SDL SDL2 EXCLUDE_FROM_ALL) -if (NOT MSVC) - target_compile_options(SDL2-static PRIVATE -Wno-implicit-fallthrough -Wno-shadow) -endif () - -add_subdirectory(../extern/dawn dawn EXCLUDE_FROM_ALL) -target_compile_definitions(dawn_native PRIVATE - DAWN_ENABLE_VULKAN_VALIDATION_LAYERS - DAWN_VK_DATA_DIR="vulkandata") -if (NOT MSVC) - target_compile_options(SPIRV-Tools-static PRIVATE -Wno-implicit-fallthrough) - target_compile_options(SPIRV-Tools-opt PRIVATE -Wno-implicit-fallthrough) -endif () - add_library(aurora STATIC lib/aurora.cpp lib/gpu.cpp diff --git a/hecl/bintoc/CMakeLists.txt b/bintoc/CMakeLists.txt similarity index 76% rename from hecl/bintoc/CMakeLists.txt rename to bintoc/CMakeLists.txt index 003393286..35f812015 100644 --- a/hecl/bintoc/CMakeLists.txt +++ b/bintoc/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_policy(VERSION 3.15...3.20) project(bintoc LANGUAGES C) add_executable(bintoc bintoc.c) -add_subdirectory(../../extern/athena/extern/zlib zlib EXCLUDE_FROM_ALL) +add_subdirectory(../extern/athena/extern/zlib zlib EXCLUDE_FROM_ALL) target_link_libraries(bintoc PRIVATE ${ZLIB_LIBRARIES}) install(TARGETS bintoc DESTINATION bin) diff --git a/hecl/bintoc/bintoc.c b/bintoc/bintoc.c similarity index 100% rename from hecl/bintoc/bintoc.c rename to bintoc/bintoc.c diff --git a/hecl/bintoc/bintocHelpers.cmake b/bintoc/bintocHelpers.cmake similarity index 100% rename from hecl/bintoc/bintocHelpers.cmake rename to bintoc/bintocHelpers.cmake diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index e556ae50a..fa3d0a2cc 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -1,8 +1,3 @@ -list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/extern/sanitizers-cmake/cmake") -find_package(Sanitizers) - -add_subdirectory(boo EXCLUDE_FROM_ALL) - option(BUILD_ATHENA "Build Athena libraries from source" ON) if (WIN32 OR APPLE) # Default to binary atdna on Windows & macOS @@ -42,7 +37,9 @@ else () include(athena/atdna/atdnaHelpers.cmake) endif () -# amuse must come after athena/atdna +add_subdirectory(boo EXCLUDE_FROM_ALL) +add_subdirectory(nod EXCLUDE_FROM_ALL) +# amuse must come after athena/atdna, boo and nod add_subdirectory(amuse EXCLUDE_FROM_ALL) if (NOT GEKKO AND NOT NX) @@ -68,8 +65,6 @@ endif () add_subdirectory(jbus EXCLUDE_FROM_ALL) add_subdirectory(kabufuda EXCLUDE_FROM_ALL) -add_subdirectory(libpng EXCLUDE_FROM_ALL) -add_subdirectory(libSquish EXCLUDE_FROM_ALL) add_library(nativefiledialog STATIC EXCLUDE_FROM_ALL nativefiledialog/src/nfd_common.c) target_include_directories(nativefiledialog PUBLIC nativefiledialog/src/include) @@ -94,7 +89,33 @@ else () message(WARNING "nativefiledialog unsupported for ${CMAKE_SYSTEM_NAME}") endif () -add_subdirectory(nod EXCLUDE_FROM_ALL) +if (WIN32) + set(SDL_LIBC ON CACHE BOOL "Use the system C library" FORCE) +endif () +add_subdirectory(../extern/SDL SDL2 EXCLUDE_FROM_ALL) +if (NOT MSVC) + target_compile_options(SDL2-static PRIVATE -Wno-implicit-fallthrough -Wno-shadow) +endif () + +add_subdirectory(../extern/dawn dawn EXCLUDE_FROM_ALL) +if (DAWN_ENABLE_VULKAN) + target_compile_definitions(dawn_native PRIVATE + DAWN_ENABLE_VULKAN_VALIDATION_LAYERS + DAWN_VK_DATA_DIR="vulkandata") +endif () +if (NOT MSVC) + target_compile_options(SPIRV-Tools-static PRIVATE -Wno-implicit-fallthrough) + target_compile_options(SPIRV-Tools-opt PRIVATE -Wno-implicit-fallthrough) +endif () + +option(OPTICK_ENABLED "Enable profiling with Optick" OFF) +set(OPTICK_USE_VULKAN ${DAWN_ENABLE_VULKAN} CACHE BOOL "Built-in support for Vulkan" FORCE) +set(OPTICK_INSTALL_TARGETS OFF CACHE BOOL "Should optick be installed? Set to OFF if you use add_subdirectory to include Optick." FORCE) +add_subdirectory(optick) +if (NOT MSVC) + target_compile_options(OptickCore PRIVATE -Wno-implicit-fallthrough) +endif () + add_subdirectory(libjpeg-turbo EXCLUDE_FROM_ALL) add_subdirectory(xxhash EXCLUDE_FROM_ALL) add_subdirectory(zeus EXCLUDE_FROM_ALL) diff --git a/extern/boo b/extern/boo index 94d11cb32..33cfcd8b6 160000 --- a/extern/boo +++ b/extern/boo @@ -1 +1 @@ -Subproject commit 94d11cb32884cfc90a0f13f6ff98a1c7637f8312 +Subproject commit 33cfcd8b63fdd6fabdcca4704c48626838f9b0f8 diff --git a/extern/libSquish b/extern/libSquish deleted file mode 160000 index fd5e6f4fe..000000000 --- a/extern/libSquish +++ /dev/null @@ -1 +0,0 @@ -Subproject commit fd5e6f4fe294bcdde24e591fcef37dd5d740e060 diff --git a/extern/libpng/ANNOUNCE b/extern/libpng/ANNOUNCE deleted file mode 100644 index 9f1b66583..000000000 --- a/extern/libpng/ANNOUNCE +++ /dev/null @@ -1,115 +0,0 @@ -Libpng 1.6.19 - November 12, 2015 - -This is a public release of libpng, intended for use in production codes. - -Files available for download: - -Source files with LF line endings (for Unix/Linux) and with a -"configure" script - - libpng-1.6.19.tar.xz (LZMA-compressed, recommended) - libpng-1.6.19.tar.gz - -Source files with CRLF line endings (for Windows), without the -"configure" script - - lpng1619.7z (LZMA-compressed, recommended) - lpng1619.zip - -Other information: - - libpng-1.6.19-README.txt - libpng-1.6.19-LICENSE.txt - libpng-1.6.19-*.asc (armored detached GPG signatures) - -Changes since the last public release (1.6.18): - - Updated obsolete information about the simplified API macros in the - manual pages (Bug report by Arc Riley). - Avoid potentially dereferencing NULL info_ptr in png_info_init_3(). - Rearranged png.h to put the major sections in the same order as - in libpng17. - Eliminated unused PNG_COST_SHIFT, PNG_WEIGHT_SHIFT, PNG_COST_FACTOR, and - PNG_WEIGHT_FACTOR macros. - Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler - (Bug report by Viktor Szakats). Several warnings remain and are - unavoidable, where we test for overflow. - Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c - Fixed uninitialized variable in contrib/gregbook/rpng2-x.c - Moved config.h.in~ from the "libpng_autotools_files" list to the - "libpng_autotools_extra" list in autogen.sh because it was causing a - false positive for missing files (bug report by Robert C. Seacord). - Removed unreachable "break" statements in png.c, pngread.c, and pngrtran.c - to suppress clang warnings (Bug report by Viktor Szakats). - Fixed some bad links in the man page. - Changed "n bit" to "n-bit" in comments. - Added signed/unsigned 16-bit safety net. This removes the dubious - 0x8000 flag definitions on 16-bit systems. They aren't supported - yet the defs *probably* work, however it seems much safer to do this - and be advised if anyone, contrary to advice, is building libpng 1.6 - on a 16-bit system. It also adds back various switch default clauses - for GCC; GCC errors out if they are not present (with an appropriately - high level of warnings). - Safely convert num_bytes to a png_byte in png_set_sig_bytes() (Robert - Seacord). - Fixed the recently reported 1's complement security issue by replacing - the value that is illegal in the PNG spec, in both signed and unsigned - values, with 0. Illegal unsigned values (anything greater than or equal - to 0x80000000) can still pass through, but since these are not illegal - in ANSI-C (unlike 0x80000000 in the signed case) the checking that - occurs later can catch them (John Bowler). - Fixed png_save_int_32 when int is not 2's complement (John Bowler). - Updated libpng16 with all the recent test changes from libpng17, - including changes to pngvalid.c to ensure that the original, - distributed, version of contrib/visupng/cexcept.h can be used - (John Bowler). - pngvalid contains the correction to the use of SAVE/STORE_ - UNKNOWN_CHUNKS; a bug revealed by changes in libpng 1.7. More - tests contain the --strict option to detect warnings and the - pngvalid-standard test has been corrected so that it does not - turn on progressive-read. There is a separate test which does - that. (John Bowler) - Also made some signed/unsigned fixes. - Make pngstest error limits version specific. Splitting the machine - generated error structs out to a file allows the values to be updated - without changing pngstest.c itself. Since libpng 1.6 and 1.7 have - slightly different error limits this simplifies maintenance. The - makepngs.sh script has also been updated to more accurately reflect - current problems in libpng 1.7 (John Bowler). - Incorporated new test PNG files into make check. tests/pngstest-* - are changed so that the new test files are divided into 8 groups by - gamma and alpha channel. These tests have considerably better code - and pixel-value coverage than contrib/pngsuite; however,coverage is - still incomplete (John Bowler). - Removed the '--strict' in 1.6 because of the double-gamma-correction - warning, updated pngstest-errors.h for the errors detected with the - new contrib/testspngs PNG test files (John Bowler). - Worked around rgb-to-gray issues in libpng 1.6. The previous - attempts to ignore the errors in the code aren't quite enough to - deal with the 'channel selection' encoding added to libpng 1.7; abort. - Fixed 'pow' macros in pngvalid.c. It is legal for 'pow' to be a - macro, therefore the argument list cannot contain preprocessing - directives. Make sure pow is a function where this happens. This is - a minimal safe fix, the issue only arises in non-performance-critical - code (bug report by Curtis Leach, fix by John Bowler). - Added sPLT support to pngtest.c - Prevent setting or writing over-length PLTE chunk (Cosmin Truta). - Silently truncate over-length PLTE chunk while reading. - Libpng incorrectly calculated the output rowbytes when the application - decreased either the number of channels or the bit depth (or both) in - a user transform. This was safe; libpng overallocated buffer space - (potentially by quite a lot; up to 4 times the amount required) but, - from 1.5.4 on, resulted in a png_error (John Bowler). - Fixed some inconsequential cut-and-paste typos in png_set_cHRM_XYZ_fixed(). - Clarified COPYRIGHT information to state explicitly that versions - are derived from previous versions. - Removed much of the long list of previous versions from png.h and - libpng.3. - -Send comments/corrections/commendations to png-mng-implement at lists.sf.net -(subscription required; visit -https://lists.sourceforge.net/lists/listinfo/png-mng-implement -to subscribe) -or to glennrp at users.sourceforge.net - -Glenn R-P diff --git a/extern/libpng/CHANGES b/extern/libpng/CHANGES deleted file mode 100644 index 2e4d2bb29..000000000 --- a/extern/libpng/CHANGES +++ /dev/null @@ -1,5424 +0,0 @@ -#if 0 -CHANGES - changes for libpng - -version 0.1 [March 29, 1995] - initial work-in-progress release - -version 0.2 [April 1, 1995] - added reader into png.h - fixed small problems in stub file - -version 0.3 [April 8, 1995] - added pull reader - split up pngwrite.c to several files - added pnglib.txt - added example.c - cleaned up writer, adding a few new transformations - fixed some bugs in writer - interfaced with zlib 0.5 - added K&R support - added check for 64 KB blocks for 16 bit machines - -version 0.4 [April 26, 1995] - cleaned up code and commented code - simplified time handling into png_time - created png_color_16 and png_color_8 to handle color needs - cleaned up color type defines - fixed various bugs - made various names more consistent - interfaced with zlib 0.71 - cleaned up zTXt reader and writer (using zlib's Reset functions) - split transformations into pngrtran.c and pngwtran.c - -version 0.5 [April 30, 1995] - interfaced with zlib 0.8 - fixed many reading and writing bugs - saved using 3 spaces instead of tabs - -version 0.6 [May 1, 1995] - first beta release - added png_large_malloc() and png_large_free() - added png_size_t - cleaned up some compiler warnings - added png_start_read_image() - -version 0.7 [June 24, 1995] - cleaned up lots of bugs - finished dithering and other stuff - added test program - changed name from pnglib to libpng - -version 0.71 [June 26, 1995] - changed pngtest.png for zlib 0.93 - fixed error in libpng.txt and example.c - -version 0.8 [August 20, 1995] - cleaned up some bugs - added png_set_filler() - split up pngstub.c into pngmem.c, pngio.c, and pngerror.c - added #define's to remove unwanted code - moved png_info_init() to png.c - added old_size into png_realloc() - added functions to manually set filtering and compression info - changed compression parameters based on image type - optimized filter selection code - added version info - changed external functions passing floats to doubles (k&r problems?) - put all the configurable stuff in pngconf.h - enabled png_set_shift to work with paletted images on read - added png_read_update_info() - updates info structure with transformations - -Version 0.81 [August, 1995] - incorporated Tim Wegner's medium model code (thanks, Tim) - -Version 0.82 [September, 1995] - [unspecified changes] - -Version 0.85 [December, 1995] - added more medium model code (almost everything's a far) - added i/o, error, and memory callback functions - fixed some bugs (16-bit, 4-bit interlaced, etc.) - added first run progressive reader (barely tested) - -Version 0.86 [January, 1996] - fixed bugs - improved documentation - -Version 0.87 [January, 1996] - fixed medium model bugs - fixed other bugs introduced in 0.85 and 0.86 - added some minor documentation - -Version 0.88 [January, 1996] - fixed progressive bugs - replaced tabs with spaces - cleaned up documentation - added callbacks for read/write and warning/error functions - -Version 0.89 [June 5, 1996] - Added new initialization API to make libpng work better with shared libs - we now have png_create_read_struct(), png_create_write_struct(), - png_create_info_struct(), png_destroy_read_struct(), and - png_destroy_write_struct() instead of the separate calls to - malloc and png_read_init(), png_info_init(), and png_write_init() - Changed warning/error callback functions to fix bug - this means you - should use the new initialization API if you were using the old - png_set_message_fn() calls, and that the old API no longer exists - so that people are aware that they need to change their code - Changed filter selection API to allow selection of multiple filters - since it didn't work in previous versions of libpng anyways - Optimized filter selection code - Fixed png_set_background() to allow using an arbitrary RGB color for - paletted images - Fixed gamma and background correction for paletted images, so - png_correct_palette is not needed unless you are correcting an - external palette (you will need to #define PNG_CORRECT_PALETTE_SUPPORTED - in pngconf.h) - if nobody uses this, it may disappear in the future. - Fixed bug with Borland 64K memory allocation (Alexander Lehmann) - Fixed bug in interlace handling (Smarasderagd, I think) - Added more error checking for writing and image to reduce invalid files - Separated read and write functions so that they won't both be linked - into a binary when only reading or writing functionality is used - New pngtest image also has interlacing and zTXt - Updated documentation to reflect new API - -Version 0.89c [June 17, 1996] - Bug fixes. - -Version 0.90 [January, 1997] - Made CRC errors/warnings on critical and ancillary chunks configurable - libpng will use the zlib CRC routines by (compile-time) default - Changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner) - Added external C++ wrapper statements to png.h (Gilles Dauphin) - Allow PNG file to be read when some or all of file signature has already - been read from the beginning of the stream. ****This affects the size - of info_struct and invalidates all programs that use a shared libpng**** - Fixed png_filler() declarations - Fixed? background color conversions - Fixed order of error function pointers to match documentation - Current chunk name is now available in png_struct to reduce the number - of nearly identical error messages (will simplify multi-lingual - support when available) - Try to get ready for unknown-chunk callback functions: - - previously read critical chunks are flagged, so the chunk handling - routines can determine if the chunk is in the right place - - all chunk handling routines have the same prototypes, so we will - be able to handle all chunks via a callback mechanism - Try to fix Linux "setjmp" buffer size problems - Removed png_large_malloc, png_large_free, and png_realloc functions. - -Version 0.95 [March, 1997] - Fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never - Fixed bug in PNG file signature compares when start != 0 - Changed parameter type of png_set_filler(...filler...) from png_byte - to png_uint_32 - Added test for MACOS to ensure that both math.h and fp.h are not #included - Added macros for libpng to be compiled as a Windows DLL (Andreas Kupries) - Added "packswap" transformation, which changes the endianness of - packed-pixel bytes (Kevin Bracey) - Added "strip_alpha" transformation, which removes the alpha channel of - input images without using it (not necessarily a good idea) - Added "swap_alpha" transformation, which puts the alpha channel in front - of the color bytes instead of after - Removed all implicit variable tests which assume NULL == 0 (I think) - Changed several variables to "png_size_t" to show 16/32-bit limitations - Added new pCAL chunk read/write support - Added experimental filter selection weighting (Greg Roelofs) - Removed old png_set_rgbx() and png_set_xrgb() functions that have been - obsolete for about 2 years now (use png_set_filler() instead) - Added macros to read 16- and 32-bit ints directly from buffer, to be - used only on those systems that support it (namely PowerPC and 680x0) - With some testing, this may become the default for MACOS/PPC systems. - Only calculate CRC on data if we are going to use it - Added macros for zTXt compression type PNG_zTXt_COMPRESSION_??? - Added macros for simple libpng debugging output selectable at compile time - Removed PNG_READ_END_MODE in progressive reader (Smarasderagd) - More description of info_struct in libpng.txt and png.h - More instructions in example.c - More chunk types tested in pngtest.c - Renamed pngrcb.c to pngset.c, and all png_read_ functions to be - png_set_. We now have corresponding png_get_ - functions in pngget.c to get information in info_ptr. This isolates - the application from the internal organization of png_info_struct - (good for shared library implementations). - -Version 0.96 [May, 1997] - Fixed serious bug with < 8bpp images introduced in 0.95 - Fixed 256-color transparency bug (Greg Roelofs) - Fixed up documentation (Greg Roelofs, Laszlo Nyul) - Fixed "error" in pngconf.h for Linux setjmp() behavior - Fixed DOS medium model support (Tim Wegner) - Fixed png_check_keyword() for case with error in static string text - Added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul) - Added typecasts to quiet compiler errors - Added more debugging info - -Version 0.97 [January, 1998] - Removed PNG_USE_OWN_CRC capability - Relocated png_set_crc_action from pngrutil.c to pngrtran.c - Fixed typecasts of "new_key", etc. (Andreas Dilger) - Added RFC 1152 [sic] date support - Fixed bug in gamma handling of 4-bit grayscale - Added 2-bit grayscale gamma handling (Glenn R-P) - Added more typecasts. 65536L becomes (png_uint_32)65536L, etc. (Glenn R-P) - Minor corrections in libpng.txt - Added simple sRGB support (Glenn R-P) - Easier conditional compiling, e.g., - define PNG_READ/WRITE_NOT_FULLY_SUPPORTED; - all configurable options can be selected from command-line instead - of having to edit pngconf.h (Glenn R-P) - Fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P) - Added more conditions for png_do_background, to avoid changing - black pixels to background when a background is supplied and - no pixels are transparent - Repaired PNG_NO_STDIO behavior - Tested NODIV support and made it default behavior (Greg Roelofs) - Added "-m" option and PNGTEST_DEBUG_MEMORY to pngtest (John Bowler) - Regularized version numbering scheme and bumped shared-library major - version number to 2 to avoid problems with libpng 0.89 apps - (Greg Roelofs) - -Version 0.98 [January, 1998] - Cleaned up some typos in libpng.txt and in code documentation - Fixed memory leaks in pCAL chunk processing (Glenn R-P and John Bowler) - Cosmetic change "display_gamma" to "screen_gamma" in pngrtran.c - Changed recommendation about file_gamma for PC images to .51 from .45, - in example.c and libpng.txt, added comments to distinguish between - screen_gamma, viewing_gamma, and display_gamma. - Changed all references to RFC1152 to read RFC1123 and changed the - PNG_TIME_RFC1152_SUPPORTED macro to PNG_TIME_RFC1123_SUPPORTED - Added png_invert_alpha capability (Glenn R-P -- suggestion by Jon Vincent) - Changed srgb_intent from png_byte to int to avoid compiler bugs - -Version 0.99 [January 30, 1998] - Free info_ptr->text instead of end_info_ptr->text in pngread.c (John Bowler) - Fixed a longstanding "packswap" bug in pngtrans.c - Fixed some inconsistencies in pngconf.h that prevented compiling with - PNG_READ_GAMMA_SUPPORTED and PNG_READ_hIST_SUPPORTED undefined - Fixed some typos and made other minor rearrangement of libpng.txt (Andreas) - Changed recommendation about file_gamma for PC images to .50 from .51 in - example.c and libpng.txt, and changed file_gamma for sRGB images to .45 - Added a number of functions to access information from the png structure - png_get_image_height(), etc. (Glenn R-P, suggestion by Brad Pettit) - Added TARGET_MACOS similar to zlib-1.0.8 - Define PNG_ALWAYS_EXTERN when __MWERKS__ && WIN32 are defined - Added type casting to all png_malloc() function calls - -Version 0.99a [January 31, 1998] - Added type casts and parentheses to all returns that return a value.(Tim W.) - -Version 0.99b [February 4, 1998] - Added type cast png_uint_32 on malloc function calls where needed. - Changed type of num_hist from png_uint_32 to int (same as num_palette). - Added checks for rowbytes overflow, in case png_size_t is less than 32 bits. - Renamed makefile.elf to makefile.lnx. - -Version 0.99c [February 7, 1998] - More type casting. Removed erroneous overflow test in pngmem.c. - Added png_buffered_memcpy() and png_buffered_memset(), apply them to rowbytes. - Added UNIX manual pages libpng.3 (incorporating libpng.txt) and png.5. - -Version 0.99d [February 11, 1998] - Renamed "far_to_near()" "png_far_to_near()" - Revised libpng.3 - Version 99c "buffered" operations didn't work as intended. Replaced them - with png_memcpy_check() and png_memset_check(). - Added many "if (png_ptr == NULL) return" to quell compiler warnings about - unused png_ptr, mostly in pngget.c and pngset.c. - Check for overlength tRNS chunk present when indexed-color PLTE is read. - Cleaned up spelling errors in libpng.3/libpng.txt - Corrected a problem with png_get_tRNS() which returned undefined trans array - -Version 0.99e [February 28, 1998] - Corrected png_get_tRNS() again. - Add parentheses for easier reading of pngget.c, fixed "||" should be "&&". - Touched up example.c to make more of it compileable, although the entire - file still can't be compiled (Willem van Schaik) - Fixed a bug in png_do_shift() (Bryan Tsai) - Added a space in png.h prototype for png_write_chunk_start() - Replaced pngtest.png with one created with zlib 1.1.1 - Changed pngtest to report PASS even when file size is different (Jean-loup G.) - Corrected some logic errors in png_do_invert_alpha() (Chris Patterson) - -Version 0.99f [March 5, 1998] - Corrected a bug in pngpread() introduced in version 99c (Kevin Bracey) - Moved makefiles into a "scripts" directory, and added INSTALL instruction file - Added makefile.os2 and pngos2.def (A. Zabolotny) and makefile.s2x (W. Sebok) - Added pointers to "note on libpng versions" in makefile.lnx and README - Added row callback feature when reading and writing nonprogressive rows - and added a test of this feature in pngtest.c - Added user transform callbacks, with test of the feature in pngtest.c - -Version 0.99g [March 6, 1998, morning] - Minor changes to pngtest.c to suppress compiler warnings. - Removed "beta" language from documentation. - -Version 0.99h [March 6, 1998, evening] - Minor changes to previous minor changes to pngtest.c - Changed PNG_READ_NOT_FULLY_SUPPORTED to PNG_READ_TRANSFORMS_NOT_SUPPORTED - and added PNG_PROGRESSIVE_READ_NOT_SUPPORTED macro - Added user transform capability - -Version 1.00 [March 7, 1998] - Changed several typedefs in pngrutil.c - Added makefile.wat (Pawel Mrochen), updated makefile.tc3 (Willem van Schaik) - Replaced "while(1)" with "for(;;)" - Added PNGARG() to prototypes in pngtest.c and removed some prototypes - Updated some of the makefiles (Tom Lane) - Changed some typedefs (s_start, etc.) in pngrutil.c - Fixed dimensions of "short_months" array in pngwrite.c - Replaced ansi2knr.c with the one from jpeg-v6 - -Version 1.0.0 [March 8, 1998] - Changed name from 1.00 to 1.0.0 (Adam Costello) - Added smakefile.ppc (with SCOPTIONS.ppc) for Amiga PPC (Andreas Kleinert) - -Version 1.0.0a [March 9, 1998] - Fixed three bugs in pngrtran.c to make gamma+background handling consistent - (Greg Roelofs) - Changed format of the PNG_LIBPNG_VER integer to xyyzz instead of xyz - for major, minor, and bugfix releases. This is 10001. (Adam Costello, - Tom Lane) - Make months range from 1-12 in png_convert_to_rfc1123 - -Version 1.0.0b [March 13, 1998] - Quieted compiler complaints about two empty "for" loops in pngrutil.c - Minor changes to makefile.s2x - Removed #ifdef/#endif around a png_free() in pngread.c - -Version 1.0.1 [March 14, 1998] - Changed makefile.s2x to reduce security risk of using a relative pathname - Fixed some typos in the documentation (Greg). - Fixed a problem with value of "channels" returned by png_read_update_info() - -Version 1.0.1a [April 21, 1998] - Optimized Paeth calculations by replacing abs() function calls with intrinsics - plus other loop optimizations. Improves avg decoding speed by about 20%. - Commented out i386istic "align" compiler flags in makefile.lnx. - Reduced the default warning level in some makefiles, to make them consistent. - Removed references to IJG and JPEG in the ansi2knr.c copyright statement. - Fixed a bug in png_do_strip_filler with XXRRGGBB => RRGGBB transformation. - Added grayscale and 16-bit capability to png_do_read_filler(). - Fixed a bug in pngset.c, introduced in version 0.99c, that sets rowbytes - too large when writing an image with bit_depth < 8 (Bob Dellaca). - Corrected some bugs in the experimental weighted filtering heuristics. - Moved a misplaced pngrutil code block that truncates tRNS if it has more - than num_palette entries -- test was done before num_palette was defined. - Fixed a png_convert_to_rfc1123() bug that converts day 31 to 0 (Steve Eddins). - Changed compiler flags in makefile.wat for better optimization - (Pawel Mrochen). - -Version 1.0.1b [May 2, 1998] - Relocated png_do_gray_to_rgb() within png_do_read_transformations() (Greg). - Relocated the png_composite macros from pngrtran.c to png.h (Greg). - Added makefile.sco (contributed by Mike Hopkirk). - Fixed two bugs (missing definitions of "istop") introduced in libpng-1.0.1a. - Fixed a bug in pngrtran.c that would set channels=5 under some circumstances. - More work on the Paeth-filtering, achieving imperceptible speedup - (A Kleinert). - More work on loop optimization which may help when compiled with C++ - compilers. - Added warnings when people try to use transforms they've defined out. - Collapsed 4 "i" and "c" loops into single "i" loops in pngrtran and pngwtran. - Revised paragraph about png_set_expand() in libpng.txt and libpng.3 (Greg) - -Version 1.0.1c [May 11, 1998] - Fixed a bug in pngrtran.c (introduced in libpng-1.0.1a) where the masks for - filler bytes should have been 0xff instead of 0xf. - Added max_pixel_depth=32 in pngrutil.c when using FILLER with palette images. - Moved PNG_WRITE_WEIGHTED_FILTER_SUPPORTED and PNG_WRITE_FLUSH_SUPPORTED - out of the PNG_WRITE_TRANSFORMS_NOT_SUPPORTED block of pngconf.h - Added "PNG_NO_WRITE_TRANSFORMS" etc., as alternatives for *_NOT_SUPPORTED, - for consistency, in pngconf.h - Added individual "ifndef PNG_NO_[CAPABILITY]" in pngconf.h to make it easier - to remove unwanted capabilities via the compile line - Made some corrections to grammar (which, it's) in documentation (Greg). - Corrected example.c, use of row_pointers in png_write_image(). - -Version 1.0.1d [May 24, 1998] - Corrected several statements that used side effects illegally in pngrutil.c - and pngtrans.c, that were introduced in version 1.0.1b - Revised png_read_rows() to avoid repeated if-testing for NULL (A Kleinert) - More corrections to example.c, use of row_pointers in png_write_image() - and png_read_rows(). - Added pngdll.mak and pngdef.pas to scripts directory, contributed by - Bob Dellaca, to make a png32bd.dll with Borland C++ 4.5 - Fixed error in example.c with png_set_text: num_text is 3, not 2 (Guido V.) - Changed several loops from count-down to count-up, for consistency. - -Version 1.0.1e [June 6, 1998] - Revised libpng.txt and libpng.3 description of png_set_read|write_fn(), and - added warnings when people try to set png_read_fn and png_write_fn in - the same structure. - Added a test such that png_do_gamma will be done when num_trans==0 - for truecolor images that have defined a background. This corrects an - error that was introduced in libpng-0.90 that can cause gamma processing - to be skipped. - Added tests in png.h to include "trans" and "trans_values" in structures - when PNG_READ_BACKGROUND_SUPPORTED or PNG_READ_EXPAND_SUPPORTED is defined. - Add png_free(png_ptr->time_buffer) in png_destroy_read_struct() - Moved png_convert_to_rfc_1123() from pngwrite.c to png.c - Added capability for user-provided malloc_fn() and free_fn() functions, - and revised pngtest.c to demonstrate their use, replacing the - PNGTEST_DEBUG_MEM feature. - Added makefile.w32, for Microsoft C++ 4.0 and later (Tim Wegner). - -Version 1.0.2 [June 14, 1998] - Fixed two bugs in makefile.bor . - -Version 1.0.2a [December 30, 1998] - Replaced and extended code that was removed from png_set_filler() in 1.0.1a. - Fixed a bug in png_do_filler() that made it fail to write filler bytes in - the left-most pixel of each row (Kevin Bracey). - Changed "static pngcharp tIME_string" to "static char tIME_string[30]" - in pngtest.c (Duncan Simpson). - Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk - even when no tIME chunk was present in the source file. - Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit. - Fixed a problem in png_read_push_finish_row(), which would not skip some - passes that it should skip, for images that are less than 3 pixels high. - Interchanged the order of calls to png_do_swap() and png_do_shift() - in pngwtran.c (John Cromer). - Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h . - Changed "bad adaptive filter type" from error to warning in pngrutil.c . - Fixed a documentation error about default filtering with 8-bit indexed-color. - Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO - (L. Peter Deutsch). - Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions. - Added png_get_copyright() and png_get_header_version() functions. - Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c - Added information about debugging in libpng.txt and libpng.3 . - Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and - makefile.sco. - Removed lines after Dynamic Dependencies" in makefile.aco . - Revised makefile.dec to make a shared library (Jeremie Petit). - Removed trailing blanks from all files. - -Version 1.0.2a [January 6, 1999] - Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h - Added "if" tests to silence complaints about unused png_ptr in png.h and png.c - Changed "check_if_png" function in example.c to return true (nonzero) if PNG. - Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig() - which is obsolete. - -Version 1.0.3 [January 14, 1999] - Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice) - Added a statement of Y2K compliance in png.h, libpng.3, and Y2KINFO. - -Version 1.0.3a [August 12, 1999] - Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning - if an attempt is made to read an interlaced image when it's not supported. - Added check if png_ptr->trans is defined before freeing it in pngread.c - Modified the Y2K statement to include versions back to version 0.71 - Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c - Modified makefile.wat (added -zp8 flag, ".symbolic", changed some comments) - Replaced leading blanks with tab characters in makefile.hux - Changed "dworkin.wustl.edu" to "ccrc.wustl.edu" in various documents. - Changed (float)red and (float)green to (double)red, (double)green - in png_set_rgb_to_gray() to avoid "promotion" problems in AIX. - Fixed a bug in pngconf.h that omitted when PNG_DEBUG==0 (K Bracey). - Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt). - Updated documentation to refer to the PNG-1.2 specification. - Removed ansi2knr.c and left pointers to the latest source for ansi2knr.c - in makefile.knr, INSTALL, and README (L. Peter Deutsch) - Fixed bugs in calculation of the length of rowbytes when adding alpha - channels to 16-bit images, in pngrtran.c (Chris Nokleberg) - Added function png_set_user_transform_info() to store user_transform_ptr, - user_depth, and user_channels into the png_struct, and a function - png_get_user_transform_ptr() to retrieve the pointer (Chris Nokleberg) - Added function png_set_empty_plte_permitted() to make libpng useable - in MNG applications. - Corrected the typedef for png_free_ptr in png.h (Jesse Jones). - Correct gamma with srgb is 45455 instead of 45000 in pngrutil.c, to be - consistent with PNG-1.2, and allow variance of 500 before complaining. - Added assembler code contributed by Intel in file pngvcrd.c and modified - makefile.w32 to use it (Nirav Chhatrapati, INTEL Corporation, - Gilles Vollant) - Changed "ln -s -f" to "ln -f -s" in the makefiles to make Solaris happy. - Added some aliases for png_set_expand() in pngrtran.c, namely - png_set_expand_PLTE(), png_set_expand_depth(), and png_set_expand_tRNS() - (Greg Roelofs, in "PNG: The Definitive Guide"). - Added makefile.beo for BEOS on X86, contributed by Sander Stok. - -Version 1.0.3b [August 26, 1999] - Replaced 2147483647L several places with PNG_MAX_UINT macro, defined in png.h - Changed leading blanks to tabs in all makefiles. - Define PNG_USE_PNGVCRD in makefile.w32, to get MMX assembler code. - Made alternate versions of png_set_expand() in pngrtran.c, namely - png_set_gray_1_2_4_to_8, png_set_palette_to_rgb, and png_set_tRNS_to_alpha - (Greg Roelofs, in "PNG: The Definitive Guide"). Deleted the 1.0.3a aliases. - Relocated start of 'extern "C"' block in png.h so it doesn't include pngconf.h - Revised calculation of num_blocks in pngmem.c to avoid a potentially - negative shift distance, whose results are undefined in the C language. - Added a check in pngset.c to prevent writing multiple tIME chunks. - Added a check in pngwrite.c to detect invalid small window_bits sizes. - -Version 1.0.3d [September 4, 1999] - Fixed type casting of igamma in pngrutil.c - Added new png_expand functions to scripts/pngdef.pas and pngos2.def - Added a demo read_user_transform_fn that examines the row filters in pngtest.c - -Version 1.0.4 [September 24, 1999, not distributed publicly] - Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined - Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h - Made several minor corrections to pngtest.c - Renamed the makefiles with longer but more user friendly extensions. - Copied the PNG copyright and license to a separate LICENSE file. - Revised documentation, png.h, and example.c to remove reference to - "viewing_gamma" which no longer appears in the PNG specification. - Revised pngvcrd.c to use MMX code for interlacing only on the final pass. - Updated pngvcrd.c to use the faster C filter algorithms from libpng-1.0.1a - Split makefile.win32vc into two versions, makefile.vcawin32 (uses MMX - assembler code) and makefile.vcwin32 (doesn't). - Added a CPU timing report to pngtest.c (enabled by defining PNGTEST_TIMING) - Added a copy of pngnow.png to the distribution. - -Version 1.0.4a [September 25, 1999] - Increase max_pixel_depth in pngrutil.c if a user transform needs it. - Changed several division operations to right-shifts in pngvcrd.c - -Version 1.0.4b [September 30, 1999] - Added parentheses in line 3732 of pngvcrd.c - Added a comment in makefile.linux warning about buggy -O3 in pgcc 2.95.1 - -Version 1.0.4c [October 1, 1999] - Added a "png_check_version" function in png.c and pngtest.c that will generate - a helpful compiler error if an old png.h is found in the search path. - Changed type of png_user_transform_depth|channels from int to png_byte. - Added "Libpng is OSI Certified Open Source Software" statement to png.h - -Version 1.0.4d [October 6, 1999] - Changed 0.45 to 0.45455 in png_set_sRGB() - Removed unused PLTE entries from pngnow.png - Re-enabled some parts of pngvcrd.c (png_combine_row) that work properly. - -Version 1.0.4e [October 10, 1999] - Fixed sign error in pngvcrd.c (Greg Roelofs) - Replaced some instances of memcpy with simple assignments in pngvcrd (GR-P) - -Version 1.0.4f [October 15, 1999] - Surrounded example.c code with #if 0 .. #endif to prevent people from - inadvertently trying to compile it. - Changed png_get_header_version() from a function to a macro in png.h - Added type casting mostly in pngrtran.c and pngwtran.c - Removed some pointless "ptr = NULL" in pngmem.c - Added a "contrib" directory containing the source code from Greg's book. - -Version 1.0.5 [October 15, 1999] - Minor editing of the INSTALL and README files. - -Version 1.0.5a [October 23, 1999] - Added contrib/pngsuite and contrib/pngminus (Willem van Schaik) - Fixed a typo in the png_set_sRGB() function call in example.c (Jan Nijtmans) - Further optimization and bugfix of pngvcrd.c - Revised pngset.c so that it does not allocate or free memory in the user's - text_ptr structure. Instead, it makes its own copy. - Created separate write_end_info_struct in pngtest.c for a more severe test. - Added code in pngwrite.c to free info_ptr->text[i].key to stop a memory leak. - -Version 1.0.5b [November 23, 1999] - Moved PNG_FLAG_HAVE_CHUNK_HEADER, PNG_FLAG_BACKGROUND_IS_GRAY and - PNG_FLAG_WROTE_tIME from flags to mode. - Added png_write_info_before_PLTE() function. - Fixed some typecasting in contrib/gregbook/*.c - Updated scripts/makevms.com and added makevms.com to contrib/gregbook - and contrib/pngminus (Martin Zinser) - -Version 1.0.5c [November 26, 1999] - Moved png_get_header_version from png.h to png.c, to accommodate ansi2knr. - Removed all global arrays (according to PNG_NO_GLOBAL_ARRAYS macro), to - accommodate making DLL's: Moved usr_png_ver from global variable to function - png_get_header_ver() in png.c. Moved png_sig to png_sig_bytes in png.c and - eliminated use of png_sig in pngwutil.c. Moved the various png_CHNK arrays - into pngtypes.h. Eliminated use of global png_pass arrays. Declared the - png_CHNK and png_pass arrays to be "const". Made the global arrays - available to applications (although none are used in libpng itself) when - PNG_NO_GLOBAL_ARRAYS is not defined or when PNG_GLOBAL_ARRAYS is defined. - Removed some extraneous "-I" from contrib/pngminus/makefile.std - Changed the PNG_sRGB_INTENT macros in png.h to be consistent with PNG-1.2. - Change PNG_SRGB_INTENT to PNG_sRGB_INTENT in libpng.txt and libpng.3 - -Version 1.0.5d [November 29, 1999] - Add type cast (png_const_charp) two places in png.c - Eliminated pngtypes.h; use macros instead to declare PNG_CHNK arrays. - Renamed "PNG_GLOBAL_ARRAYS" to "PNG_USE_GLOBAL_ARRAYS" and made available - to applications a macro "PNG_USE_LOCAL_ARRAYS". - comment out (with #ifdef) all the new declarations when - PNG_USE_GLOBAL_ARRAYS is defined. - Added PNG_EXPORT_VAR macro to accommodate making DLL's. - -Version 1.0.5e [November 30, 1999] - Added iCCP, iTXt, and sPLT support; added "lang" member to the png_text - structure; refactored the inflate/deflate support to make adding new chunks - with trailing compressed parts easier in the future, and added new functions - png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP, - png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond). - NOTE: Applications that write text chunks MUST define png_text->lang - before calling png_set_text(). It must be set to NULL if you want to - write tEXt or zTXt chunks. If you want your application to be able to - run with older versions of libpng, use - - #ifdef PNG_iTXt_SUPPORTED - png_text[i].lang = NULL; - #endif - - Changed png_get_oFFs() and png_set_oFFs() to use signed rather than unsigned - offsets (Eric S. Raymond). - Combined PNG_READ_cHNK_SUPPORTED and PNG_WRITE_cHNK_SUPPORTED macros into - PNG_cHNK_SUPPORTED and combined the three types of PNG_text_SUPPORTED - macros, leaving the separate macros also available. - Removed comments on #endifs at the end of many short, non-nested #if-blocks. - -Version 1.0.5f [December 6, 1999] - Changed makefile.solaris to issue a warning about potential problems when - the ucb "ld" is in the path ahead of the ccs "ld". - Removed "- [date]" from the "synopsis" line in libpng.3 and libpngpf.3. - Added sCAL chunk support (Eric S. Raymond). - -Version 1.0.5g [December 7, 1999] - Fixed "png_free_spallettes" typo in png.h - Added code to handle new chunks in pngpread.c - Moved PNG_CHNK string macro definitions outside of PNG_NO_EXTERN block - Added "translated_key" to png_text structure and png_write_iTXt(). - Added code in pngwrite.c to work around a newly discovered zlib bug. - -Version 1.0.5h [December 10, 1999] - NOTE: regarding the note for version 1.0.5e, the following must also - be included in your code: - png_text[i].translated_key = NULL; - Unknown chunk handling is now supported. - Option to eliminate all floating point support was added. Some new - fixed-point functions such as png_set_gAMA_fixed() were added. - Expanded tabs and removed trailing blanks in source files. - -Version 1.0.5i [December 13, 1999] - Added some type casts to silence compiler warnings. - Renamed "png_free_spalette" to "png_free_spalettes" for consistency. - Removed leading blanks from a #define in pngvcrd.c - Added some parameters to the new png_set_keep_unknown_chunks() function. - Added a test for up->location != 0 in the first instance of writing - unknown chunks in pngwrite.c - Changed "num" to "i" in png_free_spalettes() and png_free_unknowns() to - prevent recursion. - Added png_free_hIST() function. - Various patches to fix bugs in the sCAL and integer cHRM processing, - and to add some convenience macros for use with sCAL. - -Version 1.0.5j [December 21, 1999] - Changed "unit" parameter of png_write_sCAL from png_byte to int, to work - around buggy compilers. - Added new type "png_fixed_point" for integers that hold float*100000 values - Restored backward compatibility of tEXt/zTXt chunk processing: - Restored the first four members of png_text to the same order as v.1.0.5d. - Added members "lang_key" and "itxt_length" to png_text struct. Set - text_length=0 when "text" contains iTXt data. Use the "compression" - member to distinguish among tEXt/zTXt/iTXt types. Added - PNG_ITXT_COMPRESSION_NONE (1) and PNG_ITXT_COMPRESSION_zTXt(2) macros. - The "Note" above, about backward incompatibility of libpng-1.0.5e, no - longer applies. - Fixed png_read|write_iTXt() to read|write parameters in the right order, - and to write the iTXt chunk after IDAT if it appears in the end_ptr. - Added pnggccrd.c, version of pngvcrd.c Intel assembler for gcc (Greg Roelofs) - Reversed the order of trying to write floating-point and fixed-point gAMA. - -Version 1.0.5k [December 27, 1999] - Added many parentheses, e.g., "if (a && b & c)" becomes "if (a && (b & c))" - Added png_handle_as_unknown() function (Glenn) - Added png_free_chunk_list() function and chunk_list and num_chunk_list members - of png_ptr. - Eliminated erroneous warnings about multiple sPLT chunks and sPLT-after-PLTE. - Fixed a libpng-1.0.5h bug in pngrutil.c that was issuing erroneous warnings - about ignoring incorrect gAMA with sRGB (gAMA was in fact not ignored) - Added png_free_tRNS(); png_set_tRNS() now malloc's its own trans array (ESR). - Define png_get_int_32 when oFFs chunk is supported as well as when pCAL is. - Changed type of proflen from png_int_32 to png_uint_32 in png_get_iCCP(). - -Version 1.0.5l [January 1, 2000] - Added functions png_set_read_user_chunk_fn() and png_get_user_chunk_ptr() - for setting a callback function to handle unknown chunks and for - retrieving the associated user pointer (Glenn). - -Version 1.0.5m [January 7, 2000] - Added high-level functions png_read_png(), png_write_png(), png_free_pixels(). - -Version 1.0.5n [January 9, 2000] - Added png_free_PLTE() function, and modified png_set_PLTE() to malloc its - own memory for info_ptr->palette. This makes it safe for the calling - application to free its copy of the palette any time after it calls - png_set_PLTE(). - -Version 1.0.5o [January 20, 2000] - Cosmetic changes only (removed some trailing blanks and TABs) - -Version 1.0.5p [January 31, 2000] - Renamed pngdll.mak to makefile.bd32 - Cosmetic changes in pngtest.c - -Version 1.0.5q [February 5, 2000] - Relocated the makefile.solaris warning about PATH problems. - Fixed pngvcrd.c bug by pushing/popping registers in mmxsupport (Bruce Oberg) - Revised makefile.gcmmx - Added PNG_SETJMP_SUPPORTED, PNG_SETJMP_NOT_SUPPORTED, and PNG_ABORT() macros - -Version 1.0.5r [February 7, 2000] - Removed superfluous prototype for png_get_itxt from png.h - Fixed a bug in pngrtran.c that improperly expanded the background color. - Return *num_text=0 from png_get_text() when appropriate, and fix documentation - of png_get_text() in libpng.txt/libpng.3. - -Version 1.0.5s [February 18, 2000] - Added "png_jmp_env()" macro to pngconf.h, to help people migrate to the - new error handler that's planned for the next libpng release, and changed - example.c, pngtest.c, and contrib programs to use this macro. - Revised some of the DLL-export macros in pngconf.h (Greg Roelofs) - Fixed a bug in png_read_png() that caused it to fail to expand some images - that it should have expanded. - Fixed some mistakes in the unused and undocumented INCH_CONVERSIONS functions - in pngget.c - Changed the allocation of palette, history, and trans arrays back to - the version 1.0.5 method (linking instead of copying) which restores - backward compatibility with version 1.0.5. Added some remarks about - that in example.c. Added "free_me" member to info_ptr and png_ptr - and added png_free_data() function. - Updated makefile.linux and makefile.gccmmx to make directories conditionally. - Made cosmetic changes to pngasmrd.h - Added png_set_rows() and png_get_rows(), for use with png_read|write_png(). - Modified png_read_png() to allocate info_ptr->row_pointers only if it - hasn't already been allocated. - -Version 1.0.5t [March 4, 2000] - Changed png_jmp_env() migration aiding macro to png_jmpbuf(). - Fixed "interlace" typo (should be "interlaced") in contrib/gregbook/read2-x.c - Fixed bug with use of PNG_BEFORE_IHDR bit in png_ptr->mode, introduced when - PNG_FLAG_HAVE_CHUNK_HEADER was moved into png_ptr->mode in version 1.0.5b - Files in contrib/gregbook were revised to use png_jmpbuf() and to select - a 24-bit visual if one is available, and to allow abbreviated options. - Files in contrib/pngminus were revised to use the png_jmpbuf() macro. - Removed spaces in makefile.linux and makefile.gcmmx, introduced in 1.0.5s - -Version 1.0.5u [March 5, 2000] - Simplified the code that detects old png.h in png.c and pngtest.c - Renamed png_spalette (_p, _pp) to png_sPLT_t (_tp, _tpp) - Increased precision of rgb_to_gray calculations from 8 to 15 bits and - added png_set_rgb_to_gray_fixed() function. - Added makefile.bc32 (32-bit Borland C++, C mode) - -Version 1.0.5v [March 11, 2000] - Added some parentheses to the png_jmpbuf macro definition. - Updated references to the zlib home page, which has moved to freesoftware.com. - Corrected bugs in documentation regarding png_read_row() and png_write_row(). - Updated documentation of png_rgb_to_gray calculations in libpng.3/libpng.txt. - Renamed makefile.borland,turboc3 back to makefile.bor,tc3 as in version 1.0.3, - revised borland makefiles; added makefile.ibmvac3 and makefile.gcc (Cosmin) - -Version 1.0.6 [March 20, 2000] - Minor revisions of makefile.bor, libpng.txt, and gregbook/rpng2-win.c - Added makefile.sggcc (SGI IRIX with gcc) - -Version 1.0.6d [April 7, 2000] - Changed sprintf() to strcpy() in png_write_sCAL_s() to work without STDIO - Added data_length parameter to png_decompress_chunk() function - Revised documentation to remove reference to abandoned png_free_chnk functions - Fixed an error in png_rgb_to_gray_fixed() - Revised example.c, usage of png_destroy_write_struct(). - Renamed makefile.ibmvac3 to makefile.ibmc, added libpng.icc IBM project file - Added a check for info_ptr->free_me&PNG_FREE_TEXT when freeing text in png.c - Simplify png_sig_bytes() function to remove use of non-ISO-C strdup(). - -Version 1.0.6e [April 9, 2000] - Added png_data_freer() function. - In the code that checks for over-length tRNS chunks, added check of - info_ptr->num_trans as well as png_ptr->num_trans (Matthias Benckmann) - Minor revisions of libpng.txt/libpng.3. - Check for existing data and free it if the free_me flag is set, in png_set_*() - and png_handle_*(). - Only define PNG_WEIGHTED_FILTERS_SUPPORTED when PNG_FLOATING_POINT_SUPPORTED - is defined. - Changed several instances of PNG_NO_CONSOLE_ID to PNG_NO_STDIO in pngrutil.c - and mentioned the purposes of the two macros in libpng.txt/libpng.3. - -Version 1.0.6f [April 14, 2000] - Revised png_set_iCCP() and png_set_rows() to avoid prematurely freeing data. - Add checks in png_set_text() for NULL members of the input text structure. - Revised libpng.txt/libpng.3. - Removed superfluous prototype for png_set_iTXt from png.h - Removed "else" from pngread.c, after png_error(), and changed "0" to "length". - Changed several png_errors about malformed ancillary chunks to png_warnings. - -Version 1.0.6g [April 24, 2000] - Added png_pass-* arrays to pnggccrd.c when PNG_USE_LOCAL_ARRAYS is defined. - Relocated paragraph about png_set_background() in libpng.3/libpng.txt - and other revisions (Matthias Benckmann) - Relocated info_ptr->free_me, png_ptr->free_me, and other info_ptr and - png_ptr members to restore binary compatibility with libpng-1.0.5 - (breaks compatibility with libpng-1.0.6). - -Version 1.0.6h [April 24, 2000] - Changed shared library so-number pattern from 2.x.y.z to xy.z (this builds - libpng.so.10 & libpng.so.10.6h instead of libpng.so.2 & libpng.so.2.1.0.6h) - This is a temporary change for test purposes. - -Version 1.0.6i [May 2, 2000] - Rearranged some members at the end of png_info and png_struct, to put - unknown_chunks_num and free_me within the original size of the png_structs - and free_me, png_read_user_fn, and png_free_fn within the original png_info, - because some old applications allocate the structs directly instead of - using png_create_*(). - Added documentation of user memory functions in libpng.txt/libpng.3 - Modified png_read_png so that it will use user_allocated row_pointers - if present, unless free_me directs that it be freed, and added description - of the use of png_set_rows() and png_get_rows() in libpng.txt/libpng.3. - Added PNG_LEGACY_SUPPORTED macro, and #ifdef out all new (since version - 1.00) members of png_struct and png_info, to regain binary compatibility - when you define this macro. Capabilities lost in this event - are user transforms (new in version 1.0.0),the user transform pointer - (new in version 1.0.2), rgb_to_gray (new in 1.0.5), iCCP, sCAL, sPLT, - the high-level interface, and unknown chunks support (all new in 1.0.6). - This was necessary because of old applications that allocate the structs - directly as authors were instructed to do in libpng-0.88 and earlier, - instead of using png_create_*(). - Added modes PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT which - can be used to detect codes that directly allocate the structs, and - code to check these modes in png_read_init() and png_write_init() and - generate a libpng error if the modes aren't set and PNG_LEGACY_SUPPORTED - was not defined. - Added makefile.intel and updated makefile.watcom (Pawel Mrochen) - -Version 1.0.6j [May 3, 2000] - Overloaded png_read_init() and png_write_init() with macros that convert - calls to png_read_init_2() or png_write_init_2() that check the version - and structure sizes. - -Version 1.0.7beta11 [May 7, 2000] - Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes - which are no longer used. - Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is - defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXT_SUPPORTED - is defined. - Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory - overrun when old applications fill the info_ptr->text structure directly. - Added PNGAPI macro, and added it to the definitions of all exported functions. - Relocated version macro definitions ahead of the includes of zlib.h and - pngconf.h in png.h. - -Version 1.0.7beta12 [May 12, 2000] - Revised pngset.c to avoid a problem with expanding the png_debug macro. - Deleted some extraneous defines from pngconf.h - Made PNG_NO_CONSOLE_IO the default condition when PNG_BUILD_DLL is defined. - Use MSC _RPTn debugging instead of fprintf if _MSC_VER is defined. - Added png_access_version_number() function. - Check for mask&PNG_FREE_CHNK (for TEXT, SCAL, PCAL) in png_free_data(). - Expanded libpng.3/libpng.txt information about png_data_freer(). - -Version 1.0.7beta14 [May 17, 2000] (beta13 was not published) - Changed pnggccrd.c and pngvcrd.c to handle bad adaptive filter types as - warnings instead of errors, as pngrutil.c does. - Set the PNG_INFO_IDAT valid flag in png_set_rows() so png_write_png() - will actually write IDATs. - Made the default PNG_USE_LOCAL_ARRAYS depend on PNG_DLL instead of WIN32. - Make png_free_data() ignore its final parameter except when freeing data - that can have multiple instances (text, sPLT, unknowns). - Fixed a new bug in png_set_rows(). - Removed info_ptr->valid tests from png_free_data(), as in version 1.0.5. - Added png_set_invalid() function. - Fixed incorrect illustrations of png_destroy_write_struct() in example.c. - -Version 1.0.7beta15 [May 30, 2000] - Revised the deliberately erroneous Linux setjmp code in pngconf.h to produce - fewer error messages. - Rearranged checks for Z_OK to check the most likely path first in pngpread.c - and pngwutil.c. - Added checks in pngtest.c for png_create_*() returning NULL, and mentioned - in libpng.txt/libpng.3 the need for applications to check this. - Changed names of png_default_*() functions in pngtest to pngtest_*(). - Changed return type of png_get_x|y_offset_*() from png_uint_32 to png_int_32. - Fixed some bugs in the unused PNG_INCH_CONVERSIONS functions in pngget.c - Set each pointer to NULL after freeing it in png_free_data(). - Worked around a problem in pngconf.h; AIX's strings.h defines an "index" - macro that conflicts with libpng's png_color_16.index. (Dimitri - Papadapoulos) - Added "msvc" directory with MSVC++ project files (Simon-Pierre Cadieux). - -Version 1.0.7beta16 [June 4, 2000] - Revised the workaround of AIX string.h "index" bug. - Added a check for overlength PLTE chunk in pngrutil.c. - Added PNG_NO_POINTER_INDEXING macro to use array-indexing instead of pointer - indexing in pngrutil.c and pngwutil.c to accommodate a buggy compiler. - Added a warning in png_decompress_chunk() when it runs out of data, e.g. - when it tries to read an erroneous PhotoShop iCCP chunk. - Added PNG_USE_DLL macro. - Revised the copyright/disclaimer/license notice. - Added contrib/msvctest directory - -Version 1.0.7rc1 [June 9, 2000] - Corrected the definition of PNG_TRANSFORM_INVERT_ALPHA (0x0400 not 0x0200) - Added contrib/visupng directory (Willem van Schaik) - -Version 1.0.7beta18 [June 23, 2000] - Revised PNGAPI definition, and pngvcrd.c to work with __GCC__ - and do not redefine PNGAPI if it is passed in via a compiler directive. - Revised visupng/PngFile.c to remove returns from within the Try block. - Removed leading underscores from "_PNG_H" and "_PNG_SAVE_BSD_SOURCE" macros. - Updated contrib/visupng/cexcept.h to version 1.0.0. - Fixed bugs in pngwrite.c and pngwutil.c that prevented writing iCCP chunks. - -Version 1.0.7rc2 [June 28, 2000] - Updated license to include disclaimers required by UCITA. - Fixed "DJBPP" typo in pnggccrd.c introduced in beta18. - -Version 1.0.7 [July 1, 2000] - Revised the definition of "trans_values" in libpng.3/libpng.txt - -Version 1.0.8beta1 [July 8, 2000] - Added png_free(png_ptr, key) two places in pngpread.c to stop memory leaks. - Changed PNG_NO_STDIO to PNG_NO_CONSOLE_IO, several places in pngrutil.c and - pngwutil.c. - Changed PNG_EXPORT_VAR to use PNG_IMPEXP, in pngconf.h. - Removed unused "#include " from png.c - Added WindowsCE support. - Revised pnggccrd.c to work with gcc-2.95.2 and in the Cygwin environment. - -Version 1.0.8beta2 [July 10, 2000] - Added project files to the wince directory and made further revisions - of pngtest.c, pngrio.c, and pngwio.c in support of WindowsCE. - -Version 1.0.8beta3 [July 11, 2000] - Only set the PNG_FLAG_FREE_TRNS or PNG_FREE_TRNS flag in png_handle_tRNS() - for indexed-color input files to avoid potential double-freeing trans array - under some unusual conditions; problem was introduced in version 1.0.6f. - Further revisions to pngtest.c and files in the wince subdirectory. - -Version 1.0.8beta4 [July 14, 2000] - Added the files pngbar.png and pngbar.jpg to the distribution. - Added makefile.cygwin, and cygwin support in pngconf.h - Added PNG_NO_ZALLOC_ZERO macro (makes png_zalloc skip zeroing memory) - -Version 1.0.8rc1 [July 16, 2000] - Revised png_debug() macros and statements to eliminate compiler warnings. - -Version 1.0.8 [July 24, 2000] - Added png_flush() in pngwrite.c, after png_write_IEND(). - Updated makefile.hpux to build a shared library. - -Version 1.0.9beta1 [November 10, 2000] - Fixed typo in scripts/makefile.hpux - Updated makevms.com in scripts and contrib/* and contrib/* (Martin Zinser) - Fixed seqence-point bug in contrib/pngminus/png2pnm (Martin Zinser) - Changed "cdrom.com" in documentation to "libpng.org" - Revised pnggccrd.c to get it all working, and updated makefile.gcmmx (Greg). - Changed type of "params" from voidp to png_voidp in png_read|write_png(). - Make sure PNGAPI and PNG_IMPEXP are defined in pngconf.h. - Revised the 3 instances of WRITEFILE in pngtest.c. - Relocated "msvc" and "wince" project subdirectories into "dll" subdirectory. - Updated png.rc in dll/msvc project - Revised makefile.dec to define and use LIBPATH and INCPATH - Increased size of global png_libpng_ver[] array from 12 to 18 chars. - Made global png_libpng_ver[], png_sig[] and png_pass_*[] arrays const. - Removed duplicate png_crc_finish() from png_handle_bKGD() function. - Added a warning when application calls png_read_update_info() multiple times. - Revised makefile.cygwin - Fixed bugs in iCCP support in pngrutil.c and pngwutil.c. - Replaced png_set_empty_plte_permitted() with png_permit_mng_features(). - -Version 1.0.9beta2 [November 19, 2000] - Renamed the "dll" subdirectory "projects". - Added borland project files to "projects" subdirectory. - Set VS_FF_PRERELEASE and VS_FF_PATCHED flags in msvc/png.rc when appropriate. - Add error message in png_set_compression_buffer_size() when malloc fails. - -Version 1.0.9beta3 [November 23, 2000] - Revised PNG_LIBPNG_BUILD_TYPE macro in png.h, used in the msvc project. - Removed the png_flush() in pngwrite.c that crashes some applications - that don't set png_output_flush_fn. - Added makefile.macosx and makefile.aix to scripts directory. - -Version 1.0.9beta4 [December 1, 2000] - Change png_chunk_warning to png_warning in png_check_keyword(). - Increased the first part of msg buffer from 16 to 18 in png_chunk_error(). - -Version 1.0.9beta5 [December 15, 2000] - Added support for filter method 64 (for PNG datastreams embedded in MNG). - -Version 1.0.9beta6 [December 18, 2000] - Revised png_set_filter() to accept filter method 64 when appropriate. - Added new PNG_HAVE_PNG_SIGNATURE bit to png_ptr->mode and use it to - help prevent applications from using MNG features in PNG datastreams. - Added png_permit_mng_features() function. - Revised libpng.3/libpng.txt. Changed "filter type" to "filter method". - -Version 1.0.9rc1 [December 23, 2000] - Revised test for PNG_HAVE_PNG_SIGNATURE in pngrutil.c - Fixed error handling of unknown compression type in png_decompress_chunk(). - In pngconf.h, define __cdecl when _MSC_VER is defined. - -Version 1.0.9beta7 [December 28, 2000] - Changed PNG_TEXT_COMPRESSION_zTXt to PNG_COMPRESSION_TYPE_BASE several places. - Revised memory management in png_set_hIST and png_handle_hIST in a backward - compatible manner. PLTE and tRNS were revised similarly. - Revised the iCCP chunk reader to ignore trailing garbage. - -Version 1.0.9beta8 [January 12, 2001] - Moved pngasmrd.h into pngconf.h. - Improved handling of out-of-spec garbage iCCP chunks generated by PhotoShop. - -Version 1.0.9beta9 [January 15, 2001] - Added png_set_invalid, png_permit_mng_features, and png_mmx_supported to - wince and msvc project module definition files. - Minor revision of makefile.cygwin. - Fixed bug with progressive reading of narrow interlaced images in pngpread.c - -Version 1.0.9beta10 [January 16, 2001] - Do not typedef png_FILE_p in pngconf.h when PNG_NO_STDIO is defined. - Fixed "png_mmx_supported" typo in project definition files. - -Version 1.0.9beta11 [January 19, 2001] - Updated makefile.sgi to make shared library. - Removed png_mmx_support() function and disabled PNG_MNG_FEATURES_SUPPORTED - by default, for the benefit of DLL forward compatibility. These will - be re-enabled in version 1.2.0. - -Version 1.0.9rc2 [January 22, 2001] - Revised cygwin support. - -Version 1.0.9 [January 31, 2001] - Added check of cygwin's ALL_STATIC in pngconf.h - Added "-nommx" parameter to contrib/gregbook/rpng2-win and rpng2-x demos. - -Version 1.0.10beta1 [March 14, 2001] - Revised makefile.dec, makefile.sgi, and makefile.sggcc; added makefile.hpgcc. - Reformatted libpng.3 to eliminate bad line breaks. - Added checks for _mmx_supported in the read_filter_row function of pnggccrd.c - Added prototype for png_mmx_support() near the top of pnggccrd.c - Moved some error checking from png_handle_IHDR to png_set_IHDR. - Added PNG_NO_READ_SUPPORTED and PNG_NO_WRITE_SUPPORTED macros. - Revised png_mmx_support() function in pnggccrd.c - Restored version 1.0.8 PNG_WRITE_EMPTY_PLTE_SUPPORTED behavior in pngwutil.c - Fixed memory leak in contrib/visupng/PngFile.c - Fixed bugs in png_combine_row() in pnggccrd.c and pngvcrd.c (C version) - Added warnings when retrieving or setting gamma=0. - Increased the first part of msg buffer from 16 to 18 in png_chunk_warning(). - -Version 1.0.10rc1 [March 23, 2001] - Changed all instances of memcpy, strcpy, and strlen to png_memcpy, png_strcpy, - and png_strlen. - Revised png_mmx_supported() function in pnggccrd.c to return proper value. - Fixed bug in progressive reading (pngpread.c) with small images (height < 8). - -Version 1.0.10 [March 30, 2001] - Deleted extraneous space (introduced in 1.0.9) from line 42 of makefile.cygwin - Added beos project files (Chris Herborth) - -Version 1.0.11beta1 [April 3, 2001] - Added type casts on several png_malloc() calls (Dimitri Papadapoulos). - Removed a no-longer needed AIX work-around from pngconf.h - Changed several "//" single-line comments to C-style in pnggccrd.c - -Version 1.0.11beta2 [April 11, 2001] - Removed PNGAPI from several functions whose prototypes did not have PNGAPI. - Updated scripts/pngos2.def - -Version 1.0.11beta3 [April 14, 2001] - Added checking the results of many instances of png_malloc() for NULL - -Version 1.0.11beta4 [April 20, 2001] - Undid the changes from version 1.0.11beta3. Added a check for NULL return - from user's malloc_fn(). - Removed some useless type casts of the NULL pointer. - Added makefile.netbsd - -Version 1.0.11 [April 27, 2001] - Revised makefile.netbsd - -Version 1.0.12beta1 [May 14, 2001] - Test for Windows platform in pngconf.h when including malloc.h (Emmanuel Blot) - Updated makefile.cygwin and handling of Cygwin's ALL_STATIC in pngconf.h - Added some never-to-be-executed code in pnggccrd.c to quiet compiler warnings. - Eliminated the png_error about apps using png_read|write_init(). Instead, - libpng will reallocate the png_struct and info_struct if they are too small. - This retains future binary compatibility for old applications written for - libpng-0.88 and earlier. - -Version 1.2.0beta1 [May 6, 2001] - Bumped DLLNUM to 2. - Re-enabled PNG_MNG_FEATURES_SUPPORTED and enabled PNG_ASSEMBLER_CODE_SUPPORTED - by default. - Added runtime selection of MMX features. - Added png_set_strip_error_numbers function and related macros. - -Version 1.2.0beta2 [May 7, 2001] - Finished merging 1.2.0beta1 with version 1.0.11 - Added a check for attempts to read or write PLTE in grayscale PNG datastreams. - -Version 1.2.0beta3 [May 17, 2001] - Enabled user memory function by default. - Modified png_create_struct so it passes user mem_ptr to user memory allocator. - Increased png_mng_features flag from png_byte to png_uint_32. - Bumped shared-library (so-number) and dll-number to 3. - -Version 1.2.0beta4 [June 23, 2001] - Check for missing profile length field in iCCP chunk and free chunk_data - in case of truncated iCCP chunk. - Bumped shared-library number to 3 in makefile.sgi and makefile.sggcc - Bumped dll-number from 2 to 3 in makefile.cygwin - Revised contrib/gregbook/rpng*-x.c to avoid a memory leak and to exit cleanly - if user attempts to run it on an 8-bit display. - Updated contrib/gregbook - Use png_malloc instead of png_zalloc to allocate palette in pngset.c - Updated makefile.ibmc - Added some typecasts to eliminate gcc 3.0 warnings. Changed prototypes - of png_write_oFFS width and height from png_uint_32 to png_int_32. - Updated example.c - Revised prototypes for png_debug_malloc and png_debug_free in pngtest.c - -Version 1.2.0beta5 [August 8, 2001] - Revised contrib/gregbook - Revised makefile.gcmmx - Revised pnggccrd.c to conditionally compile some thread-unsafe code only - when PNG_THREAD_UNSAFE_OK is defined. - Added tests to prevent pngwutil.c from writing a bKGD or tRNS chunk with - value exceeding 2^bit_depth-1 - Revised makefile.sgi and makefile.sggcc - Replaced calls to fprintf(stderr,...) with png_warning() in pnggccrd.c - Removed restriction that do_invert_mono only operate on 1-bit opaque files - -Version 1.2.0 [September 1, 2001] - Changed a png_warning() to png_debug() in pnggccrd.c - Fixed contrib/gregbook/rpng-x.c, rpng2-x.c to avoid crash with XFreeGC(). - -Version 1.2.1beta1 [October 19, 2001] - Revised makefile.std in contrib/pngminus - Include background_1 in png_struct regardless of gamma support. - Revised makefile.netbsd and makefile.macosx, added makefile.darwin. - Revised example.c to provide more details about using row_callback(). - -Version 1.2.1beta2 [October 25, 2001] - Added type cast to each NULL appearing in a function call, except for - WINCE functions. - Added makefile.so9. - -Version 1.2.1beta3 [October 27, 2001] - Removed type casts from all NULLs. - Simplified png_create_struct_2(). - -Version 1.2.1beta4 [November 7, 2001] - Revised png_create_info_struct() and png_creat_struct_2(). - Added error message if png_write_info() was omitted. - Type cast NULLs appearing in function calls when _NO_PROTO or - PNG_TYPECAST_NULL is defined. - -Version 1.2.1rc1 [November 24, 2001] - Type cast NULLs appearing in function calls except when PNG_NO_TYPECAST_NULL - is defined. - Changed typecast of "size" argument to png_size_t in pngmem.c calls to - the user malloc_fn, to agree with the prototype in png.h - Added a pop/push operation to pnggccrd.c, to preserve Eflag (Maxim Sobolev) - Updated makefile.sgi to recognize LIBPATH and INCPATH. - Updated various makefiles so "make clean" does not remove previous major - version of the shared library. - -Version 1.2.1rc2 [December 4, 2001] - Always allocate 256-entry internal palette, hist, and trans arrays, to - avoid out-of-bounds memory reference caused by invalid PNG datastreams. - Added a check for prefix_length > data_length in iCCP chunk handler. - -Version 1.2.1 [December 7, 2001] - None. - -Version 1.2.2beta1 [February 22, 2002] - Fixed a bug with reading the length of iCCP profiles (Larry Reeves). - Revised makefile.linux, makefile.gcmmx, and makefile.sgi to generate - libpng.a, libpng12.so (not libpng.so.3), and libpng12/png.h - Revised makefile.darwin to remove "-undefined suppress" option. - Added checks for gamma and chromaticity values over 21474.83, which exceed - the limit for PNG unsigned 32-bit integers when encoded. - Revised calls to png_create_read_struct() and png_create_write_struct() - for simpler debugging. - Revised png_zalloc() so zlib handles errors (uses PNG_FLAG_MALLOC_NULL_MEM_OK) - -Version 1.2.2beta2 [February 23, 2002] - Check chunk_length and idat_size for invalid (over PNG_MAX_UINT) lengths. - Check for invalid image dimensions in png_get_IHDR. - Added missing "fi;" in the install target of the SGI makefiles. - Added install-static to all makefiles that make shared libraries. - Always do gamma compensation when image is partially transparent. - -Version 1.2.2beta3 [March 7, 2002] - Compute background.gray and background_1.gray even when color_type is RGB - in case image gets reduced to gray later. - Modified shared-library makefiles to install pkgconfig/libpngNN.pc. - Export (with PNGAPI) png_zalloc, png_zfree, and png_handle_as_unknown - Removed unused png_write_destroy_info prototype from png.h - Eliminated incorrect use of width_mmx from pnggccrd.c in pixel_bytes == 8 case - Added install-shared target to all makefiles that make shared libraries. - Stopped a double free of palette, hist, and trans when not using free_me. - Added makefile.32sunu for Sun Ultra 32 and makefile.64sunu for Sun Ultra 64. - -Version 1.2.2beta4 [March 8, 2002] - Compute background.gray and background_1.gray even when color_type is RGB - in case image gets reduced to gray later (Jason Summers). - Relocated a misplaced /bin/rm in the "install-shared" makefile targets - Added PNG_1_0_X macro which can be used to build a 1.0.x-compatible library. - -Version 1.2.2beta5 [March 26, 2002] - Added missing PNGAPI to several function definitions. - Check for invalid bit_depth or color_type in png_get_IHDR(), and - check for missing PLTE or IHDR in png_push_read_chunk() (Matthias Clasen). - Revised iTXt support to accept NULL for lang and lang_key. - Compute gamma for color components of background even when color_type is gray. - Changed "()" to "{}" in scripts/libpng.pc.in. - Revised makefiles to put png.h and pngconf.h only in $prefix/include/libpngNN - Revised makefiles to make symlink to libpng.so.NN in addition to libpngNN.so - -Version 1.2.2beta6 [March 31, 2002] - -Version 1.0.13beta1 [March 31, 2002] - Prevent png_zalloc() from trying to memset memory that it failed to acquire. - Add typecasts of PNG_MAX_UINT in pngset_cHRM_fixed() (Matt Holgate). - Ensure that the right function (user or default) is used to free the - png_struct after an error in png_create_read_struct_2(). - -Version 1.2.2rc1 [April 7, 2002] - -Version 1.0.13rc1 [April 7, 2002] - Save the ebx register in pnggccrd.c (Sami Farin) - Add "mem_ptr = png_ptr->mem_ptr" in png_destroy_write_struct() (Paul Gardner). - Updated makefiles to put headers in include/libpng and remove old include/*.h. - -Version 1.2.2 [April 15, 2002] - -Version 1.0.13 [April 15, 2002] - Revised description of png_set_filter() in libpng.3/libpng.txt. - Revised makefile.netbsd and added makefile.neNNbsd and makefile.freebsd - -Version 1.0.13patch01 [April 17, 2002] - -Version 1.2.2patch01 [April 17, 2002] - Changed ${PNGMAJ}.${PNGVER} bug to ${PNGVER} in makefile.sgi and - makefile.sggcc - Fixed VER -> PNGVER typo in makefile.macosx and added install-static to - install - Added install: target to makefile.32sunu and makefile.64sunu - -Version 1.0.13patch03 [April 18, 2002] - -Version 1.2.2patch03 [April 18, 2002] - Revised 15 makefiles to link libpng.a to libpngNN.a and the include libpng - subdirectory to libpngNN subdirectory without the full pathname. - Moved generation of libpng.pc from "install" to "all" in 15 makefiles. - -Version 1.2.3rc1 [April 28, 2002] - Added install-man target to 15 makefiles (Dimitri Papadopolous-Orfanos). - Added $(DESTDIR) feature to 24 makefiles (Tim Mooney) - Fixed bug with $prefix, should be $(prefix) in makefile.hpux. - Updated cygwin-specific portion of pngconf.h and revised makefile.cygwin - Added a link from libpngNN.pc to libpng.pc in 15 makefiles. - Added links from include/libpngNN/*.h to include/*.h in 24 makefiles. - Revised makefile.darwin to make relative links without full pathname. - Added setjmp() at the end of png_create_*_struct_2() in case user forgets - to put one in their application. - Restored png_zalloc() and png_zfree() prototypes to version 1.2.1 and - removed them from module definition files. - -Version 1.2.3rc2 [May 1, 2002] - Fixed bug in reporting number of channels in pngget.c and pngset.c, - that was introduced in version 1.2.2beta5. - Exported png_zalloc(), png_zfree(), png_default_read(), png_default_write(), - png_default_flush(), and png_push_fill_buffer() and included them in - module definition files. - Added "libpng.pc" dependency to the "install-shared" target in 15 makefiles. - -Version 1.2.3rc3 [May 1, 2002] - Revised prototype for png_default_flush() - Remove old libpng.pc and libpngNN.pc before installing new ones. - -Version 1.2.3rc4 [May 2, 2002] - Typos in *.def files (png_default_read|write -> png_default_read|write_data) - In makefiles, changed rm libpng.NN.pc to rm libpngNN.pc - Added libpng-config and libpngNN-config and modified makefiles to install - them. - Changed $(MANPATH) to $(DESTDIR)$(MANPATH) in makefiles - Added "Win32 DLL VB" configuration to projects/msvc/libpng.dsp - -Version 1.2.3rc5 [May 11, 2002] - Changed "error" and "message" in prototypes to "error_message" and - "warning_message" to avoid namespace conflict. - Revised 15 makefiles to build libpng-config from libpng-config-*.in - Once more restored png_zalloc and png_zfree to regular nonexported form. - Restored png_default_read|write_data, png_default_flush, png_read_fill_buffer - to nonexported form, but with PNGAPI, and removed them from module def - files. - -Version 1.2.3rc6 [May 14, 2002] - Removed "PNGAPI" from png_zalloc() and png_zfree() in png.c - Changed "Gz" to "Gd" in projects/msvc/libpng.dsp and zlib.dsp. - Removed leftover libpng-config "sed" script from four makefiles. - Revised libpng-config creating script in 16 makefiles. - -Version 1.2.3 [May 22, 2002] - Revised libpng-config target in makefile.cygwin. - Removed description of png_set_mem_fn() from documentation. - Revised makefile.freebsd. - Minor cosmetic changes to 15 makefiles, e.g., $(DI) = $(DESTDIR)/$(INCDIR). - Revised projects/msvc/README.txt - Changed -lpng to -lpngNN in LDFLAGS in several makefiles. - -Version 1.2.4beta1 [May 24, 2002] - Added libpng.pc and libpng-config to "all:" target in 16 makefiles. - Fixed bug in 16 makefiles: $(DESTDIR)/$(LIBPATH) to $(DESTDIR)$(LIBPATH) - Added missing "\" before closing double quote in makefile.gcmmx. - Plugged various memory leaks; added png_malloc_warn() and png_set_text_2() - functions. - -Version 1.2.4beta2 [June 25, 2002] - Plugged memory leak of png_ptr->current_text (Matt Holgate). - Check for buffer overflow before reading CRC in pngpread.c (Warwick Allison) - Added -soname to the loader flags in makefile.dec, makefile.sgi, and - makefile.sggcc. - Added "test-installed" target to makefile.linux, makefile.gcmmx, - makefile.sgi, and makefile.sggcc. - -Version 1.2.4beta3 [June 28, 2002] - Plugged memory leak of row_buf in pngtest.c when there is a png_error(). - Detect buffer overflow in pngpread.c when IDAT is corrupted with extra data. - Added "test-installed" target to makefile.32sunu, makefile.64sunu, - makefile.beos, makefile.darwin, makefile.dec, makefile.macosx, - makefile.solaris, makefile.hpux, makefile.hpgcc, and makefile.so9. - -Version 1.2.4rc1 and 1.0.14rc1 [July 2, 2002] - Added "test-installed" target to makefile.cygwin and makefile.sco. - Revised pnggccrd.c to be able to back out version 1.0.x via PNG_1_0_X macro. - -Version 1.2.4 and 1.0.14 [July 8, 2002] - Changed png_warning() to png_error() when width is too large to process. - -Version 1.2.4patch01 [July 20, 2002] - Revised makefile.cygwin to use DLL number 12 instead of 13. - -Version 1.2.5beta1 [August 6, 2002] - Added code to contrib/gregbook/readpng2.c to ignore unused chunks. - Replaced toucan.png in contrib/gregbook (it has been corrupt since 1.0.11) - Removed some stray *.o files from contrib/gregbook. - Changed png_error() to png_warning() about "Too much data" in pngpread.c - and about "Extra compressed data" in pngrutil.c. - Prevent png_ptr->pass from exceeding 7 in png_push_finish_row(). - Updated makefile.hpgcc - Updated png.c and pnggccrd.c handling of return from png_mmx_support() - -Version 1.2.5beta2 [August 15, 2002] - Only issue png_warning() about "Too much data" in pngpread.c when avail_in - is nonzero. - Updated makefiles to install a separate libpng.so.3 with its own rpath. - -Version 1.2.5rc1 and 1.0.15rc1 [August 24, 2002] - Revised makefiles to not remove previous minor versions of shared libraries. - -Version 1.2.5rc2 and 1.0.15rc2 [September 16, 2002] - Revised 13 makefiles to remove "-lz" and "-L$(ZLIBLIB)", etc., from shared - library loader directive. - Added missing "$OBJSDLL" line to makefile.gcmmx. - Added missing "; fi" to makefile.32sunu. - -Version 1.2.5rc3 and 1.0.15rc3 [September 18, 2002] - Revised libpng-config script. - -Version 1.2.5 and 1.0.15 [October 3, 2002] - Revised makefile.macosx, makefile.darwin, makefile.hpgcc, and makefile.hpux, - and makefile.aix. - Relocated two misplaced PNGAPI lines in pngtest.c - -Version 1.2.6beta1 [October 22, 2002] - Commented out warning about uninitialized mmx_support in pnggccrd.c. - Changed "IBMCPP__" flag to "__IBMCPP__" in pngconf.h. - Relocated two more misplaced PNGAPI lines in pngtest.c - Fixed memory overrun bug in png_do_read_filler() with 16-bit datastreams, - introduced in version 1.0.2. - Revised makefile.macosx, makefile.dec, makefile.aix, and makefile.32sunu. - -Version 1.2.6beta2 [November 1, 2002] - Added libpng-config "--ldopts" output. - Added "AR=ar" and "ARFLAGS=rc" and changed "ar rc" to "$(AR) $(ARFLAGS)" - in makefiles. - -Version 1.2.6beta3 [July 18, 2004] - Reverted makefile changes from version 1.2.6beta2 and some of the changes - from version 1.2.6beta1; these will be postponed until version 1.2.7. - Version 1.2.6 is going to be a simple bugfix release. - Changed the one instance of "ln -sf" to "ln -f -s" in each Sun makefile. - Fixed potential overrun in pngerror.c by using strncpy instead of memcpy. - Added "#!/bin/sh" at the top of configure, for recognition of the - 'x' flag under Cygwin (Cosmin). - Optimized vacuous tests that silence compiler warnings, in png.c (Cosmin). - Added support for PNG_USER_CONFIG, in pngconf.h (Cosmin). - Fixed the special memory handler for Borland C under DOS, in pngmem.c - (Cosmin). - Removed some spurious assignments in pngrutil.c (Cosmin). - Replaced 65536 with 65536L, and 0xffff with 0xffffL, to silence warnings - on 16-bit platforms (Cosmin). - Enclosed shift op expressions in parentheses, to silence warnings (Cosmin). - Used proper type png_fixed_point, to avoid problems on 16-bit platforms, - in png_handle_sRGB() (Cosmin). - Added compression_type to png_struct, and optimized the window size - inside the deflate stream (Cosmin). - Fixed definition of isnonalpha(), in pngerror.c and pngrutil.c (Cosmin). - Fixed handling of unknown chunks that come after IDAT (Cosmin). - Allowed png_error() and png_warning() to work even if png_ptr == NULL - (Cosmin). - Replaced row_info->rowbytes with row_bytes in png_write_find_filter() - (Cosmin). - Fixed definition of PNG_LIBPNG_VER_DLLNUM (Simon-Pierre). - Used PNG_LIBPNG_VER and PNG_LIBPNG_VER_STRING instead of the hardcoded - values in png.c (Simon-Pierre, Cosmin). - Initialized png_libpng_ver[] with PNG_LIBPNG_VER_STRING (Simon-Pierre). - Replaced PNG_LIBPNG_VER_MAJOR with PNG_LIBPNG_VER_DLLNUM in png.rc - (Simon-Pierre). - Moved the definition of PNG_HEADER_VERSION_STRING near the definitions - of the other PNG_LIBPNG_VER_... symbols in png.h (Cosmin). - Relocated #ifndef PNGAPI guards in pngconf.h (Simon-Pierre, Cosmin). - Updated scripts/makefile.vc(a)win32 (Cosmin). - Updated the MSVC project (Simon-Pierre, Cosmin). - Updated the Borland C++ Builder project (Cosmin). - Avoided access to asm_flags in pngvcrd.c, if PNG_1_0_X is defined (Cosmin). - Commented out warning about uninitialized mmx_support in pngvcrd.c (Cosmin). - Removed scripts/makefile.bd32 and scripts/pngdef.pas (Cosmin). - Added extra guard around inclusion of Turbo C memory headers, in pngconf.h - (Cosmin). - Renamed projects/msvc/ to projects/visualc6/, and projects/borland/ to - projects/cbuilder5/ (Cosmin). - Moved projects/visualc6/png32ms.def to scripts/pngw32.def, - and projects/visualc6/png.rc to scripts/pngw32.rc (Cosmin). - Added projects/visualc6/pngtest.dsp; removed contrib/msvctest/ (Cosmin). - Changed line endings to DOS style in cbuilder5 and visualc6 files, even - in the tar.* distributions (Cosmin). - Updated contrib/visupng/VisualPng.dsp (Cosmin). - Updated contrib/visupng/cexcept.h to version 2.0.0 (Cosmin). - Added a separate distribution with "configure" and supporting files (Junichi). - -Version 1.2.6beta4 [July 28, 2004] - Added user ability to change png_size_t via a PNG_SIZE_T macro. - Added png_sizeof() and png_convert_size() functions. - Added PNG_SIZE_MAX (maximum value of a png_size_t variable. - Added check in png_malloc_default() for (size_t)size != (png_uint_32)size - which would indicate an overflow. - Changed sPLT failure action from png_error to png_warning and abandon chunk. - Changed sCAL and iCCP failures from png_error to png_warning and abandon. - Added png_get_uint_31(png_ptr, buf) function. - Added PNG_UINT_32_MAX macro. - Renamed PNG_MAX_UINT to PNG_UINT_31_MAX. - Made png_zalloc() issue a png_warning and return NULL on potential - overflow. - Turn on PNG_NO_ZALLOC_ZERO by default in version 1.2.x - Revised "clobber list" in pnggccrd.c so it will compile under gcc-3.4. - Revised Borland portion of png_malloc() to return NULL or issue - png_error() according to setting of PNG_FLAG_MALLOC_NULL_MEM_OK. - Added PNG_NO_SEQUENTIAL_READ_SUPPORTED macro to conditionally remove - sequential read support. - Added some "#if PNG_WRITE_SUPPORTED" blocks. - Added #ifdef to remove some redundancy in png_malloc_default(). - Use png_malloc instead of png_zalloc to allocate the pallete. - -Version 1.0.16rc1 and 1.2.6rc1 [August 4, 2004] - Fixed buffer overflow vulnerability (CVE-2004-0597) in png_handle_tRNS(). - Fixed NULL dereference vulnerability (CVE-2004-0598) in png_handle_iCCP(). - Fixed integer overflow vulnerability (CVE-2004-0599) in png_read_png(). - Fixed some harmless bugs in png_handle_sBIT, etc, that would cause - duplicate chunk types to go undetected. - Fixed some timestamps in the -config version - Rearranged order of processing of color types in png_handle_tRNS(). - Added ROWBYTES macro to calculate rowbytes without integer overflow. - Updated makefile.darwin and removed makefile.macosx from scripts directory. - Imposed default one million column, one-million row limits on the image - dimensions, and added png_set_user_limits() function to override them. - Revised use of PNG_SET_USER_LIMITS_SUPPORTED macro. - Fixed wrong cast of returns from png_get_user_width|height_max(). - Changed some "keep the compiler happy" from empty statements to returns, - Revised libpng.txt to remove 1.2.x stuff from the 1.0.x distribution - -Version 1.0.16rc2 and 1.2.6rc2 [August 7, 2004] - Revised makefile.darwin and makefile.solaris. Removed makefile.macosx. - Revised pngtest's png_debug_malloc() to use png_malloc() instead of - png_malloc_default() which is not supposed to be exported. - Fixed off-by-one error in one of the conversions to PNG_ROWBYTES() in - pngpread.c. Bug was introduced in 1.2.6rc1. - Fixed bug in RGB to RGBX transformation introduced in 1.2.6rc1. - Fixed old bug in RGB to Gray transformation. - Fixed problem with 64-bit compilers by casting arguments to abs() - to png_int_32. - Changed "ln -sf" to "ln -f -s" in three makefiles (solaris, sco, so9). - Changed "HANDLE_CHUNK_*" to "PNG_HANDLE_CHUNK_*" (Cosmin) - Added "-@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGMAJ)" to 15 *NIX makefiles. - Added code to update the row_info->colortype in png_do_read_filler() (MSB). - -Version 1.0.16rc3 and 1.2.6rc3 [August 9, 2004] - Eliminated use of "abs()" in testing cHRM and gAMA values, to avoid - trouble with some 64-bit compilers. Created PNG_OUT_OF_RANGE() macro. - Revised documentation of png_set_keep_unknown_chunks(). - Check handle_as_unknown status in pngpread.c, as in pngread.c previously. - Moved "PNG_HANDLE_CHUNK_*" macros out of PNG_INTERNAL section of png.h - Added "rim" definitions for CONST4 and CONST6 in pnggccrd.c - -Version 1.0.16rc4 and 1.2.6rc4 [August 10, 2004] - Fixed mistake in pngtest.c introduced in 1.2.6rc2 (declaration of - "pinfo" was out of place). - -Version 1.0.16rc5 and 1.2.6rc5 [August 10, 2004] - Moved "PNG_HANDLE_CHUNK_*" macros out of PNG_ASSEMBLER_CODE_SUPPORTED - section of png.h where they were inadvertently placed in version rc3. - -Version 1.2.6 and 1.0.16 [August 15, 2004] - Revised pngtest so memory allocation testing is only done when PNG_DEBUG==1. - -Version 1.2.7beta1 [August 26, 2004] - Removed unused pngasmrd.h file. - Removed references to uu.net for archived files. Added references to - PNG Spec (second edition) and the PNG ISO/IEC Standard. - Added "test-dd" target in 15 makefiles, to run pngtest in DESTDIR. - Fixed bug with "optimized window size" in the IDAT datastream, that - causes libpng to write PNG files with incorrect zlib header bytes. - -Version 1.2.7beta2 [August 28, 2004] - Fixed bug with sCAL chunk and big-endian machines (David Munro). - Undid new code added in 1.2.6rc2 to update the color_type in - png_set_filler(). - Added png_set_add_alpha() that updates color type. - -Version 1.0.17rc1 and 1.2.7rc1 [September 4, 2004] - Revised png_set_strip_filler() to not remove alpha if color_type has alpha. - -Version 1.2.7 and 1.0.17 [September 12, 2004] - Added makefile.hp64 - Changed projects/msvc/png32ms.def to scripts/png32ms.def in makefile.cygwin - -Version 1.2.8beta1 [November 1, 2004] - Fixed bug in png_text_compress() that would fail to complete a large block. - Fixed bug, introduced in libpng-1.2.7, that overruns a buffer during - strip alpha operation in png_do_strip_filler(). - Added PNG_1_2_X definition in pngconf.h - Use #ifdef to comment out png_info_init in png.c and png_read_init in - pngread.c (as of 1.3.0) - -Version 1.2.8beta2 [November 2, 2004] - Reduce color_type to a nonalpha type after strip alpha operation in - png_do_strip_filler(). - -Version 1.2.8beta3 [November 3, 2004] - Revised definitions of PNG_MAX_UINT_32, PNG_MAX_SIZE, and PNG_MAXSUM - -Version 1.2.8beta4 [November 12, 2004] - Fixed (again) definition of PNG_LIBPNG_VER_DLLNUM in png.h (Cosmin). - Added PNG_LIBPNG_BUILD_PRIVATE in png.h (Cosmin). - Set png_ptr->zstream.data_type to Z_BINARY, to avoid unnecessary detection - of data type in deflate (Cosmin). - Deprecated but continue to support SPECIALBUILD and PRIVATEBUILD in favor of - PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING. - -Version 1.2.8beta5 [November 20, 2004] - Use png_ptr->flags instead of png_ptr->transformations to pass - PNG_STRIP_ALPHA info to png_do_strip_filler(), to preserve ABI - compatibility. - Revised handling of SPECIALBUILD, PRIVATEBUILD, - PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING. - -Version 1.2.8rc1 [November 24, 2004] - Moved handling of BUILD macros from pngconf.h to png.h - Added definition of PNG_LIBPNG_BASE_TYPE in png.h, inadvertently - omitted from beta5. - Revised scripts/pngw32.rc - Despammed mailing addresses by masking "@" with "at". - Inadvertently installed a supposedly faster test version of pngrutil.c - -Version 1.2.8rc2 [November 26, 2004] - Added two missing "\" in png.h - Change tests in pngread.c and pngpread.c to - if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) - png_do_read_transformations(png_ptr); - -Version 1.2.8rc3 [November 28, 2004] - Reverted pngrutil.c to version libpng-1.2.8beta5. - Added scripts/makefile.elf with supporting code in pngconf.h for symbol - versioning (John Bowler). - -Version 1.2.8rc4 [November 29, 2004] - Added projects/visualc7 (Simon-pierre). - -Version 1.2.8rc5 [November 29, 2004] - Fixed new typo in scripts/pngw32.rc - -Version 1.2.8 [December 3, 2004] - Removed projects/visualc7, added projects/visualc71. - -Version 1.2.9beta1 [February 21, 2006] - Initialized some structure members in pngwutil.c to avoid gcc-4.0.0 complaints - Revised man page and libpng.txt to make it clear that one should not call - png_read_end or png_write_end after png_read_png or png_write_png. - Updated references to png-mng-implement mailing list. - Fixed an incorrect typecast in pngrutil.c - Added PNG_NO_READ_SUPPORTED conditional for making a write-only library. - Added PNG_NO_WRITE_INTERLACING_SUPPORTED conditional. - Optimized alpha-inversion loops in pngwtran.c - Moved test for nonzero gamma outside of png_build_gamma_table() in pngrtran.c - Make sure num_trans is <= 256 before copying data in png_set_tRNS(). - Make sure num_palette is <= 256 before copying data in png_set_PLTE(). - Interchanged order of write_swap_alpha and write_invert_alpha transforms. - Added parentheses in the definition of PNG_LIBPNG_BUILD_TYPE (Cosmin). - Optimized zlib window flag (CINFO) in contrib/pngsuite/*.png (Cosmin). - Updated scripts/makefile.bc32 for Borland C++ 5.6 (Cosmin). - Exported png_get_uint_32, png_save_uint_32, png_get_uint_16, png_save_uint_16, - png_get_int_32, png_save_int_32, png_get_uint_31 (Cosmin). - Added type cast (png_byte) in png_write_sCAL() (Cosmin). - Fixed scripts/makefile.cygwin (Christian Biesinger, Cosmin). - Default iTXt support was inadvertently enabled. - -Version 1.2.9beta2 [February 21, 2006] - Check for png_rgb_to_gray and png_gray_to_rgb read transformations before - checking for png_read_dither in pngrtran.c - Revised checking of chromaticity limits to accommodate extended RGB - colorspace (John Denker). - Changed line endings in some of the project files to CRLF, even in the - "Unix" tar distributions (Cosmin). - Made png_get_int_32 and png_save_int_32 always available (Cosmin). - Updated scripts/pngos2.def, scripts/pngw32.def and projects/wince/png32ce.def - with the newly exported functions. - Eliminated distributions without the "configure" script. - Updated INSTALL instructions. - -Version 1.2.9beta3 [February 24, 2006] - Fixed CRCRLF line endings in contrib/visupng/VisualPng.dsp - Made libpng.pc respect EXEC_PREFIX (D. P. Kreil, J. Bowler) - Removed reference to pngasmrd.h from Makefile.am - Renamed CHANGES to ChangeLog. - Renamed LICENSE to COPYING. - Renamed ANNOUNCE to NEWS. - Created AUTHORS file. - -Version 1.2.9beta4 [March 3, 2006] - Changed definition of PKGCONFIG from $prefix/lib to $libdir in configure.ac - Reverted to filenames LICENSE and ANNOUNCE; removed AUTHORS and COPYING. - Removed newline from the end of some error and warning messages. - Removed test for sqrt() from configure.ac and configure. - Made swap tables in pngtrans.c PNG_CONST (Carlo Bramix). - Disabled default iTXt support that was inadvertently enabled in - libpng-1.2.9beta1. - Added "OS2" to list of systems that don't need underscores, in pnggccrd.c - Removed libpng version and date from *.c files. - -Version 1.2.9beta5 [March 4, 2006] - Removed trailing blanks from source files. - Put version and date of latest change in each source file, and changed - copyright year accordingly. - More cleanup of configure.ac, Makefile.am, and associated scripts. - Restored scripts/makefile.elf which was inadvertently deleted. - -Version 1.2.9beta6 [March 6, 2006] - Fixed typo (RELEASE) in configuration files. - -Version 1.2.9beta7 [March 7, 2006] - Removed libpng.vers and libpng.sym from libpng12_la_SOURCES in Makefile.am - Fixed inconsistent #ifdef's around png_sig_bytes() and png_set_sCAL_s() - in png.h. - Updated makefile.elf as suggested by debian. - Made cosmetic changes to some makefiles, adding LN_SF and other macros. - Made some makefiles accept "exec_prefix". - -Version 1.2.9beta8 [March 9, 2006] - Fixed some "#if defined (..." which should be "#if defined(..." - Bug introduced in libpng-1.2.8. - Fixed inconsistency in definition of png_default_read_data() - Restored blank that was lost from makefile.sggcc "clean" target in beta7. - Revised calculation of "current" and "major" for irix in ltmain.sh - Changed "mkdir" to "MKDIR_P" in some makefiles. - Separated PNG_EXPAND and PNG_EXPAND_tRNS. - Added png_set_expand_gray_1_2_4_to_8() and deprecated - png_set_gray_1_2_4_to_8() which also expands tRNS to alpha. - -Version 1.2.9beta9 [March 10, 2006] - Include "config.h" in pngconf.h when available. - Added some checks for NULL png_ptr or NULL info_ptr (timeless) - -Version 1.2.9beta10 [March 20, 2006] - Removed extra CR from contrib/visualpng/VisualPng.dsw (Cosmin) - Made pnggccrd.c PIC-compliant (Christian Aichinger). - Added makefile.mingw (Wolfgang Glas). - Revised pngconf.h MMX checking. - -Version 1.2.9beta11 [March 22, 2006] - Fixed out-of-order declaration in pngwrite.c that was introduced in beta9 - Simplified some makefiles by using LIBSO, LIBSOMAJ, and LIBSOVER macros. - -Version 1.2.9rc1 [March 31, 2006] - Defined PNG_USER_PRIVATEBUILD when including "pngusr.h" (Cosmin). - Removed nonsensical assertion check from pngtest.c (Cosmin). - -Version 1.2.9 [April 14, 2006] - Revised makefile.beos and added "none" selector in ltmain.sh - -Version 1.2.10beta1 [April 15, 2006] - Renamed "config.h" to "png_conf.h" and revised Makefile.am to add - -DPNG_BUILDING_LIBPNG to compile directive, and modified pngconf.h - to include png_conf.h only when PNG_BUILDING_LIBPNG is defined. - -Version 1.2.10beta2 [April 15, 2006] - Manually updated Makefile.in and configure. Changed png_conf.h.in - back to config.h. - -Version 1.2.10beta3 [April 15, 2006] - Change png_conf.h back to config.h in pngconf.h. - -Version 1.2.10beta4 [April 16, 2006] - Change PNG_BUILDING_LIBPNG to PNG_CONFIGURE_LIBPNG in config/Makefile*. - -Version 1.2.10beta5 [April 16, 2006] - Added a configure check for compiling assembler code in pnggccrd.c - -Version 1.2.10beta6 [April 17, 2006] - Revised the configure check for pnggccrd.c - Moved -DPNG_CONFIGURE_LIBPNG into @LIBPNG_DEFINES@ - Added @LIBPNG_DEFINES@ to arguments when building libpng.sym - -Version 1.2.10beta7 [April 18, 2006] - Change "exec_prefix=$prefix" to "exec_prefix=$(prefix)" in makefiles. - -Version 1.2.10rc1 [April 19, 2006] - Ensure pngconf.h doesn't define both PNG_USE_PNGGCCRD and PNG_USE_PNGVCRD - Fixed "LN_FS" typo in makefile.sco and makefile.solaris. - -Version 1.2.10rc2 [April 20, 2006] - Added a backslash between -DPNG_CONFIGURE_LIBPNG and -DPNG_NO_ASSEMBLER_CODE - in configure.ac and configure - Made the configure warning about versioned symbols less arrogant. - -Version 1.2.10rc3 [April 21, 2006] - Added a note in libpng.txt that png_set_sig_bytes(8) can be used when - writing an embedded PNG without the 8-byte signature. - Revised makefiles and configure to avoid making links to libpng.so.* - -Version 1.2.10 [April 23, 2006] - Reverted configure to "rc2" state. - -Version 1.2.11beta1 [May 31, 2006] - scripts/libpng.pc.in contained "configure" style version info and would - not work with makefiles. - The shared-library makefiles were linking to libpng.so.0 instead of - libpng.so.3 compatibility as the library. - -Version 1.2.11beta2 [June 2, 2006] - Increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid - buffer overflow. - Fixed bug in example.c (png_set_palette_rgb -> png_set_palette_to_rgb) - -Version 1.2.11beta3 [June 5, 2006] - Prepended "#! /bin/sh" to ltmail.sh and contrib/pngminus/*.sh (Cosmin). - Removed the accidental leftover Makefile.in~ (Cosmin). - Avoided potential buffer overflow and optimized buffer in - png_write_sCAL(), png_write_sCAL_s() (Cosmin). - Removed the include directories and libraries from CFLAGS and LDFLAGS - in scripts/makefile.gcc (Nelson A. de Oliveira, Cosmin). - -Version 1.2.11beta4 [June 6, 2006] - Allow zero-length IDAT chunks after the entire zlib datastream, but not - after another intervening chunk type. - -Version 1.0.19rc1, 1.2.11rc1 [June 13, 2006] - Deleted extraneous square brackets from [config.h] in configure.ac - -Version 1.0.19rc2, 1.2.11rc2 [June 14, 2006] - Added prototypes for PNG_INCH_CONVERSIONS functions to png.h - Revised INSTALL and autogen.sh - Fixed typo in several makefiles (-W1 should be -Wl) - Added typedef for png_int_32 and png_uint_32 on 64-bit systems. - -Version 1.0.19rc3, 1.2.11rc3 [June 15, 2006] - Removed the new typedefs for 64-bit systems (delay until version 1.4.0) - Added one zero element to png_gamma_shift[] array in pngrtran.c to avoid - reading out of bounds. - -Version 1.0.19rc4, 1.2.11rc4 [June 15, 2006] - Really removed the new typedefs for 64-bit systems. - -Version 1.0.19rc5, 1.2.11rc5 [June 22, 2006] - Removed png_sig_bytes entry from scripts/pngw32.def - -Version 1.0.19, 1.2.11 [June 26, 2006] - None. - -Version 1.0.20, 1.2.12 [June 27, 2006] - Really increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid - buffer overflow. - -Version 1.2.13beta1 [October 2, 2006] - Removed AC_FUNC_MALLOC from configure.ac - Work around Intel-Mac compiler bug by setting PNG_NO_MMX_CODE in pngconf.h - Change "logical" to "bitwise" throughout documentation. - Detect and fix attempt to write wrong iCCP profile length (CVE-2006-7244) - -Version 1.0.21, 1.2.13 [November 14, 2006] - Fix potential buffer overflow in sPLT chunk handler. - Fix Makefile.am to not try to link to noexistent files. - Check all exported functions for NULL png_ptr. - -Version 1.2.14beta1 [November 17, 2006] - Relocated three misplaced tests for NULL png_ptr. - Built Makefile.in with automake-1.9.6 instead of 1.9.2. - Build configure with autoconf-2.60 instead of 2.59 - -Version 1.2.14beta2 [November 17, 2006] - Added some typecasts in png_zalloc(). - -Version 1.2.14rc1 [November 20, 2006] - Changed "strtod" to "png_strtod" in pngrutil.c - -Version 1.0.22, 1.2.14 [November 27, 2006] - Added missing "$(srcdir)" in Makefile.am and Makefile.in - -Version 1.2.15beta1 [December 3, 2006] - Generated configure with autoconf-2.61 instead of 2.60 - Revised configure.ac to update libpng.pc and libpng-config. - -Version 1.2.15beta2 [December 3, 2006] - Always export MMX asm functions, just stubs if not building pnggccrd.c - -Version 1.2.15beta3 [December 4, 2006] - Add "png_bytep" typecast to profile while calculating length in pngwutil.c - -Version 1.2.15beta4 [December 7, 2006] - Added scripts/CMakeLists.txt - Changed PNG_NO_ASSEMBLER_CODE to PNG_NO_MMX_CODE in scripts, like 1.4.0beta - -Version 1.2.15beta5 [December 7, 2006] - Changed some instances of PNG_ASSEMBLER_* to PNG_MMX_* in pnggccrd.c - Revised scripts/CMakeLists.txt - -Version 1.2.15beta6 [December 13, 2006] - Revised scripts/CMakeLists.txt and configure.ac - -Version 1.2.15rc1 [December 18, 2006] - Revised scripts/CMakeLists.txt - -Version 1.2.15rc2 [December 21, 2006] - Added conditional #undef jmpbuf in pngtest.c to undo #define in AIX headers. - Added scripts/makefile.nommx - -Version 1.2.15rc3 [December 25, 2006] - Fixed shared library numbering error that was introduced in 1.2.15beta6. - -Version 1.2.15rc4 [December 27, 2006] - Fixed handling of rgb_to_gray when png_ptr->color.gray isn't set. - -Version 1.2.15rc5 [December 31, 2006] - Revised handling of rgb_to_gray. - -Version 1.2.15 [January 5, 2007] - Added some (unsigned long) typecasts in pngtest.c to avoid printing errors. - -Version 1.2.16beta1 [January 6, 2007] - Fix bugs in makefile.nommx - -Version 1.2.16beta2 [January 16, 2007] - Revised scripts/CMakeLists.txt - -Version 1.2.16 [January 31, 2007] - No changes. - -Version 1.2.17beta1 [March 6, 2007] - Revised scripts/CMakeLists.txt to install both shared and static libraries. - Deleted a redundant line from pngset.c. - -Version 1.2.17beta2 [April 26, 2007] - Relocated misplaced test for png_ptr == NULL in pngpread.c - Change "==" to "&" for testing PNG_RGB_TO_GRAY_ERR & PNG_RGB_TO_GRAY_WARN - flags. - Changed remaining instances of PNG_ASSEMBLER_* to PNG_MMX_* - Added pngerror() when write_IHDR fails in deflateInit2(). - Added "const" to some array declarations. - Mention examples of libpng usage in the libpng*.txt and libpng.3 documents. - -Version 1.2.17rc1 [May 4, 2007] - No changes. - -Version 1.2.17rc2 [May 8, 2007] - Moved several PNG_HAVE_* macros out of PNG_INTERNAL because applications - calling set_unknown_chunk_location() need them. - Changed transformation flag from PNG_EXPAND_tRNS to PNG_EXPAND in - png_set_expand_gray_1_2_4_to_8(). - Added png_ptr->unknown_chunk to hold working unknown chunk data, so it - can be free'ed in case of error. Revised unknown chunk handling in - pngrutil.c and pngpread.c to use this structure. - -Version 1.2.17rc3 [May 8, 2007] - Revised symbol-handling in configure script. - -Version 1.2.17rc4 [May 10, 2007] - Revised unknown chunk handling to avoid storing unknown critical chunks. - -Version 1.0.25 [May 15, 2007] -Version 1.2.17 [May 15, 2007] - Added "png_ptr->num_trans=0" before error return in png_handle_tRNS, - to eliminate a vulnerability (CVE-2007-2445, CERT VU#684664) - -Version 1.0.26 [May 15, 2007] -Version 1.2.18 [May 15, 2007] - Reverted the libpng-1.2.17rc3 change to symbol-handling in configure script - -Version 1.2.19beta1 [May 18, 2007] - Changed "const static" to "static PNG_CONST" everywhere, mostly undoing - change of libpng-1.2.17beta2. Changed other "const" to "PNG_CONST" - Changed some handling of unused parameters, to avoid compiler warnings. - "if (unused == NULL) return;" becomes "unused = unused". - -Version 1.2.19beta2 [May 18, 2007] - Only use the valid bits of tRNS value in png_do_expand() (Brian Cartier) - -Version 1.2.19beta3 [May 19, 2007] - Add some "png_byte" typecasts in png_check_keyword() and write new_key - instead of key in zTXt chunk (Kevin Ryde). - -Version 1.2.19beta4 [May 21, 2007] - Add png_snprintf() function and use it in place of sprint() for improved - defense against buffer overflows. - -Version 1.2.19beta5 [May 21, 2007] - Fixed png_handle_tRNS() to only use the valid bits of tRNS value. - Changed handling of more unused parameters, to avoid compiler warnings. - Removed some PNG_CONST in pngwutil.c to avoid compiler warnings. - -Version 1.2.19beta6 [May 22, 2007] - Added some #ifdef PNG_MMX_CODE_SUPPORTED where needed in pngvcrd.c - Added a special "_MSC_VER" case that defines png_snprintf to _snprintf - -Version 1.2.19beta7 [May 22, 2007] - Squelched png_squelch_warnings() in pnggccrd.c and added - an #ifdef PNG_MMX_CODE_SUPPORTED block around the declarations that caused - the warnings that png_squelch_warnings was squelching. - -Version 1.2.19beta8 [May 22, 2007] - Removed __MMX__ from test in pngconf.h. - -Version 1.2.19beta9 [May 23, 2007] - Made png_squelch_warnings() available via PNG_SQUELCH_WARNINGS macro. - Revised png_squelch_warnings() so it might work. - Updated makefile.sgcc and makefile.solaris; added makefile.solaris-x86. - -Version 1.2.19beta10 [May 24, 2007] - Resquelched png_squelch_warnings(), use "__attribute__((used))" instead. - -Version 1.4.0beta1 [April 20, 2006] - Enabled iTXt support (changes png_struct, thus requires so-number change). - Cleaned up PNG_ASSEMBLER_CODE_SUPPORTED vs PNG_MMX_CODE_SUPPORTED - Eliminated PNG_1_0_X and PNG_1_2_X macros. - Removed deprecated functions png_read_init, png_write_init, png_info_init, - png_permit_empty_plte, png_set_gray_1_2_4_to_8, png_check_sig, and - removed the deprecated macro PNG_MAX_UINT. - Moved "PNG_INTERNAL" parts of png.h and pngconf.h into pngintrn.h - Removed many WIN32_WCE #ifdefs (Cosmin). - Reduced dependency on C-runtime library when on Windows (Simon-Pierre) - Replaced sprintf() with png_sprintf() (Simon-Pierre) - -Version 1.4.0beta2 [April 20, 2006] - Revised makefiles and configure to avoid making links to libpng.so.* - Moved some leftover MMX-related defines from pngconf.h to pngintrn.h - Updated scripts/pngos2.def, pngw32.def, and projects/wince/png32ce.def - -Version 1.4.0beta3 [May 10, 2006] - Updated scripts/pngw32.def to comment out MMX functions. - Added PNG_NO_GET_INT_32 and PNG_NO_SAVE_INT_32 macros. - Scripts/libpng.pc.in contained "configure" style version info and would - not work with makefiles. - Revised pngconf.h and added pngconf.h.in, so makefiles and configure can - pass defines to libpng and applications. - -Version 1.4.0beta4 [May 11, 2006] - Revised configure.ac, Makefile.am, and many of the makefiles to write - their defines in pngconf.h. - -Version 1.4.0beta5 [May 15, 2006] - Added a missing semicolon in Makefile.am and Makefile.in - Deleted extraneous square brackets from configure.ac - -Version 1.4.0beta6 [June 2, 2006] - Increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid - buffer overflow. - Changed sonum from 0 to 1. - Removed unused prototype for png_check_sig() from png.h - -Version 1.4.0beta7 [June 16, 2006] - Exported png_write_sig (Cosmin). - Optimized buffer in png_handle_cHRM() (Cosmin). - Set pHYs = 2835 x 2835 pixels per meter, and added - sCAL = 0.352778e-3 x 0.352778e-3 meters, in pngtest.png (Cosmin). - Added png_set_benign_errors(), png_benign_error(), png_chunk_benign_error(). - Added typedef for png_int_32 and png_uint_32 on 64-bit systems. - Added "(unsigned long)" typecast on png_uint_32 variables in printf lists. - -Version 1.4.0beta8 [June 22, 2006] - Added demonstration of user chunk support in pngtest.c, to support the - public sTER chunk and a private vpAg chunk. - -Version 1.4.0beta9 [July 3, 2006] - Removed ordinals from scripts/pngw32.def and removed png_info_int and - png_set_gray_1_2_4_to_8 entries. - Inline call of png_get_uint_32() in png_get_uint_31(). - Use png_get_uint_31() to get vpAg width and height in pngtest.c - Removed WINCE and Netware projects. - Removed standalone Y2KINFO file. - -Version 1.4.0beta10 [July 12, 2006] - Eliminated automatic copy of pngconf.h to pngconf.h.in from configure and - some makefiles, because it was not working reliably. Instead, distribute - pngconf.h.in along with pngconf.h and cause configure and some of the - makefiles to update pngconf.h from pngconf.h.in. - Added pngconf.h to DEPENDENCIES in Makefile.am - -Version 1.4.0beta11 [August 19, 2006] - Removed AC_FUNC_MALLOC from configure.ac. - Added a warning when writing iCCP profile with mismatched profile length. - Patched pnggccrd.c to assemble on x86_64 platforms. - Moved chunk header reading into a separate function png_read_chunk_header() - in pngrutil.c. The chunk header (len+sig) is now serialized in a single - operation (Cosmin). - Implemented support for I/O states. Added png_ptr member io_state, and - functions png_get_io_chunk_name() and png_get_io_state() in pngget.c - (Cosmin). - Added png_get_io_chunk_name and png_get_io_state to scripts/*.def (Cosmin). - Renamed scripts/pngw32.* to scripts/pngwin.* (Cosmin). - Removed the include directories and libraries from CFLAGS and LDFLAGS - in scripts/makefile.gcc (Cosmin). - Used png_save_uint_32() to set vpAg width and height in pngtest.c (Cosmin). - Cast to proper type when getting/setting vpAg units in pngtest.c (Cosmin). - Added pngintrn.h to the Visual C++ projects (Cosmin). - Removed scripts/list (Cosmin). - Updated copyright year in scripts/pngwin.def (Cosmin). - Removed PNG_TYPECAST_NULL and used standard NULL consistently (Cosmin). - Disallowed the user to redefine png_size_t, and enforced a consistent use - of png_size_t across libpng (Cosmin). - Changed the type of png_ptr->rowbytes, PNG_ROWBYTES() and friends - to png_size_t (Cosmin). - Removed png_convert_size() and replaced png_sizeof with sizeof (Cosmin). - Removed some unnecessary type casts (Cosmin). - Changed prototype of png_get_compression_buffer_size() and - png_set_compression_buffer_size() to work with png_size_t instead of - png_uint_32 (Cosmin). - Removed png_memcpy_check() and png_memset_check() (Cosmin). - Fixed a typo (png_byte --> png_bytep) in libpng.3 and libpng.txt (Cosmin). - Clarified that png_zalloc() does not clear the allocated memory, - and png_zalloc() and png_zfree() cannot be PNGAPI (Cosmin). - Renamed png_mem_size_t to png_alloc_size_t, fixed its definition in - pngconf.h, and used it in all memory allocation functions (Cosmin). - Renamed pngintrn.h to pngpriv.h, added a comment at the top of the file - mentioning that the symbols declared in that file are private, and - updated the scripts and the Visual C++ projects accordingly (Cosmin). - Removed circular references between pngconf.h and pngconf.h.in in - scripts/makefile.vc*win32 (Cosmin). - Removing trailing '.' from the warning and error messages (Cosmin). - Added pngdefs.h that is built by makefile or configure, instead of - pngconf.h.in (Glenn). - Detect and fix attempt to write wrong iCCP profile length. - -Version 1.4.0beta12 [October 19, 2006] - Changed "logical" to "bitwise" in the documentation. - Work around Intel-Mac compiler bug by setting PNG_NO_MMX_CODE in pngconf.h - Add a typecast to stifle compiler warning in pngrutil.c - -Version 1.4.0beta13 [November 10, 2006] - Fix potential buffer overflow in sPLT chunk handler. - Fix Makefile.am to not try to link to noexistent files. - -Version 1.4.0beta14 [November 15, 2006] - Check all exported functions for NULL png_ptr. - -Version 1.4.0beta15 [November 17, 2006] - Relocated two misplaced tests for NULL png_ptr. - Built Makefile.in with automake-1.9.6 instead of 1.9.2. - Build configure with autoconf-2.60 instead of 2.59 - Add "install: all" in Makefile.am so "configure; make install" will work. - -Version 1.4.0beta16 [November 17, 2006] - Added a typecast in png_zalloc(). - -Version 1.4.0beta17 [December 4, 2006] - Changed "new_key[79] = '\0';" to "(*new_key)[79] = '\0';" in pngwutil.c - Add "png_bytep" typecast to profile while calculating length in pngwutil.c - -Version 1.4.0beta18 [December 7, 2006] - Added scripts/CMakeLists.txt - -Version 1.4.0beta19 [May 16, 2007] - Revised scripts/CMakeLists.txt - Rebuilt configure and Makefile.in with newer tools. - Added conditional #undef jmpbuf in pngtest.c to undo #define in AIX headers. - Added scripts/makefile.nommx - -Version 1.4.0beta20 [July 9, 2008] - Moved several PNG_HAVE_* macros from pngpriv.h to png.h because applications - calling set_unknown_chunk_location() need them. - Moved several macro definitions from pngpriv.h to pngconf.h - Merge with changes to the 1.2.X branch, as of 1.2.30beta04. - Deleted all use of the MMX assembler code and Intel-licensed optimizations. - Revised makefile.mingw - -Version 1.4.0beta21 [July 21, 2008] - Moved local array "chunkdata" from pngrutil.c to the png_struct, so - it will be freed by png_read_destroy() in case of a read error (Kurt - Christensen). - -Version 1.4.0beta22 [July 21, 2008] - Change "purpose" and "buffer" to png_ptr->chunkdata to avoid memory leaking. - -Version 1.4.0beta23 [July 22, 2008] - Change "chunkdata = NULL" to "png_ptr->chunkdata = NULL" several places in - png_decompress_chunk(). - -Version 1.4.0beta24 [July 25, 2008] - Change all remaining "chunkdata" to "png_ptr->chunkdata" in - png_decompress_chunk(), and remove "chunkdata" from parameter list. - Put a call to png_check_chunk_name() in png_read_chunk_header(). - Revised png_check_chunk_name() to reject a name with a lowercase 3rd byte. - Removed two calls to png_check_chunk_name() occurring later in the process. - Define PNG_NO_ERROR_NUMBERS by default in pngconf.h - -Version 1.4.0beta25 [July 30, 2008] - Added a call to png_check_chunk_name() in pngpread.c - Reverted png_check_chunk_name() to accept a name with a lowercase 3rd byte. - Added png_push_have_buffer() function to pngpread.c - Eliminated PNG_BIG_ENDIAN_SUPPORTED and associated png_get_* macros. - Made inline expansion of png_get_*() optional with PNG_USE_READ_MACROS. - Eliminated all PNG_USELESS_TESTS and PNG_CORRECT_PALETTE_SUPPORTED code. - Synced contrib directory and configure files with libpng-1.2.30beta06. - Eliminated no-longer-used pngdefs.h (but it's still built in the makefiles) - Relocated a misplaced "#endif /* PNG_NO_WRITE_FILTER */" in pngwutil.c - -Version 1.4.0beta26 [August 4, 2008] - Removed png_push_have_buffer() function in pngpread.c. It increased the - compiled library size slightly. - Changed "-Wall" to "-W -Wall" in the CFLAGS in all makefiles (Cosmin Truta) - Declared png_ptr "volatile" in pngread.c and pngwrite.c to avoid warnings. - Updated contrib/visupng/cexcept.h to version 2.0.1 - Added PNG_LITERAL_CHARACTER macros for #, [, and ]. - -Version 1.4.0beta27 [August 5, 2008] - Revised usage of PNG_LITERAL_SHARP in pngerror.c. - Moved newline character from individual png_debug messages into the - png_debug macros. - Allow user to #define their own png_debug, png_debug1, and png_debug2. - -Version 1.4.0beta28 [August 5, 2008] - Revised usage of PNG_LITERAL_SHARP in pngerror.c. - Added PNG_STRING_NEWLINE macro - -Version 1.4.0beta29 [August 9, 2008] - Revised usage of PNG_STRING_NEWLINE to work on non-ISO compilers. - Added PNG_STRING_COPYRIGHT macro. - Added non-ISO versions of png_debug macros. - -Version 1.4.0beta30 [August 14, 2008] - Added premultiplied alpha feature (Volker Wiendl). - -Version 1.4.0beta31 [August 18, 2008] - Moved png_set_premultiply_alpha from pngtrans.c to pngrtran.c - Removed extra crc check at the end of png_handle_cHRM(). Bug introduced - in libpng-1.4.0beta20. - -Version 1.4.0beta32 [August 19, 2008] - Added PNG_WRITE_FLUSH_SUPPORTED block around new png_flush() call. - Revised PNG_NO_STDIO version of png_write_flush() - -Version 1.4.0beta33 [August 20, 2008] - Added png_get|set_chunk_cache_max() to limit the total number of sPLT, - text, and unknown chunks that can be stored. - -Version 1.4.0beta34 [September 6, 2008] - Shortened tIME_string to 29 bytes in pngtest.c - Fixed off-by-one error introduced in png_push_read_zTXt() function in - libpng-1.2.30beta04/pngpread.c (Harald van Dijk) - -Version 1.4.0beta35 [October 6, 2008] - Changed "trans_values" to "trans_color". - Changed so-number from 0 to 14. Some OS do not like 0. - Revised makefile.darwin to fix shared library numbering. - Change png_set_gray_1_2_4_to_8() to png_set_expand_gray_1_2_4_to_8() - in example.c (debian bug report) - -Version 1.4.0beta36 [October 25, 2008] - Sync with tEXt vulnerability fix in libpng-1.2.33rc02. - -Version 1.4.0beta37 [November 13, 2008] - Added png_check_cHRM in png.c and moved checking from pngget.c, pngrutil.c, - and pngwrite.c - -Version 1.4.0beta38 [November 22, 2008] - Added check for zero-area RGB cHRM triangle in png_check_cHRM() and - png_check_cHRM_fixed(). - -Version 1.4.0beta39 [November 23, 2008] - Revised png_warning() to write its message on standard output by default - when warning_fn is NULL. - -Version 1.4.0beta40 [November 24, 2008] - Eliminated png_check_cHRM(). Instead, always use png_check_cHRM_fixed(). - In png_check_cHRM_fixed(), ensure white_y is > 0, and removed redundant - check for all-zero coordinates that is detected by the triangle check. - -Version 1.4.0beta41 [November 26, 2008] - Fixed string vs pointer-to-string error in png_check_keyword(). - Rearranged test expressions in png_check_cHRM_fixed() to avoid internal - overflows. - Added PNG_NO_CHECK_cHRM conditional. - -Version 1.4.0beta42, 43 [December 1, 2008] - Merge png_debug with version 1.2.34beta04. - -Version 1.4.0beta44 [December 6, 2008] - Removed redundant check for key==NULL before calling png_check_keyword() - to ensure that new_key gets initialized and removed extra warning - (Merge with version 1.2.34beta05 -- Arvan Pritchard). - -Version 1.4.0beta45 [December 9, 2008] - In png_write_png(), respect the placement of the filler bytes in an earlier - call to png_set_filler() (Jim Barry). - -Version 1.4.0beta46 [December 10, 2008] - Undid previous change and added PNG_TRANSFORM_STRIP_FILLER_BEFORE and - PNG_TRANSFORM_STRIP_FILLER_AFTER conditionals and deprecated - PNG_TRANSFORM_STRIP_FILLER (Jim Barry). - -Version 1.4.0beta47 [December 15, 2008] - Support for dithering was disabled by default, because it has never - been well tested and doesn't work very well. The code has not - been removed, however, and can be enabled by building libpng with - PNG_READ_DITHER_SUPPORTED defined. - -Version 1.4.0beta48 [February 14, 2009] - Added new exported function png_calloc(). - Combined several instances of png_malloc(); png_memset() into png_calloc(). - Removed prototype for png_freeptr() that was added in libpng-1.4.0beta24 - but was never defined. - -Version 1.4.0beta49 [February 28, 2009] - Added png_fileno() macro to pngconf.h, used in pngwio.c - Corrected order of #ifdef's in png_debug definition in png.h - Fixed bug introduced in libpng-1.4.0beta48 with the memset arguments - for pcal_params. - Fixed order of #ifdef directives in the png_debug defines in png.h - (bug introduced in libpng-1.2.34/1.4.0beta29). - Revised comments in png_set_read_fn() and png_set_write_fn(). - -Version 1.4.0beta50 [March 18, 2009] - Use png_calloc() instead of png_malloc() to allocate big_row_buf when - reading an interlaced file, to avoid a possible UMR. - Undid revision of PNG_NO_STDIO version of png_write_flush(). Users - having trouble with fflush() can build with PNG_NO_WRITE_FLUSH defined - or supply their own flush_fn() replacement. - Revised libpng*.txt and png.h documentation about use of png_write_flush() - and png_set_write_fn(). - Removed fflush() from pngtest.c. - Added "#define PNG_NO_WRITE_FLUSH" to contrib/pngminim/encoder/pngusr.h - -Version 1.4.0beta51 [March 21, 2009] - Removed new png_fileno() macro from pngconf.h . - -Version 1.4.0beta52 [March 27, 2009] - Relocated png_do_chop() ahead of building gamma tables in pngrtran.c - This avoids building 16-bit gamma tables unnecessarily. - Removed fflush() from pngtest.c. - Added "#define PNG_NO_WRITE_FLUSH" to contrib/pngminim/encoder/pngusr.h - Added a section on differences between 1.0.x and 1.2.x to libpng.3/libpng.txt - -Version 1.4.0beta53 [April 1, 2009] - Removed some remaining MMX macros from pngpriv.h - Fixed potential memory leak of "new_name" in png_write_iCCP() (Ralph Giles) - -Version 1.4.0beta54 [April 13, 2009] - Added "ifndef PNG_SKIP_SETJMP_CHECK" block in pngconf.h to allow - application code writers to bypass the check for multiple inclusion - of setjmp.h when they know that it is safe to ignore the situation. - Eliminated internal use of setjmp() in pngread.c and pngwrite.c - Reordered ancillary chunks in pngtest.png to be the same as what - pngtest now produces, and made some cosmetic changes to pngtest output. - Eliminated deprecated png_read_init_3() and png_write_init_3() functions. - -Version 1.4.0beta55 [April 15, 2009] - Simplified error handling in pngread.c and pngwrite.c by putting - the new png_read_cleanup() and png_write_cleanup() functions inline. - -Version 1.4.0beta56 [April 25, 2009] - Renamed "user_chunk_data" to "my_user_chunk_data" in pngtest.c to suppress - "shadowed declaration" warning from gcc-4.3.3. - Renamed "gamma" to "png_gamma" in pngset.c to avoid "shadowed declaration" - warning about a global "gamma" variable in math.h on some platforms. - -Version 1.4.0beta57 [May 2, 2009] - Removed prototype for png_freeptr() that was added in libpng-1.4.0beta24 - but was never defined (again). - Rebuilt configure scripts with autoconf-2.63 instead of 2.62 - Removed pngprefs.h and MMX from makefiles - -Version 1.4.0beta58 [May 14, 2009] - Changed pngw32.def to pngwin.def in makefile.mingw (typo was introduced - in beta57). - Clarified usage of sig_bit versus sig_bit_p in example.c (Vincent Torri) - -Version 1.4.0beta59 [May 15, 2009] - Reformated sources in libpng style (3-space intentation, comment format) - Fixed typo in libpng docs (PNG_FILTER_AVE should be PNG_FILTER_AVG) - Added sections about the git repository and our coding style to the - documentation - Relocated misplaced #endif in pngwrite.c, sCAL chunk handler. - -Version 1.4.0beta60 [May 19, 2009] - Conditionally compile png_read_finish_row() which is not used by - progressive readers. - Added contrib/pngminim/preader to demonstrate building minimal progressive - decoder, based on contrib/gregbook with embedded libpng and zlib. - -Version 1.4.0beta61 [May 20, 2009] - In contrib/pngminim/*, renamed "makefile.std" to "makefile", since there - is only one makefile in those directories, and revised the README files - accordingly. - More reformatting of comments, mostly to capitalize sentences. - -Version 1.4.0beta62 [June 2, 2009] - Added "#define PNG_NO_WRITE_SWAP" to contrib/pngminim/encoder/pngusr.h - and "define PNG_NO_READ_SWAP" to decoder/pngusr.h and preader/pngusr.h - Reformatted several remaining "else statement" into two lines. - Added a section to the libpng documentation about using png_get_io_ptr() - in configure scripts to detect the presence of libpng. - -Version 1.4.0beta63 [June 15, 2009] - Revised libpng*.txt and libpng.3 to mention calling png_set_IHDR() - multiple times and to specify the sample order in the tRNS chunk, - because the ISO PNG specification has a typo in the tRNS table. - Changed several PNG_UNKNOWN_CHUNK_SUPPORTED to - PNG_HANDLE_AS_UNKNOWN_SUPPORTED, to make the png_set_keep mechanism - available for ignoring known chunks even when not saving unknown chunks. - Adopted preference for consistent use of "#ifdef" and "#ifndef" versus - "#if defined()" and "if !defined()" where possible. - -Version 1.4.0beta64 [June 24, 2009] - Eliminated PNG_LEGACY_SUPPORTED code. - Moved the various unknown chunk macro definitions outside of the - PNG_READ|WRITE_ANCILLARY_CHUNK_SUPPORTED blocks. - -Version 1.4.0beta65 [June 26, 2009] - Added a reference to the libpng license in each file. - -Version 1.4.0beta66 [June 27, 2009] - Refer to the libpng license instead of the libpng license in each file. - -Version 1.4.0beta67 [July 6, 2009] - Relocated INVERT_ALPHA within png_read_png() and png_write_png(). - Added high-level API transform PNG_TRANSFORM_GRAY_TO_RGB. - Added an "xcode" project to the projects directory (Alam Arias). - -Version 1.4.0beta68 [July 19, 2009] - Avoid some tests in filter selection in pngwutil.c - -Version 1.4.0beta69 [July 25, 2009] - Simplified the new filter-selection test. This runs faster in the - common "PNG_ALL_FILTERS" and PNG_FILTER_NONE cases. - Removed extraneous declaration from the new call to png_read_gray_to_rgb() - (bug introduced in libpng-1.4.0beta67). - Fixed up xcode project (Alam Arias) - Added a prototype for png_64bit_product() in png.c - -Version 1.4.0beta70 [July 27, 2009] - Avoid a possible NULL dereference in debug build, in png_set_text_2(). - (bug introduced in libpng-0.95, discovered by Evan Rouault) - -Version 1.4.0beta71 [July 29, 2009] - Rebuilt configure scripts with autoconf-2.64. - -Version 1.4.0beta72 [August 1, 2009] - Replaced *.tar.lzma with *.tar.xz in distribution. Get the xz codec - from . - -Version 1.4.0beta73 [August 1, 2009] - Reject attempt to write iCCP chunk with negative embedded profile length - (JD Chen) (CVE-2009-5063). - -Version 1.4.0beta74 [August 8, 2009] - Changed png_ptr and info_ptr member "trans" to "trans_alpha". - -Version 1.4.0beta75 [August 21, 2009] - Removed an extra png_debug() recently added to png_write_find_filter(). - Fixed incorrect #ifdef in pngset.c regarding unknown chunk support. - -Version 1.4.0beta76 [August 22, 2009] - Moved an incorrectly located test in png_read_row() in pngread.c - -Version 1.4.0beta77 [August 27, 2009] - Removed lpXYZ.tar.bz2 (with CRLF), KNOWNBUG, libpng-x.y.z-KNOWNBUG.txt, - and the "noconfig" files from the distribution. - Moved CMakeLists.txt from scripts into the main libpng directory. - Various bugfixes and improvements to CMakeLists.txt (Philip Lowman) - -Version 1.4.0beta78 [August 31, 2009] - Converted all PNG_NO_* tests to PNG_*_SUPPORTED everywhere except pngconf.h - Eliminated PNG_NO_FREE_ME and PNG_FREE_ME_SUPPORTED macros. - Use png_malloc plus a loop instead of png_calloc() to initialize - row_pointers in png_read_png(). - -Version 1.4.0beta79 [September 1, 2009] - Eliminated PNG_GLOBAL_ARRAYS and PNG_LOCAL_ARRAYS; always use local arrays. - Eliminated PNG_CALLOC_SUPPORTED macro and always provide png_calloc(). - -Version 1.4.0beta80 [September 17, 2009] - Removed scripts/libpng.icc - Changed typecast of filler from png_byte to png_uint_16 in png_set_filler(). - (Dennis Gustafsson) - Fixed typo introduced in beta78 in pngtest.c ("#if def " should be "#ifdef ") - -Version 1.4.0beta81 [September 23, 2009] - Eliminated unused PNG_FLAG_FREE_* defines from pngpriv.h - Expanded TAB characters in pngrtran.c - Removed PNG_CONST from all "PNG_CONST PNG_CHNK" declarations to avoid - compiler complaints about doubly declaring things "const". - Changed all "#if [!]defined(X)" to "if[n]def X" where possible. - Eliminated unused png_ptr->row_buf_size - -Version 1.4.0beta82 [September 25, 2009] - Moved redundant IHDR checking into new png_check_IHDR() in png.c - and report all errors found in the IHDR data. - Eliminated useless call to png_check_cHRM() from pngset.c - -Version 1.4.0beta83 [September 25, 2009] - Revised png_check_IHDR() to eliminate bogus complaint about filter_type. - -Version 1.4.0beta84 [September 30, 2009] - Fixed some inconsistent indentation in pngconf.h - Revised png_check_IHDR() to add a test for width variable less than 32-bit. - -Version 1.4.0beta85 [October 1, 2009] - Revised png_check_IHDR() again, to check info_ptr members instead of - the contents of the returned parameters. - -Version 1.4.0beta86 [October 9, 2009] - Updated the "xcode" project (Alam Arias). - Eliminated a shadowed declaration of "pp" in png_handle_sPLT(). - -Version 1.4.0rc01 [October 19, 2009] - Trivial cosmetic changes. - -Version 1.4.0beta87 [October 30, 2009] - Moved version 1.4.0 back into beta. - -Version 1.4.0beta88 [October 30, 2009] - Revised libpng*.txt section about differences between 1.2.x and 1.4.0 - because most of the new features have now been ported back to 1.2.41 - -Version 1.4.0beta89 [November 1, 2009] - More bugfixes and improvements to CMakeLists.txt (Philip Lowman) - Removed a harmless extra png_set_invert_alpha() from pngwrite.c - Apply png_user_chunk_cache_max within png_decompress_chunk(). - Merged libpng-1.2.41.txt with libpng-1.4.0.txt where appropriate. - -Version 1.4.0beta90 [November 2, 2009] - Removed all remaining WIN32_WCE #ifdefs except those involving the - time.h "tm" structure - -Version 1.4.0beta91 [November 3, 2009] - Updated scripts/pngw32.def and projects/wince/png32ce.def - Copied projects/wince/png32ce.def to the scripts directory. - Added scripts/makefile.wce - Patched ltmain.sh for wince support. - Added PNG_CONVERT_tIME_SUPPORTED macro. - -Version 1.4.0beta92 [November 4, 2009] - Make inclusion of time.h in pngconf.h depend on PNG_CONVERT_tIME_SUPPORTED - Make #define PNG_CONVERT_tIME_SUPPORTED depend on PNG_WRITE_tIME_SUPPORTED - Revised libpng*.txt to describe differences from 1.2.40 to 1.4.0 (instead - of differences from 1.2.41 to 1.4.0) - -Version 1.4.0beta93 [November 7, 2009] - Added PNG_DEPSTRUCT, PNG_DEPRECATED, PNG_USE_RESULT, PNG_NORETURN, and - PNG_ALLOCATED macros to detect deprecated direct access to the - png_struct or info_struct members and other deprecated usage in - applications (John Bowler). - Updated scripts/makefile* to add "-DPNG_CONFIGURE_LIBPNG" to CFLAGS, - to prevent warnings about direct access to png structs by libpng - functions while building libpng. They need to be tested, especially - those using compilers other than gcc. - Updated projects/visualc6 and visualc71 with "/d PNG_CONFIGURE_LIBPNG". - They should work but still need to be updated to remove - references to pnggccrd.c or pngvcrd.c and ASM building. - Added README.txt to the beos, cbuilder5, netware, and xcode projects warning - that they need to be updated, to remove references to pnggccrd.c and - pngvcrd.c and to depend on pngpriv.h - Removed three direct references to read_info_ptr members in pngtest.c - that were detected by the new PNG_DEPSTRUCT macro. - Moved the png_debug macro definitions and the png_read_destroy(), - png_write_destroy() and png_far_to_near() prototypes from png.h - to pngpriv.h (John Bowler) - Moved the synopsis lines for png_read_destroy(), png_write_destroy() - png_debug(), png_debug1(), and png_debug2() from libpng.3 to libpngpf.3. - -Version 1.4.0beta94 [November 9, 2009] - Removed the obsolete, unused pnggccrd.c and pngvcrd.c files. - Updated CMakeLists.txt to add "-DPNG_CONFIGURE_LIBPNG" to the definitions. - Removed dependency of pngtest.o on pngpriv.h in the makefiles. - Only #define PNG_DEPSTRUCT, etc. in pngconf.h if not already defined. - -Version 1.4.0beta95 [November 10, 2009] - Changed png_check_sig() to !png_sig_cmp() in contrib programs. - Added -DPNG_CONFIGURE_LIBPNG to contrib/pngminm/*/makefile - Changed png_check_sig() to !png_sig_cmp() in contrib programs. - Corrected the png_get_IHDR() call in contrib/gregbook/readpng2.c - Changed pngminim/*/gather.sh to stop trying to remove pnggccrd.c and pngvcrd.c - Added dependency on pngpriv.h in contrib/pngminim/*/makefile - -Version 1.4.0beta96 [November 12, 2009] - Renamed scripts/makefile.wce to scripts/makefile.cegcc - Revised Makefile.am to use libpng.sys while building libpng.so - so that only PNG_EXPORT functions are exported. - Removed the deprecated png_check_sig() function/macro. - Removed recently removed function names from scripts/*.def - Revised pngtest.png to put chunks in the same order written by pngtest - (evidently the same change made in libpng-1.0beta54 was lost). - Added PNG_PRIVATE macro definition in pngconf.h for possible future use. - -Version 1.4.0beta97 [November 13, 2009] - Restored pngtest.png to the libpng-1.4.0beta7 version. - Removed projects/beos and netware.txt; no one seems to be supporting them. - Revised Makefile.in - -Version 1.4.0beta98 [November 13, 2009] - Added the "xcode" project to zip distributions, - Fixed a typo in scripts/pngwin.def introduced in beta97. - -Version 1.4.0beta99 [November 14, 2009] - Moved libpng-config.in and libpng.pc-configure.in out of the scripts - directory, to libpng-config.in and libpng-pc.in, respectively, and - modified Makefile.am and configure.ac accordingly. Now "configure" - needs nothing from the "scripts" directory. - Avoid redefining PNG_CONST in pngconf.h - -Version 1.4.0beta100 [November 14, 2009] - Removed ASM builds from projects/visualc6 and projects/visualc71 - Removed scripts/makefile.nommx and makefile.vcawin32 - Revised CMakeLists.txt to account for new location of libpng-config.in - and libpng-pc.in - Updated INSTALL to reflect removal and relocation of files. - -Version 1.4.0beta101 [November 14, 2009] - Restored the binary files (*.jpg, *.png, some project files) that were - accidentally deleted from the zip and 7z distributions when the xcode - project was added. - -Version 1.4.0beta102 [November 18, 2009] - Added libpng-config.in and libpng-pc.in to the zip and 7z distributions. - Fixed a typo in projects/visualc6/pngtest.dsp, introduced in beta100. - Moved descriptions of makefiles and other scripts out of INSTALL into - scripts/README.txt - Updated the copyright year in scripts/pngwin.rc from 2006 to 2009. - -Version 1.4.0beta103 [November 21, 2009] - Removed obsolete comments about ASM from projects/visualc71/README_zlib.txt - Align row_buf on 16-byte boundary in memory. - Restored the PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED guard around the call - to png_flush() after png_write_IEND(). See 1.4.0beta32, 1.4.0beta50 - changes above and 1.2.30, 1.2.30rc01 and rc03 in 1.2.41 CHANGES. Someone - needs this feature. - Make the 'png_jmpbuf' macro expand to a call that records the correct - longjmp function as well as returning a pointer to the setjmp - jmp_buf buffer, and marked direct access to jmpbuf 'deprecated'. - (John Bowler) - -Version 1.4.0beta104 [November 22, 2009] - Removed png_longjmp_ptr from scripts/*.def and libpng.3 - Rebuilt configure scripts with autoconf-2.65 - -Version 1.4.0beta105 [November 25, 2009] - Use fast integer PNG_DIVIDE_BY_255() or PNG_DIVIDE_BY_65535() - to accomplish alpha premultiplication when - PNG_READ_COMPOSITE_NODIV_SUPPORTED is defined. - Changed "/255" to "/255.0" in background calculations to make it clear - that the 255 is used as a double. - -Version 1.4.0beta106 [November 27, 2009] - Removed premultiplied alpha feature. - -Version 1.4.0beta107 [December 4, 2009] - Updated README - Added "#define PNG_NO_PEDANTIC_WARNINGS" in the libpng source files. - Removed "-DPNG_CONFIGURE_LIBPNG" from the makefiles and projects. - Revised scripts/makefile.netbsd, makefile.openbsd, and makefile.sco - to put png.h and pngconf.h in $prefix/include, like the other scripts, - instead of in $prefix/include/libpng. Also revised makefile.sco - to put them in $prefix/include/libpng15 instead of in - $prefix/include/libpng/libpng15. - -Version 1.4.0beta108 [December 11, 2009] - Removed leftover "-DPNG_CONFIGURE_LIBPNG" from contrib/pngminim/*/makefile - Relocated png_do_chop() to its original position in pngrtran.c; the - change in version 1.2.41beta08 caused transparency to be handled wrong - in some 16-bit datastreams (Yusaku Sugai). - -Version 1.4.0beta109 [December 13, 2009] - Added "bit_depth" parameter to the private png_build_gamma_table() function. - Pass bit_depth=8 to png_build_gamma_table() when bit_depth is 16 but the - PNG_16_TO_8 transform has been set, to avoid unnecessary build of 16-bit - tables. - -Version 1.4.0rc02 [December 20, 2009] - Declared png_cleanup_needed "volatile" in pngread.c and pngwrite.c - -Version 1.4.0rc03 [December 22, 2009] - Renamed libpng-pc.in back to libpng.pc.in and revised CMakeLists.txt - (revising the change in 1.4.0beta99) - -Version 1.4.0rc04 [December 25, 2009] - Swapped PNG_UNKNOWN_CHUNKS_SUPPORTED and PNG_HANDLE_AS_UNKNOWN_SUPPORTED - in pngset.c to be consistent with other changes in version 1.2.38. - -Version 1.4.0rc05 [December 25, 2009] - Changed "libpng-pc.in" to "libpng.pc.in" in configure.ac, configure, and - Makefile.in to be consistent with changes in libpng-1.4.0rc03 - -Version 1.4.0rc06 [December 29, 2009] - Reverted the gamma_table changes from libpng-1.4.0beta109. - Fixed some indentation errors. - -Version 1.4.0rc07 [January 1, 2010] - Revised libpng*.txt and libpng.3 about 1.2.x->1.4.x differences. - Use png_calloc() instead of png_malloc(); png_memset() in pngrutil.c - Update copyright year to 2010. - -Version 1.4.0rc08 [January 2, 2010] - Avoid deprecated references to png_ptr-io_ptr and png_ptr->error_ptr - in pngtest.c - -Version 1.4.0 [January 3, 2010] - No changes. - -Version 1.4.1beta01 [January 8, 2010] - Updated CMakeLists.txt for consistent indentation and to avoid an - unclosed if-statement warning (Philip Lowman). - Revised Makefile.am and Makefile.in to remove references to Y2KINFO, - KNOWNBUG, and libpng.la (Robert Schwebel). - Revised the makefiles to install the same files and symbolic - links as configure, except for libpng.la and libpng14.la. - Make png_set|get_compression_buffer_size() available even when - PNG_WRITE_SUPPORTED is not enabled. - Revised Makefile.am and Makefile.in to simplify their maintenance. - Revised scripts/makefile.linux to install a link to libpng14.so.14.1 - -Version 1.4.1beta02 [January 9, 2010] - Revised the rest of the makefiles to install a link to libpng14.so.14.1 - -Version 1.4.1beta03 [January 10, 2010] - Removed png_set_premultiply_alpha() from scripts/*.def - -Version 1.4.1rc01 [January 16, 2010] - No changes. - -Version 1.4.1beta04 [January 23, 2010] - Revised png_decompress_chunk() to improve speed and memory usage when - decoding large chunks. - Added png_set|get_chunk_malloc_max() functions. - -Version 1.4.1beta05 [January 26, 2010] - Relocated "int k" declaration in pngtest.c to minimize its scope. - -Version 1.4.1beta06 [January 28, 2010] - Revised png_decompress_chunk() to use a two-pass method suggested by - John Bowler. - -Version 1.4.1beta07 [February 6, 2010] - Folded some long lines in the source files. - Added defineable PNG_USER_CHUNK_CACHE_MAX, PNG_USER_CHUNK_MALLOC_MAX, - and a PNG_USER_LIMITS_SUPPORTED flag. - Eliminated use of png_ptr->irowbytes and reused the slot in png_ptr as - png_ptr->png_user_chunk_malloc_max. - Revised png_push_save_buffer() to do fewer but larger png_malloc() calls. - -Version 1.4.1beta08 [February 6, 2010] - Minor cleanup and updating of dates and copyright year. - -Version 1.5.0beta01 [February 7, 2010] - Moved declaration of png_struct into private pngstruct.h and png_info - into pnginfo.h - -Version 1.4.1beta09 and 1.5.0beta02 [February 7, 2010] - Reverted to original png_push_save_buffer() code. - -Version 1.4.1beta10 and 1.5.0beta03 [February 8, 2010] - Return allocated "old_buffer" in png_push_save_buffer() before - calling png_error(), to avoid a potential memory leak. - Updated configure script to use SO number 15. - -Version 1.5.0beta04 [February 9, 2010] - Removed malformed "incomplete struct declaration" of png_info from png.h - -Version 1.5.0beta05 [February 12, 2010] - Removed PNG_DEPSTRUCT markup in pngstruct.h and pnginfo.h, and undid the - linewrapping that it entailed. - Revised comments in pngstruct.h and pnginfo.h and added pointers to - the libpng license. - Changed PNG_INTERNAL to PNG_EXPOSE_INTERNAL_STRUCTURES - Removed the cbuilder5 project, which has not been updated to 1.4.0. - -Version 1.4.1beta12 and 1.5.0beta06 [February 14, 2010] - Fixed type declaration of png_get_chunk_malloc_max() in pngget.c (Daisuke - Nishikawa) - -Version 1.5.0beta07 [omitted] - -Version 1.5.0beta08 [February 19, 2010] - Changed #ifdef PNG_NO_STDIO_SUPPORTED to #ifdef PNG_NO_CONSOLE_IO_SUPPORTED - wherever png_snprintf() is used to construct error and warning messages. - Noted in scripts/makefile.mingw that it expects to be run under MSYS. - Removed obsolete unused MMX-querying support from contrib/gregbook - Added exported png_longjmp() function. - Removed the AIX redefinition of jmpbuf in png.h - Added -D_ALLSOURCE in configure.ac, makefile.aix, and CMakeLists.txt - when building on AIX. - -Version 1.5.0beta09 [February 19, 2010] - Removed -D_ALLSOURCE from configure.ac, makefile.aix, and CMakeLists.txt. - Changed the name of png_ptr->jmpbuf to png_ptr->png_jmpbuf in pngstruct.h - -Version 1.5.0beta10 [February 25, 2010] - Removed unused gzio.c from contrib/pngminim gather and makefile scripts - Removed replacement error handlers from contrib/gregbook. Because of - the new png_longjmp() function they are no longer needed. - -Version 1.5.0beta11 [March 6, 2010] - Removed checking for already-included setjmp.h from pngconf.h - Fixed inconsistent indentations and made numerous cosmetic changes. - Revised the "SEE ALSO" style of libpng.3, libpngpf.3, and png.5 - -Version 1.5.0beta12 [March 9, 2010] - Moved "#include png.h" inside pngpriv.h and removed "#include png.h" from - the source files, along with "#define PNG_EXPOSE_INTERNAL_STRUCTURES" - and "#define PNG_NO_PEDANTIC_WARNINGS" (John Bowler). - Created new pngdebug.h and moved debug definitions there. - -Version 1.5.0beta13 [March 10, 2010] - Protect pngstruct.h, pnginfo.h, and pngdebug.h from being included twice. - Revise the "#ifdef" blocks in png_inflate() so it will compile when neither - PNG_USER_CHUNK_MALLOC_MAX nor PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED - is defined. - Removed unused png_measure_compressed_chunk() from pngpriv.h and libpngpf.3 - Moved the 'config.h' support from pngconf.h to pngpriv.h - Removed PNGAPI from the png_longjmp_ptr typedef. - Eliminated dependence of pngtest.c on the private pngdebug.h file. - Make all png_debug macros into *unterminated* statements or - expressions (i.e. a trailing ';' must always be added) and correct - the format statements in various png_debug messages. - -Version 1.5.0beta14 [March 14, 2010] - Removed direct access to png_ptr->io_ptr from the Windows code in pngtest.c - Revised Makefile.am to account for recent additions and replacements. - Corrected CE and OS/2 DEF files (scripts/png*def) for symbols removed and - added ordinal numbers to the Windows DEF file and corrected the duplicated - ordinal numbers on CE symbols that are commented out. - Added back in export symbols that can be present in the Windows build but - are disabled by default. - PNG_EXPORT changed to include an 'ordinal' field for DEF file generation. - PNG_CALLBACK added to make callback definitions uniform. PNGAPI split - into PNGCAPI (base C form), PNGAPI (exports) and PNGCBAPI (callbacks), - and appropriate changes made to all files. Cygwin builds re-hinged to - allow procedure call standard changes and to remove the need for the DEF - file (fixes build on Cygwin). - Enabled 'attribute' warnings that are relevant to library APIs and callbacks. - Changed rules for generation of the various symbol files and added a new - rule for a DEF file (which is also added to the distribution). - Updated the symbol file generation to stop it adding spurious spaces - to EOL (coming from preprocessor macro expansion). Added a facility - to join tokens in the output and rewrite *.dfn to use this. - Eliminated scripts/*.def in favor of libpng.def; updated projects/visualc71 - and removed scripts/makefile.cygwin. - Made PNG_BUILD_DLL safe: it can be set whenever a DLL is being built. - Removed the include of sys/types.h - apparently unnecessary now on the - platforms on which it happened (all but Mac OS and RISC OS). - Moved the Mac OS test into pngpriv.h (the only place it is used.) - -Version 1.5.0beta15 [March 17, 2010] - Added symbols.chk target to Makefile.am to validate the symbols in png.h - against the new DEF file scripts/symbols.def. - Changed the default DEF file back to pngwin.def. - Removed makefile.mingw. - Eliminated PNG_NO_EXTERN and PNG_ALL_EXTERN - -Version 1.5.0beta16 [April 1, 2010] - Make png_text_struct independent of PNG_iTXt_SUPPORTED, so that - fields are initialized in all configurations. The READ/WRITE - macros (PNG_(READ|WRITE)_iTXt_SUPPORTED) still function as - before to disable code to actually read or write iTXt chunks - and iTXt_SUPPORTED can be used to detect presence of either - read or write support (but it is probably better to check for - the one actually required - read or write.) - Combined multiple png_warning() calls for a single error. - Restored the macro definition of png_check_sig(). - -Version 1.5.0beta17 [April 17, 2010] - Added some "(long)" typecasts to printf calls in png_handle_cHRM(). - Documented the fact that png_set_dither() was disabled since libpng-1.4.0. - Reenabled png_set_dither() but renamed it to png_set_quantize() to reflect - more accurately what it actually does. At the same time, renamed - the PNG_DITHER_[RED,GREEN_BLUE]_BITS macros to - PNG_QUANTIZE_[RED,GREEN,BLUE]_BITS. - Added some "(long)" typecasts to printf calls in png_handle_cHRM(). - Freeze build-time only configuration in the build. - In all prior versions of libpng most configuration options - controlled by compiler #defines had to be repeated by the - application code that used libpng. This patch changes this - so that compilation options that can only be changed at build - time are frozen in the build. Options that are compiler - dependent (and those that are system dependent) are evaluated - each time - pngconf.h holds these. Options that can be changed - per-file in the application are in png.h. Frozen options are - in the new installed header file pnglibconf.h (John Bowler) - Removed the xcode project because it has not been updated to work - with libpng-1.5.0. - Removed the ability to include optional pngusr.h - -Version 1.5.0beta18 [April 17, 2010] - Restored the ability to include optional pngusr.h - Moved replacements for png_error() and png_warning() from the - contrib/pngminim project to pngerror.c, for use when warnings or - errors are disabled via PNG_NO_WARN or PNG_NO_ERROR_TEXT, to avoid - storing unneeded error/warning text. - Updated contrib/pngminim project to work with the new pnglibconf.h - Added some PNG_NO_* defines to contrib/pngminim/*/pngusr.h to save space. - -Version 1.5.0beta19 [April 24, 2010] - Added PNG_{READ,WRITE}_INT_FUNCTIONS_SUPPORTED. This allows the functions - to read and write ints to be disabled independently of PNG_USE_READ_MACROS, - which allows libpng to be built with the functions even though the default - is to use the macros - this allows applications to choose at app build - time whether or not to use macros (previously impossible because the - functions weren't in the default build.) - Changed Windows calling convention back to __cdecl for API functions. - For Windows/x86 platforms only: - __stdcall is no longer needed for Visual Basic, so libpng-1.5.0 uses - __cdecl throughout (both API functions and callbacks) on Windows/x86 - platforms. - Replaced visualc6 and visualc71 projects with new vstudio project - Relaxed the overly-restrictive permissions of some files. - -Version 1.5.0beta20 [April 24, 2010] - Relaxed more overly-restrictive permissions of some files. - -Version 1.5.0beta21 [April 27, 2010] - Removed some unwanted binary bytes and changed CRLF to NEWLINE in the new - vstudio project files, and some trivial editing of some files in the - scripts directory. - Set PNG_NO_READ_BGR, PNG_NO_IO_STATE, and PNG_NO_TIME_RFC1123 in - contrib/pngminim/decoder/pngusr.h to make a smaller decoder application. - -Version 1.5.0beta22 [April 28, 2010] - Fixed dependencies of GET_INT_32 - it does not require READ_INT_FUNCTIONS - because it has a macro equivalent. - Improved the options.awk script; added an "everything off" option. - Revised contrib/pngminim to use the "everything off" option in pngusr.dfa. - -Version 1.5.0beta23 [April 29, 2010] - Corrected PNG_REMOVED macro to take five arguments. - The macro was documented with two arguments (name,ordinal), however - the symbol checking .dfn files assumed five arguments. The five - argument form seems more useful so it is changed to that. - Corrected PNG_UNKNOWN_CHUNKS_SUPPORTED to PNG_HANDLE_AS_UNKNOWN_SUPPORTED - in gregbook/readpng2.c - Corrected protection of png_get_user_transform_ptr. The API declaration in - png.h is removed if both READ and WRITE USER_TRANSFORM are turned off - but was left defined in pngtrans.c - Added logunsupported=1 to cause pnglibconf.h to document disabled options. - This makes the installed pnglibconf.h more readable but causes no - other change. The intention is that users of libpng will find it - easier to understand if an API they need is missing. - Include png_reset_zstream() in png.c only when PNG_READ_SUPPORTED is defined. - Removed dummy_inflate.c from contrib/pngminim/encoder - Removed contrib/pngminim/*/gather.sh; gathering is now done in the makefile. - -Version 1.5.0beta24 [May 7, 2010] - Use bitwise "&" instead of arithmetic mod in pngrutil.c calculation of the - offset of the png_ptr->rowbuf pointer into png_ptr->big_row_buf. - Added more blank lines for readability. - -Version 1.5.0beta25 [June 18, 2010] - In pngpread.c: png_push_have_row() add check for new_row > height - Removed the now-redundant check for out-of-bounds new_row from example.c - -Version 1.5.0beta26 [June 18, 2010] - In pngpread.c: png_push_process_row() add check for too many rows. - -Version 1.5.0beta27 [June 18, 2010] - Removed the check added in beta25 as it is now redundant. - -Version 1.5.0beta28 [June 20, 2010] - Rewrote png_process_IDAT_data to consistently treat extra data as warnings - and handle end conditions more cleanly. - Removed the new (beta26) check in png_push_process_row(). - -Version 1.5.0beta29 [June 21, 2010] - Revised scripts/options.awk to work on Sunos (but still doesn't work) - Added comment to options.awk and contrib/pngminim/*/makefile to try nawk. - -Version 1.5.0beta30 [June 22, 2010] - Stop memory leak when reading a malformed sCAL chunk. - -Version 1.5.0beta31 [June 26, 2010] - Revised pngpread.c patch of beta28 to avoid an endless loop. - Removed some trailing blanks. - -Version 1.5.0beta32 [June 26, 2010] - Removed leftover scripts/options.patch and scripts/options.rej - -Version 1.5.0beta33 [July 6, 3010] - Made FIXED and FLOATING options consistent in the APIs they enable and - disable. Corrected scripts/options.awk to handle both command line - options and options specified in the .dfa files. - Changed char *msg to PNG_CONST char *msg in pngrutil.c - Make png_set_sRGB_gAMA_and_cHRM set values using either the fixed or - floating point APIs, but not both. - Reversed patch to remove error handler when the jmp_buf is stored in the - main program structure, not the png_struct. - The error handler is needed because the default handler in libpng will - always use the jmp_buf in the library control structure; this is never - set. The gregbook code is a useful example because, even though it - uses setjmp/longjmp, it shows how error handling can be implemented - using control mechanisms not directly supported by libpng. The - technique will work correctly with mechanisms such as Microsoft - Structure Exceptions or C++ exceptions (compiler willing - note that gcc - does not by default support interworking of C and C++ error handling.) - Reverted changes to call png_longjmp in contrib/gregbook where it is not - appropriate. If mainprog->jmpbuf is used by setjmp, then png_longjmp - cannot be used. - Changed "extern PNG_EXPORT" to "PNG_EXPORT" in png.h (Jan Nijtmans) - Changed "extern" to "PNG_EXTERN" in pngpriv.h (except for the 'extern "C" {') - -Version 1.5.0beta34 [July 12, 2010] - Put #ifndef PNG_EXTERN, #endif around the define PNG_EXTERN in pngpriv.h - -Version 1.5.0beta35 [July 24, 2010] - Removed some newly-added TAB characters. - Added -DNO_PNG_SNPRINTF to CFLAGS in scripts/makefile.dj2 - Moved the definition of png_snprintf() outside of the enclosing - #ifdef blocks in pngconf.h - -Version 1.5.0beta36 [July 29, 2010] - Patches by John Bowler: - Fixed point APIs are now supported throughout (no missing APIs). - Internal fixed point arithmetic support exists for all internal floating - point operations. - sCAL validates the floating point strings it is passed. - Safe, albeit rudimentary, Watcom support is provided by PNG_API_RULE==2 - Two new APIs exist to get the number of passes without turning on the - PNG_INTERLACE transform and to get the number of rows in the current - pass. - A new test program, pngvalid.c, validates the gamma code. - Errors in the 16-bit gamma correction (overflows) have been corrected. - cHRM chunk testing is done consistently (previously the floating point - API bypassed it, because the test really didn't work on FP, now the test - is performed on the actual values to be stored in the PNG file so it - works in the FP case too.) - Most floating point APIs now simply call the fixed point APIs after - converting the values to the fixed point form used in the PNG file. - The standard headers no longer include zlib.h, which is currently only - required for pngstruct.h and can therefore be internal. - Revised png_get_int_32 to undo the PNG two's complement representation of - negative numbers. - -Version 1.5.0beta37 [July 30, 2010] - Added a typecast in png_get_int_32() in png.h and pngrutil.h to avoid - a compiler warning. - Replaced oFFs 0,0 with oFFs -10,20 in pngtest.png - -Version 1.5.0beta38 [July 31, 2010] - Implemented remaining "_fixed" functions. - Corrected a number of recently introduced warnings mostly resulting from - safe but uncast assignments to shorter integers. Also added a zlib - VStudio release library project because the latest zlib Official Windows - build does not include such a thing. - Revised png_get_int_16() to be similar to png_get_int_32(). - Restored projects/visualc71. - -Version 1.5.0beta39 [August 2, 2010] - VisualC/GCC warning fixes, VisualC build fixes - The changes include support for function attributes in VC in addition to - those already present in GCC - necessary because without these some - warnings are unavoidable. Fixes include signed/unsigned fixes in - pngvalid and checks with gcc -Wall -Wextra -Wunused. - VC requires function attributes on function definitions as well as - declarations, PNG_FUNCTION has been added to enable this and the - relevant function definitions changed. - -Version 1.5.0beta40 [August 6, 2010] - Correct use of _WINDOWS_ in pngconf.h - Removed png_mem_ #defines; they are no longer used. - Added the sRGB chunk to pngtest.png - -Version 1.5.0beta41 [August 11, 2010] - Added the cHRM chunk to pngtest.png - Don't try to use version-script with cygwin/mingw. - Revised contrib/gregbook to work under cygwin/mingw. - -Version 1.5.0beta42 [August 18, 2010] - Add .dll.a to the list of extensions to be symlinked by Makefile.am (Yaakov) - Made all API functions that have const arguments and constant string - literal pointers declare them (John Bowler). - -Version 1.5.0beta43 [August 20, 2010] - Removed spurious tabs, shorten long lines (no source change) - Also added scripts/chkfmt to validate the format of all the files that can - reasonably be validated (it is suggested to run "make distclean" before - checking, because some machine generated files have long lines.) - Reformatted the CHANGES file to be more consistent throughout. - Made changes to address various issues identified by GCC, mostly - signed/unsigned and shortening problems on assignment but also a few - difficult to optimize (for GCC) loops. - Fixed non-GCC fixed point builds. In png.c a declaration was misplaced - in an earlier update. Fixed to declare the auto variables at the head. - Use cexcept.h in pngvalid.c. - -Version 1.5.0beta44 [August 24, 2010] - Updated CMakeLists.txt to use CMAKE_INSTALL_LIBDIR variable; useful for - installing libpng in /usr/lib64 (Funda Wang). - Revised CMakeLists.txt to put the man pages in share/man/man* not man/man* - Revised CMakeLists.txt to make symlinks instead of copies when installing. - Changed PNG_LIB_NAME from pngNN to libpngNN in CMakeLists.txt (Philip Lowman) - Implemented memory checks within pngvalid - Reformatted/rearranged pngvalid.c to assist use of progressive reader. - Check interlaced images in pngvalid - Clarified pngusr.h comments in pnglibconf.dfa - Simplified the pngvalid error-handling code now that cexcept.h is in place. - Implemented progressive reader in pngvalid.c for standard tests - Implemented progressive read in pngvalid.c gamma tests - Turn on progressive reader in pngvalid.c by default and tidy code. - -Version 1.5.0beta45 [August 26, 2010] - Added an explicit make step to projects/vstudio for pnglibconf.h - Also corrected zlib.vcxproj into which Visual Studio had introduced - what it calls an "authoring error". The change to make pnglibconf.h - simply copies the file; in the future it may actually generate the - file from scripts/pnglibconf.dfa as the other build systems do. - Changed pngvalid to work when floating point APIs are disabled - Renamed the prebuilt scripts/pnglibconf.h to scripts/pnglibconf.h.prebuilt - Supply default values for PNG_USER_PRIVATEBUILD and PNG_USER_DLLFNAME_POSTFIX - in pngpriv.h in case the user neglected to define them in their pngusr.h - -Version 1.5.0beta46 [August 28, 2010] - Added new private header files to libpng_sources in CMakeLists.txt - Added PNG_READ_16BIT, PNG_WRITE_16BIT, and PNG_16BIT options. - Added reference to scripts/pnglibconf.h.prebuilt in the visualc71 project. - -Version 1.5.0beta47 [September 11, 2010] - Fixed a number of problems with 64-bit compilation reported by Visual - Studio 2010 (John Bowler). - -Version 1.5.0beta48 [October 4, 2010] - Updated CMakeLists.txt (Philip Lowman). - Revised autogen.sh to recognize and use $AUTOCONF, $AUTOMAKE, $AUTOHEADER, - $AUTOPOINT, $ACLOCAL and $LIBTOOLIZE - Fixed problem with symbols creation in Makefile.am which was assuming that - all versions of ccp write to standard output by default (Martin Banky). The - bug was introduced in libpng-1.2.9beta5. - Removed unused mkinstalldirs. - -Version 1.5.0beta49 [October 8, 2010] - Undid Makefile.am revision of 1.5.0beta48. - -Version 1.5.0beta50 [October 14, 2010] - Revised Makefile.in to account for mkinstalldirs being removed. - Added some "(unsigned long)" typecasts in printf statements in pngvalid.c. - Suppressed a compiler warning in png_handle_sPLT(). - Check for out-of-range text compression mode in png_set_text(). - -Version 1.5.0beta51 [October 15, 2010] - Changed embedded dates to "(PENDING RELEASE) in beta releases (and future - rc releases) to minimize the difference between releases. - -Version 1.5.0beta52 [October 16, 2010] - Restored some of the embedded dates (in png.h, png.c, documentation, etc.) - -Version 1.5.0beta53 [October 18, 2010] - Updated INSTALL to mention using "make maintainer-clean" and to remove - obsolete statement about a custom ltmain.sh - Disabled "color-tests" by default in Makefile.am so it will work with - automake versions earlier than 1.11.1 - Use document name "libpng-manual.txt" instead of "libpng-.txt" - to simplify version differences. - Removed obsolete remarks about setjmp handling from INSTALL. - Revised and renamed the typedef in png.h and png.c that was designed - to catch library and header mismatch. - -Version 1.5.0beta54 [November 10, 2010] - Require 48 bytes, not 64 bytes, for big_row_buf in overflow checks. - Used a consistent structure for the pngget.c functions. - -Version 1.5.0beta55 [November 21, 2010] - Revised png_get_uint_32, png_get_int_32, png_get_uint_16 (Cosmin) - Moved reading of file signature into png_read_sig (Cosmin) - Fixed atomicity of chunk header serialization (Cosmin) - Added test for io_state in pngtest.c (Cosmin) - Added "#!/bin/sh" at the top of contrib/pngminim/*/gather.sh scripts. - Changes to remove gcc warnings (John Bowler) - Certain optional gcc warning flags resulted in warnings in libpng code. - With these changes only -Wconversion and -Wcast-qual cannot be turned on. - Changes are trivial rearrangements of code. -Wconversion is not possible - for pngrutil.c (because of the widespread use of += et al on variables - smaller than (int) or (unsigned int)) and -Wcast-qual is not possible - with pngwio.c and pngwutil.c because the 'write' callback and zlib - compression both fail to declare their input buffers with 'const'. - -Version 1.5.0beta56 [December 7, 2010] - Added the private PNG_UNUSED() macro definition in pngpriv.h. - Added some commentary about PNG_EXPORT in png.h and pngconf.h - Revised PNG_EXPORT() macro and added PNG_EXPORTA() macro, with the - objective of simplifying and improving the cosmetic appearance of png.h. - Fixed some incorrect "=" macro names in pnglibconf.dfa - Included documentation of changes in 1.5.0 from 1.4.x in libpng-manual.txt - -Version 1.5.0beta57 [December 9, 2010] - Documented the pngvalid gamma error summary with additional comments and - print statements. - Improved missing symbol handling in checksym.awk; symbols missing in both - the old and new files can now be optionally ignored, treated as errors - or warnings. - Removed references to pngvcrd.c and pnggccrd.c from the vstudio project. - Updated "libpng14" to "libpng15" in the visualc71 project. - Enabled the strip16 tests in pngvalid.` - Don't display test results (except PASS/FAIL) when running "make test". - Instead put them in pngtest-log.txt - Added "--with-zprefix=" to configure.ac - Updated the prebuilt configuration files to autoconf version 2.68 - -Version 1.5.0beta58 [December 19, 2010] - Fixed interlace image handling and add test cases (John Bowler) - Fixed the clean rule in Makefile.am to remove pngtest-log.txt - Made minor changes to work around warnings in gcc 3.4 - -Version 1.5.0rc01 [December 27, 2010] - No changes. - -Version 1.5.0rc02 [December 27, 2010] - Eliminated references to the scripts/*.def files in project/visualc71. - -Version 1.5.0rc03 [December 28, 2010] - Eliminated scripts/*.def and revised Makefile.am accordingly - -Version 1.5.0rc04 [December 29, 2010] - Fixed bug in background transformation handling in pngrtran.c (it was - looking for the flag in png_ptr->transformations instead of in - png_ptr->flags) (David Raymond). - -Version 1.5.0rc05 [December 31, 2010] - Fixed typo in a comment in CMakeLists.txt (libpng14 => libpng15) (Cosmin) - -Version 1.5.0rc06 [January 4, 2011] - Changed the new configure option "zprefix=string" to "zlib-prefix=string" - -Version 1.5.0rc07 [January 4, 2011] - Updated copyright year. - -Version 1.5.0 [January 6, 2011] - No changes. - -version 1.5.1beta01 [January 8, 2011] - Added description of png_set_crc_action() to the manual. - Added a note in the manual that the type of the iCCP profile was changed - from png_charpp to png_bytepp in png_get_iCCP(). This change happened - in version 1.5.0beta36 but is not noted in the CHANGES. Similarly, - it was changed from png_charpp to png_const_bytepp in png_set_iCCP(). - Ensure that png_rgb_to_gray ignores palette mapped images, if libpng - internally happens to call it with one, and fixed a failure to handle - palette mapped images correctly. This fixes CVE-2690. - -Version 1.5.1beta02 [January 14, 2011] - Fixed a bug in handling of interlaced images (bero at arklinux.org). - Updated CMakeLists.txt (Clifford Yapp) - -Version 1.5.1beta03 [January 14, 2011] - Fixed typecasting of some png_debug() statements (Cosmin) - -Version 1.5.1beta04 [January 16, 2011] - Updated documentation of png_set|get_tRNS() (Thomas Klausner). - Mentioned in the documentation that applications must #include "zlib.h" - if they need access to anything in zlib.h, and that a number of - macros such as png_memset() are no longer accessible by applications. - Corrected pngvalid gamma test "sample" function to access all of the color - samples of each pixel, instead of sampling the red channel three times. - Prefixed variable names index, div, exp, gamma with "png_" to avoid "shadow" - warnings, and (mistakenly) changed png_exp() to exp(). - -Version 1.5.1beta05 [January 16, 2011] - Changed variable names png_index, png_div, png_exp, and png_gamma to - char_index, divisor, exp_b10, and gamma_val, respectively, and - changed exp() back to png_exp(). - -Version 1.5.1beta06 [January 20, 2011] - Prevent png_push_crc_skip() from hanging while reading an unknown chunk - or an over-large compressed zTXt chunk with the progressive reader. - Eliminated more GCC "shadow" warnings. - Revised png_fixed() in png.c to avoid compiler warning about reaching the - end without returning anything. - -Version 1.5.1beta07 [January 22, 2011] - In the manual, describe the png_get_IHDR() arguments in the correct order. - Added const_png_structp and const_png_infop types, and used them in - prototypes for most png_get_*() functions. - -Version 1.5.1beta08 [January 23, 2011] - Added png_get_io_chunk_type() and deprecated png_get_io_chunk_name() - Added synopses for the IO_STATE functions and other missing synopses - to the manual. Removed the synopses from libpngpf.3 because they - were out of date and no longer useful. Better information can be - obtained by reading the prototypes and comments in pngpriv.h - Attempted to fix cpp on Solaris with S. Studio 12 cc, fix build - Added a make macro DFNCPP that is a CPP that will accept the tokens in - a .dfn file and adds configure stuff to test for such a CPP. ./configure - should fail if one is not available. - Corrected const_png_ in png.h to png_const_ to avoid polluting the namespace. - Added png_get_current_row_number and png_get_current_pass_number for the - benefit of the user transform callback. - Added png_process_data_pause and png_process_data_skip for the benefit of - progressive readers that need to stop data processing or want to optimize - skipping of unread data (e.g., if the reader marks a chunk to be skipped.) - -Version 1.5.1beta09 [January 24, 2011] - Enhanced pngvalid, corrected an error in gray_to_rgb, corrected doc error. - pngvalid contains tests of transforms, which tests are currently disabled - because they are incompletely tested. gray_to_rgb was failing to expand - the bit depth for smaller bit depth images; this seems to be a long - standing error and resulted, apparently, in invalid output - (CVE-2011-0408, CERT VU#643140). The documentation did not accurately - describe what libpng really does when converting RGB to gray. - -Version 1.5.1beta10 [January 27, 2010] - Fixed incorrect examples of callback prototypes in the manual, that were - introduced in libpng-1.0.0. - In addition the order of the png_get_uint macros with respect to the - relevant function definitions has been reversed. This helps the - preprocessing of the symbol files be more robust. Furthermore, the - symbol file preprocessing now uses -DPNG_NO_USE_READ_MACROS even when - the library may actually be built with PNG_USE_READ_MACROS; this stops - the read macros interfering with the symbol file format. - Made the manual, synopses, and function prototypes use the function - argument names file_gamma, int_file_gamma, and srgb_intent consistently. - -Version 1.5.1beta11 [January 28, 2011] - Changed PNG_UNUSED from "param=param;" to "{if(param){}}". - Corrected local variable type in new API png_process_data_skip() - The type was self-evidently incorrect but only causes problems on 64-bit - architectures. - Added transform tests to pngvalid and simplified the arguments. - -Version 1.5.1rc01 [January 29, 2011] - No changes. - -Version 1.5.1rc02 [January 31, 2011] - Added a request in the manual that applications do not use "png_" or - "PNG_" to begin any of their own symbols. - Changed PNG_UNUSED to "(void)param;" and updated the commentary in pngpriv.h - -Version 1.5.1 [February 3, 2011] - No changes. - -Version 1.5.2beta01 [February 13, 2011] - More -Wshadow fixes for older gcc compilers. Older gcc versions apparently - check formal parameters names in function declarations (as well as - definitions) to see if they match a name in the global namespace. - Revised PNG_EXPORTA macro to not use an empty parameter, to accommodate the - old VisualC++ preprocessor. - Turned on interlace handling in png_read_png(). - Fixed gcc pendantic warnings. - Handle longjmp in Cygwin. - Fixed png_get_current_row_number() in the interlaced case. - Cleaned up ALPHA flags and transformations. - Implemented expansion to 16 bits. - -Version 1.5.2beta02 [February 19, 2011] - Fixed mistake in the descriptions of user read_transform and write_transform - function prototypes in the manual. The row_info struct is png_row_infop. - Reverted png_get_current_row_number() to previous (1.5.2beta01) behavior. - Corrected png_get_current_row_number documentation - Fixed the read/write row callback documentation. - This documents the current behavior, where the callback is called after - every row with information pertaining to the next row. - -Version 1.5.2beta03 [March 3, 2011] - Fixed scripts/makefile.vcwin32 - Updated contrib/pngsuite/README to add the word "modify". - Define PNG_ALLOCATED to blank when _MSC_VER<1300. - -Version 1.5.2rc01 [March 19, 2011] - Define remaining attributes to blank when MSC_VER<1300. - ifdef out mask arrays in pngread.c when interlacing is not supported. - -Version 1.5.2rc02 [March 22, 2011] - Added a hint to try CPP=/bin/cpp if "cpp -E" fails in scripts/pnglibconf.mak - and in contrib/pngminim/*/makefile, eg., on SunOS 5.10, and removed "strip" - from the makefiles. - Fixed a bug (present since libpng-1.0.7) that makes png_handle_sPLT() fail - to compile when PNG_NO_POINTER_INDEXING is defined (Chubanov Kirill) - -Version 1.5.2rc03 [March 24, 2011] - Don't include standard header files in png.h while building the symbol table, - to avoid cpp failure on SunOS (introduced PNG_BUILDING_SYMBOL_TABLE macro). - -Version 1.5.2 [March 31, 2011] - No changes. - -Version 1.5.3beta01 [April 1, 2011] - Re-initialize the zlib compressor before compressing non-IDAT chunks. - Added API functions (png_set_text_compression_level() and four others) to - set parameters for zlib compression of non-IDAT chunks. - -Version 1.5.3beta02 [April 3, 2011] - Updated scripts/symbols.def with new API functions. - Only compile the new zlib re-initializing code when text or iCCP is - supported, using PNG_WRITE_COMPRESSED_TEXT_SUPPORTED macro. - Improved the optimization of the zlib CMF byte (see libpng-1.2.6beta03). - Optimize the zlib CMF byte in non-IDAT compressed chunks - -Version 1.5.3beta03 [April 16, 2011] - Fixed gcc -ansi -pedantic compile. A strict ANSI system does not have - snprintf, and the "__STRICT_ANSI__" detects that condition more reliably - than __STDC__ (John Bowler). - Removed the PNG_PTR_NORETURN attribute because it too dangerous. It tells - the compiler that a user supplied callback (the error handler) does not - return, yet there is no guarantee in practice that the application code - will correctly implement the error handler because the compiler only - issues a warning if there is a mistake (John Bowler). - Removed the no-longer-used PNG_DEPSTRUCT macro. - Updated the zlib version to 1.2.5 in the VStudio project. - Fixed 64-bit builds where png_uint_32 is smaller than png_size_t in - pngwutil.c (John Bowler). - Fixed bug with stripping the filler or alpha channel when writing, that - was introduced in libpng-1.5.2beta01 (bug report by Andrew Church). - -Version 1.5.3beta04 [April 27, 2011] - Updated pngtest.png with the new zlib CMF optimization. - Cleaned up conditional compilation code and of background/gamma handling - Internal changes only except a new option to avoid compiling the - png_build_grayscale_palette API (which is not used at all internally.) - The main change is to move the transform tests (READ_TRANSFORMS, - WRITE_TRANSFORMS) up one level to the caller of the APIs. This avoids - calls to spurious functions if all transforms are disabled and slightly - simplifies those functions. Pngvalid modified to handle this. - A minor change is to stop the strip_16 and expand_16 interfaces from - disabling each other; this allows the future alpha premultiplication - code to use 16-bit intermediate values while still producing 8-bit output. - png_do_background and png_do_gamma have been simplified to take a single - pointer to the png_struct rather than pointers to every item required - from the png_struct. This makes no practical difference to the internal - code. - A serious bug in the pngvalid internal routine 'standard_display_init' has - been fixed - this failed to initialize the red channel and accidentally - initialized the alpha channel twice. - Changed png_struct jmp_buf member name from png_jmpbuf to tmp_jmpbuf to - avoid a possible clash with the png_jmpbuf macro on some platforms. - -Version 1.5.3beta05 [May 6, 2011] - Added the "_POSIX_SOURCE" feature test macro to ensure libpng sees the - correct API. _POSIX_SOURCE is defined in pngpriv.h, pngtest.c and - pngvalid.c to ensure that POSIX conformant systems disable non-POSIX APIs. - Removed png_snprintf and added formatted warning messages. This change adds - internal APIs to allow png_warning messages to have parameters without - requiring the host OS to implement snprintf. As a side effect the - dependency of the tIME-supporting RFC1132 code on stdio is removed and - PNG_NO_WARNINGS does actually work now. - Pass "" instead of '\0' to png_default_error() in png_err(). This mistake - was introduced in libpng-1.2.20beta01. This fixes CVE-2011-2691. - Added PNG_WRITE_OPTIMIZE_CMF_SUPPORTED macro to make the zlib "CMF" byte - optimization configureable. - IDAT compression failed if preceded by a compressed text chunk (bug - introduced in libpng-1.5.3beta01-02). This was because the attempt to - reset the zlib stream in png_write_IDAT happened after the first IDAT - chunk had been deflated - much too late. In this change internal - functions were added to claim/release the z_stream and, hopefully, make - the code more robust. Also deflateEnd checking is added - previously - libpng would ignore an error at the end of the stream. - -Version 1.5.3beta06 [May 8, 2011] - Removed the -D_ALL_SOURCE from definitions for AIX in CMakeLists.txt - Implemented premultiplied alpha support: png_set_alpha_mode API - -Version 1.5.3beta07 [May 11, 2011] - Added expand_16 support to the high level interface. - Added named value and 'flag' gamma support to png_set_gamma. Made a minor - change from the previous (unreleased) ABI/API to hide the exact value used - for Macs - it's not a good idea to embed this in the ABI! - Moved macro definitions for PNG_HAVE_IHDR, PNG_HAVE_PLTE, and PNG_AFTER_IDAT - from pngpriv.h to png.h because they must be visible to applications - that call png_set_unknown_chunks(). - Check for up->location !PNG_AFTER_IDAT when writing unknown chunks - before IDAT. - -Version 1.5.3beta08 [May 16, 2011] - Improved "pngvalid --speed" to exclude more of pngvalid from the time. - Documented png_set_alpha_mode(), other changes in libpng.3/libpng-manual.txt - The cHRM chunk now sets the defaults for png_set_rgb_to_gray() (when negative - parameters are supplied by the caller), while in the absence of cHRM - sRGB/Rec 709 values are still used. This introduced a divide-by-zero - bug in png_handle_cHRM(). - The bKGD chunk no longer overwrites the background value set by - png_set_background(), allowing the latter to be used before the file - header is read. It never performed any useful function to override - the default anyway. - Added memory overwrite and palette image checks to pngvalid.c - Previously palette image code was poorly checked. Since the transformation - code has a special palette path in most cases this was a severe weakness. - Minor cleanup and some extra checking in pngrutil.c and pngrtran.c. When - expanding an indexed image, always expand to RGBA if transparency is - present. - -Version 1.5.3beta09 [May 17, 2011] - Reversed earlier 1.5.3 change of transformation order; move png_expand_16 - back where it was. The change doesn't work because it requires 16-bit - gamma tables when the code only generates 8-bit ones. This fails - silently; the libpng code just doesn't do any gamma correction. Moving - the tests back leaves the old, inaccurate, 8-bit gamma calculations, but - these are clearly better than none! - -Version 1.5.3beta10 [May 20, 2011] - - png_set_background() and png_expand_16() did not work together correctly. - This problem is present in 1.5.2; if png_set_background is called with - need_expand false and the matching 16 bit color libpng erroneously just - treats it as an 8-bit color because of where png_do_expand_16 is in the - transform list. This simple fix reduces the supplied colour to 8-bits, - so it gets smashed, but this is better than the current behavior. - Added tests for expand16, more fixes for palette image tests to pngvalid. - Corrects the code for palette image tests and disables attempts to - validate palette colors. - -Version 1.5.3rc01 [June 3, 2011] - No changes. - -Version 1.5.3rc02 [June 8, 2011] - Fixed uninitialized memory read in png_format_buffer() (Bug report by - Frank Busse, CVE-2011-2501, related to CVE-2004-0421). - -Version 1.5.3beta11 [June 11, 2011] - Fixed png_handle_sCAL which is broken in 1.5. This fixes CVE 2011-2692. - Added sCAL to pngtest.png - Revised documentation about png_set_user_limits() to say that it also affects - png writing. - Revised handling of png_set_user_limits() so that it can increase the - limit beyond the PNG_USER_WIDTH|HEIGHT_MAX; previously it could only - reduce it. - Make the 16-to-8 scaling accurate. Dividing by 256 with no rounding is - wrong (high by one) 25% of the time. Dividing by 257 with rounding is - wrong in 128 out of 65536 cases. Getting the right answer all the time - without division is easy. - Added "_SUPPORTED" to the PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION macro. - Added projects/owatcom, an IDE project for OpenWatcom to replace - scripts/makefile.watcom. This project works with OpenWatcom 1.9. The - IDE autogenerates appropriate makefiles (libpng.mk) for batch processing. - The project is configurable, unlike the Visual Studio project, so long - as the developer has an awk. - Changed png_set_gAMA to limit the gamma value range so that the inverse - of the stored value cannot overflow the fixed point representation, - and changed other things OpenWatcom warns about. - Revised pngvalid.c to test PNG_ALPHA_MODE_SUPPORTED correctly. This allows - pngvalid to build when ALPHA_MODE is not supported, which is required if - it is to build on libpng 1.4. - Removed string/memory macros that are no longer used and are not - necessarily fully supportable, particularly png_strncpy and png_snprintf. - Added log option to pngvalid.c and attempted to improve gamma messages. - -Version 1.5.3 [omitted] - People found the presence of a beta release following an rc release - to be confusing; therefore we bump the version to libpng-1.5.4beta01 - and there will be no libpng-1.5.3 release. - -Version 1.5.4beta01 [June 14, 2011] - Made it possible to undefine PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED - to get the same (inaccurate) output as libpng-1.5.2 and earlier. - Moved definitions of PNG_HAVE_IHDR, PNG_AFTER_IDAT, and PNG_HAVE_PLTE - outside of an unknown-chunk block in png.h because they are also - needed for other uses. - -Version 1.5.4beta02 [June 14, 2011] - Fixed and clarified LEGACY 16-to-8 scaling code. - Added png_set_chop_16() API, to match inaccurate results from previous - libpng versions. - Removed the ACCURATE and LEGACY options (they are no longer useable) - Use the old scaling method for background if png_set_chop_16() was - called. - Made png_set_chop_16() API removeable by disabling PNG_CHOP_16_TO_8_SUPPORTED - -Version 1.5.4beta03 [June 15, 2011] - Fixed a problem in png_do_expand_palette() exposed by optimization in - 1.5.3beta06 - Also removed a spurious and confusing "trans" member ("trans") from png_info. - The palette expand optimization prevented expansion to an intermediate RGBA - form if tRNS was present but alpha was marked to be stripped; this exposed - a check for tRNS in png_do_expand_palette() which is inconsistent with the - code elsewhere in libpng. - Correction to the expand_16 code; removed extra instance of - png_set_scale_16_to_8 from pngpriv.h - -Version 1.5.4beta04 [June 16, 2011] - Added a missing "#ifdef PNG_READ_BACKGROUND_SUPPORTED/#endif" in pngrtran.c - Added PNG_TRANSFORM_CHOP_16 to the high-level read transforms. - Made PNG_READ_16_TO_8_ACCURATE_SCALE configurable again. If this is - not enabled, png_set_strip_16() and png_do_scale_16_to_8() aren't built. - Revised contrib/visupng, gregbook, and pngminim to demonstrate chop_16_to_8 - -Version 1.5.4beta05 [June 16, 2011] - Renamed png_set_strip_16() to png_set_scale_16() and renamed - png_set_chop_16() to png_set_strip(16) in an attempt to minimize the - behavior changes between libpng14 and libpng15. - -Version 1.5.4beta06 [June 18, 2011] - Fixed new bug that was causing both strip_16 and scale_16 to be applied. - -Version 1.5.4beta07 [June 19, 2011] - Fixed pngvalid, simplified macros, added checking for 0 in sCAL. - The ACCURATE scale macro is no longer defined in 1.5 - call the - png_scale_16_to_8 API. Made sure that PNG_READ_16_TO_8 is still defined - if the png_strip_16_to_8 API is present. png_check_fp_number now - maintains some state so that positive, negative and zero values are - identified. sCAL uses these to be strictly spec conformant. - -Version 1.5.4beta08 [June 23, 2011] - Fixed pngvalid if ACCURATE_SCALE is defined. - Updated scripts/pnglibconf.h.prebuilt. - -Version 1.5.4rc01 [June 30, 2011] - Define PNG_ALLOCATED to "restrict" only if MSC_VER >= 1400. - -Version 1.5.4 [July 7, 2011] - No changes. - -Version 1.5.5beta01 [July 13, 2011] - Fixed some typos and made other minor changes in the manual. - Updated contrib/pngminus/makefile.std (Samuli Souminen) - -Version 1.5.5beta02 [July 14, 2011] - Revised Makefile.am and Makefile.in to look in the right directory for - pnglibconf.h.prebuilt - -Version 1.5.5beta03 [July 27, 2011] - Enabled compilation with g++ compiler. This compiler does not recognize - the file extension, so it always compiles with C++ rules. Made minor - changes to pngrutil.c to cast results where C++ expects it but C does not. - Minor editing of libpng.3 and libpng-manual.txt. - -Version 1.5.5beta04 [July 29, 2011] - Revised CMakeLists.txt (Clifford Yapp) - Updated commentary about the png_rgb_to_gray() default coefficients - in the manual and in pngrtran.c - -Version 1.5.5beta05 [August 17, 2011] - Prevent unexpected API exports from non-libpng DLLs on Windows. The "_DLL" - is removed from the test of whether a DLL is being built (this erroneously - caused the libpng APIs to be marked as DLL exports in static builds under - Microsoft Visual Studio). Almost all of the libpng building configuration - is moved from pngconf.h to pngpriv.h, but PNG_DLL_EXPORT remains in - pngconf.h, though, so that it is colocated with the import definition (it - is no longer used anywhere in the installed headers). The VStudio project - definitions have been cleaned up: "_USRDLL" has been removed from the - static library builds (this was incorrect), and PNG_USE_DLL has been added - to pngvalid to test the functionality (pngtest does not supply it, - deliberately). The spurious "_EXPORTS" has been removed from the - libpng build (all these errors were a result of copy/paste between project - configurations.) - Added new types and internal functions for CIE RGB end point handling to - pngpriv.h (functions yet to be implemented). - -Version 1.5.5beta06 [August 26, 2011] - Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set in CMakeLists.txt - (Clifford Yap) - Fixes to rgb_to_gray and cHRM XYZ APIs (John Bowler): - The rgb_to_gray code had errors when combined with gamma correction. - Some pixels were treated as true grey when they weren't and such pixels - and true grey ones were not gamma corrected (the original value of the - red component was used instead). APIs to get and set cHRM using color - space end points have been added and the rgb_to_gray code that defaults - based on cHRM, and the divide-by-zero bug in png_handle_cHRM (CERT - VU#477046, CVE-2011-3328, introduced in 1.5.4) have been corrected. - A considerable number of tests has been added to pngvalid for the - rgb_to_gray transform. - Arithmetic errors in rgb_to_gray whereby the calculated gray value was - truncated to the bit depth rather than rounded have been fixed except in - the 8-bit non-gamma-corrected case (where consistency seems more important - than correctness.) The code still has considerable inaccuracies in the - 8-bit case because 8-bit linear arithmetic is used. - -Version 1.5.5beta07 [September 7, 2011] - Added "$(ARCH)" option to makefile.darwin - Added SunOS support to configure.ac and Makefile.am - Changed png_chunk_benign_error() to png_warning() in png.c, in - png_XYZ_from_xy_checked(). - -Version 1.5.5beta08 [September 10, 2011] - Fixed 64-bit compilation errors (gcc). The errors fixed relate - to conditions where types that are 32 bits in the GCC 32-bit - world (uLong and png_size_t) become 64 bits in the 64-bit - world. This produces potential truncation errors which the - compiler correctly flags. - Relocated new HAVE_SOLARIS_LD definition in configure.ac - Constant changes for 64-bit compatibility (removal of L suffixes). The - 16-bit cases still use "L" as we don't have a 16-bit test system. - -Version 1.5.5rc01 [September 15, 2011] - Removed "L" suffixes in pngpriv.h - -Version 1.5.5 [September 22, 2011] - No changes. - -Version 1.5.6beta01 [September 22, 2011] - Fixed some 64-bit type conversion warnings in pngrtran.c - Moved row_info from png_struct to a local variable. - The various interlace mask arrays have been made into arrays of - bytes and made PNG_CONST and static (previously some arrays were - marked PNG_CONST and some weren't). - Additional checks have been added to the transform code to validate the - pixel depths after the transforms on both read and write. - Removed some redundant code from pngwrite.c, in png_destroy_write_struct(). - Changed chunk reading/writing code to use png_uint_32 instead of png_byte[4]. - This removes the need to allocate temporary strings for chunk names on - the stack in the read/write code. Unknown chunk handling still uses the - string form because this is exposed in the API. - -Version 1.5.6beta02 [September 26, 2011] - Added a note in the manual the png_read_update_info() must be called only - once with a particular info_ptr. - Fixed a typo in the definition of the new PNG_STRING_FROM_CHUNK(s,c) macro. - -Version 1.5.6beta03 [September 28, 2011] - Revised test-pngtest.sh to report FAIL when pngtest fails. - Added "--strict" option to pngtest, to report FAIL when the failure is - only because the resulting valid files are different. - Revised CMakeLists.txt to work with mingw and removed some material from - CMakeLists.txt that is no longer useful in libpng-1.5. - -Version 1.5.6beta04 [October 5, 2011] - Fixed typo in Makefile.in and Makefile.am ("-M Wl" should be "-M -Wl")." - -Version 1.5.6beta05 [October 12, 2011] - Speed up png_combine_row() for interlaced images. This reduces the generality - of the code, allowing it to be optimized for Adam7 interlace. The masks - passed to png_combine_row() are now generated internally, avoiding - some code duplication and localizing the interlace handling somewhat. - Align png_struct::row_buf - previously it was always unaligned, caused by - a bug in the code that attempted to align it; the code needs to subtract - one from the pointer to take account of the filter byte prepended to - each row. - Optimized png_combine_row() when rows are aligned. This gains a small - percentage for 16-bit and 32-bit pixels in the typical case where the - output row buffers are appropriately aligned. The optimization was not - previously possible because the png_struct buffer was always misaligned. - Fixed bug in png_write_chunk_header() debug print, introduced in 1.5.6beta01. - -Version 1.5.6beta06 [October 17, 2011] - Removed two redundant tests for unitialized row. - Fixed a relatively harmless memory overwrite in compressed text writing - with a 1 byte zlib buffer. - Add ability to call png_read_update_info multiple times to pngvalid.c. - Fixes for multiple calls to png_read_update_info. These fixes attend to - most of the errors revealed in pngvalid, however doing the gamma work - twice results in inaccuracies that can't be easily fixed. There is now - a warning in the code if this is going to happen. - Turned on multiple png_read_update_info in pngvalid transform tests. - Prevent libpng from overwriting unused bits at the end of the image when - it is not byte aligned, while reading. Prior to libpng-1.5.6 libpng would - overwrite the partial byte at the end of each row if the row width was not - an exact multiple of 8 bits and the image is not interlaced. - -Version 1.5.6beta07 [October 21, 2011] - Made png_ptr->prev_row an aligned pointer into png_ptr->big_prev_row - (Mans Rullgard). - -Version 1.5.6rc01 [October 26, 2011] - Changed misleading "Missing PLTE before cHRM" warning to "Out of place cHRM" - -Version 1.5.6rc02 [October 27, 2011] - Added LSR() macro to defend against buggy compilers that evaluate non-taken - code branches and complain about out-of-range shifts. - -Version 1.5.6rc03 [October 28, 2011] - Renamed the LSR() macro to PNG_LSR() and added PNG_LSL() macro. - Fixed compiler warnings with Intel and MSYS compilers. The logical shift - fix for Microsoft Visual C is required by other compilers, so this - enables that fix for all compilers when using compile-time constants. - Under MSYS 'byte' is a name declared in a system header file, so we - changed the name of a local variable to avoid the warnings that result. - Added #define PNG_ALIGN_TYPE PNG_ALIGN_NONE to contrib/pngminim/*/pngusr.h - -Version 1.5.6 [November 3, 2011] - No changes. - -Version 1.5.7beta01 [November 4, 2011] - Added support for ARM processor, when decoding all PNG up-filtered rows - and any other-filtered rows with 3 or 4 bytes per pixel (Mans Rullgard). - Fixed bug in pngvalid on early allocation failure; fixed type cast in - pngmem.c; pngvalid would attempt to call png_error() if the allocation - of a png_struct or png_info failed. This would probably have led to a - crash. The pngmem.c implementation of png_malloc() included a cast - to png_size_t which would fail on large allocations on 16-bit systems. - Fix for the preprocessor of the Intel C compiler. The preprocessor - splits adjacent @ signs with a space; this changes the concatentation - token from @-@-@ to PNG_JOIN; that should work with all compiler - preprocessors. - Paeth filter speed improvements from work by Siarhei Siamashka. This - changes the 'Paeth' reconstruction function to improve the GCC code - generation on x86. The changes are only part of the suggested ones; - just the changes that definitely improve speed and remain simple. - The changes also slightly increase the clarity of the code. - -Version 1.5.7beta02 [November 11, 2011] - Check compression_type parameter in png_get_iCCP and remove spurious - casts. The compression_type parameter is always assigned to, so must - be non-NULL. The cast of the profile length potentially truncated the - value unnecessarily on a 16-bit int system, so the cast of the (byte) - compression type to (int) is specified by ANSI-C anyway. - Fixed FP division by zero in pngvalid.c; the 'test_pixel' code left - the sBIT fields in the test pixel as 0, which resulted in a floating - point division by zero which was irrelevant but causes systems where - FP exceptions cause a crash. Added code to pngvalid to turn on FP - exceptions if the appropriate glibc support is there to ensure this is - tested in the future. - Updated scripts/pnglibconf.mak and scripts/makefile.std to handle the - new PNG_JOIN macro. - Added versioning to pnglibconf.h comments. - Simplified read/write API initial version; basic read/write tested on - a variety of images, limited documentation (in the header file.) - Installed more accurate linear to sRGB conversion tables. The slightly - modified tables reduce the number of 16-bit values that - convert to an off-by-one 8-bit value. The "makesRGB.c" code that was used - to generate the tables is now in a contrib/sRGBtables sub-directory. - -Version 1.5.7beta03 [November 17, 2011] - Removed PNG_CONST from the sRGB table declarations in pngpriv.h and png.c - Added run-time detection of NEON support. - Added contrib/libtests; includes simplified API test and timing test and - a color conversion utility for rapid checking of failed 'pngstest' results. - Multiple transform bug fixes plus a work-round for double gamma correction. - libpng does not support more than one transform that requires linear data - at once - if this is tried typically the results is double gamma - correction. Since the simplified APIs can need rgb to gray combined with - a compose operation it is necessary to do one of these outside the main - libpng transform code. This check-in also contains fixes to various bugs - in the simplified APIs themselves and to some bugs in compose and rgb to - gray (on palette) itself. - Fixes for C++ compilation using g++ When libpng source is compiled - using g++. The compiler imposes C++ rules on the C source; thus it - is desireable to make the source work with either C or C++ rules - without throwing away useful error information. This change adds - png_voidcast to allow C semantic (void*) cases or the corresponding - C++ static_cast operation, as appropriate. - Added --noexecstack to assembler file compilation. GCC does not set - this on assembler compilation, even though it does on C compilation. - This creates security issues if assembler code is enabled; the - work-around is to set it by default in the flags for $(CCAS) - Work around compilers that don't support declaration of const data. Some - compilers fault 'extern const' data declarations (because the data is - not initialized); this turns on const-ness only for compilers where - this is known to work. - -Version 1.5.7beta04 [November 17, 2011] - Since the gcc driver does not recognize the --noexecstack flag, we must - use the -Wa prefix to have it passed through to the assembler. - Also removed a duplicate setting of this flag. - Added files that were omitted from the libpng-1.5.7beta03 zip distribution. - -Version 1.5.7beta05 [November 25, 2011] - Removed "zTXt" from warning in generic chunk decompression function. - Validate time settings passed to png_set_tIME() and png_convert_to_rfc1123() - (Frank Busse). Note: This prevented CVE-2015-7981 from affecting - libpng-1.5.7 and later. - Added MINGW support to CMakeLists.txt - Reject invalid compression flag or method when reading the iTXt chunk. - Backed out 'simplified' API changes. The API seems too complex and there - is a lack of consensus or enthusiasm for the proposals. The API also - reveals significant bugs inside libpng (double gamma correction and the - known bug of being unable to retrieve a corrected palette). It seems - better to wait until the bugs, at least, are corrected. - Moved pngvalid.c into contrib/libtests - Rebuilt Makefile.in, configure, etc., with autoconf-2.68 - -Version 1.5.7rc01 [December 1, 2011] - Replaced an "#if" with "#ifdef" in pngrtran.c - Revised #if PNG_DO_BC block in png.c (use #ifdef and add #else) - -Version 1.5.7rc02 [December 5, 2011] - Revised project files and contrib/pngvalid/pngvalid.c to account for - the relocation of pngvalid into contrib/libtests. - Revised pngconf.h to use " __declspec(restrict)" only when MSC_VER >= 1400, - as in libpng-1.5.4. - Put CRLF line endings in the owatcom project files. - -Version 1.5.7rc03 [December 7, 2011] - Updated CMakeLists.txt to account for the relocation of pngvalid.c - -Version 1.5.7 [December 15, 2011] - Minor fixes to pngvalid.c for gcc 4.6.2 compatibility to remove warnings - reported by earlier versions. - Fixed minor memset/sizeof errors in pngvalid.c. - -Version 1.6.0beta01 [December 15, 2011] - Removed machine-generated configure files from the GIT repository (they will - continue to appear in the tarball distributions and in the libpng15 and - earlier GIT branches). - Restored the new 'simplified' API, which was started in libpng-1.5.7beta02 - but later deleted from libpng-1.5.7beta05. - Added example programs for the new 'simplified' API. - Added ANSI-C (C90) headers and require them, and take advantage of the - change. Also fixed some of the projects/* and contrib/* files that needed - updates for libpng16 and the move of pngvalid.c. - With this change the required ANSI-C header files are assumed to exist: the - implementation must provide float.h, limits.h, stdarg.h and stddef.h and - libpng relies on limits.h and stddef.h existing and behaving as defined - (the other two required headers aren't used). Non-ANSI systems that don't - have stddef.h or limits.h will have to provide an appropriate fake - containing the relevant types and #defines. - Dropped support for 16-bit platforms. The use of FAR/far has been eliminated - and the definition of png_alloc_size_t is now controlled by a flag so - that 'small size_t' systems can select it if necessary. Libpng 1.6 may - not currently work on such systems -- it seems likely that it will - ask 'malloc' for more than 65535 bytes with any image that has a - sufficiently large row size (rather than simply failing to read such - images). - New tools directory containing tools used to generate libpng code. - Fixed race conditions in parallel make builds. With higher degrees of - parallelism during 'make' the use of the same temporary file names such - as 'dfn*' can result in a race where a temporary file from one arm of the - build is deleted or overwritten in another arm. This changes the - temporary files for suffix rules to always use $* and ensures that the - non-suffix rules use unique file names. - -Version 1.6.0beta02 [December 21, 2011] - Correct configure builds where build and source directories are separate. - The include path of 'config.h' was erroneously made relative in pngvalid.c - in libpng 1.5.7. - -Version 1.6.0beta03 [December 22, 2011] - Start-up code size improvements, error handler flexibility. These changes - alter how the tricky allocation of the initial png_struct and png_info - structures are handled. png_info is now handled in pretty much the same - way as everything else, except that the allocations handle NULL return - silently. png_struct is changed in a similar way on allocation and on - deallocation a 'safety' error handler is put in place (which should never - be required). The error handler itself is changed to permit mismatches - in the application and libpng error buffer size; however, this means a - silent change to the API to return the jmp_buf if the size doesn't match - the size from the libpng compilation; libpng now allocates the memory and - this may fail. Overall these changes result in slight code size - reductions; however, this is a reduction in code that is always executed - so is particularly valuable. Overall on a 64-bit system the libpng DLL - decreases in code size by 1733 bytes. pngerror.o increases in size by - about 465 bytes because of the new functionality. - Added png_convert_to_rfc1123_buffer() and deprecated png_convert_to_rfc1123() - to avoid including a spurious buffer in the png_struct. - -Version 1.6.0beta04 [December 30, 2011] - Regenerated configure scripts with automake-1.11.2 - Eliminated png_info_destroy(). It is now used only in png.c and only calls - one other internal function and memset(). - Enabled png_get_sCAL_fixed() if floating point APIs are enabled. Previously - it was disabled whenever internal fixed point arithmetic was selected, - which meant it didn't exist even on systems where FP was available but not - preferred. - Added pngvalid.c compile time checks for const APIs. - Implemented 'restrict' for png_info and png_struct. Because of the way - libpng works both png_info and png_struct are always accessed via a - single pointer. This means adding C99 'restrict' to the pointer gives - the compiler some opportunity to optimize the code. This change allows - that. - Moved AC_MSG_CHECKING([if libraries can be versioned]) later to the proper - location in configure.ac (Gilles Espinasse). - Changed png_memcpy to C assignment where appropriate. Changed all those - uses of png_memcpy that were doing a simple assignment to assignments - (all those cases where the thing being copied is a non-array C L-value). - Added some error checking to png_set_*() routines. - Removed the reference to the non-exported function png_memcpy() from - example.c. - Fixed the Visual C 64-bit build - it requires jmp_buf to be aligned, but - it had become misaligned. - Revised contrib/pngminus/pnm2png.c to avoid warnings when png_uint_32 - and unsigned long are of different sizes. - -Version 1.6.0beta05 [January 15, 2012] - Updated manual with description of the simplified API (copied from png.h) - Fix bug in pngerror.c: some long warnings were being improperly truncated - (CVE-2011-3464, bug introduced in libpng-1.5.3beta05). - -Version 1.6.0beta06 [January 24, 2012] - Added palette support to the simplified APIs. This commit - changes some of the macro definitions in png.h, app code - may need corresponding changes. - Increased the formatted warning buffer to 192 bytes. - Added color-map support to simplified API. This is an initial version for - review; the documentation has not yet been updated. - Fixed Min/GW uninstall to remove libpng.dll.a - -Version 1.6.0beta07 [January 28, 2012] - Eliminated Intel icc/icl compiler warnings. The Intel (GCC derived) - compiler issues slightly different warnings from those issued by the - current vesions of GCC. This eliminates those warnings by - adding/removing casts and small code rewrites. - Updated configure.ac from autoupdate: added --enable-werror option. - Also some layout regularization and removal of introduced tab characters - (replaced with 3-character indentation). Obsolete macros identified by - autoupdate have been removed; the replacements are all in 2.59 so - the pre-req hasn't been changed. --enable-werror checks for support - for -Werror (or the given argument) in the compiler. This mimics the - gcc configure option by allowing -Werror to be turned on safely; without - the option the tests written in configure itself fail compilation because - they cause compiler warnings. - Rewrote autogen.sh to run autoreconf instead of running tools one-by-one. - Conditionalize the install rules for MINGW and CYGWIN in CMakeLists.txt and - set CMAKE_LIBRARY_OUTPUT_DIRECTORY to "lib" on all platforms (C. Yapp). - Freeze libtool files in the 'scripts' directory. This version of autogen.sh - attempts to dissuade people from running it when it is not, or should not, - be necessary. In fact, autogen.sh does not work when run in a libpng - directory extracted from a tar distribution anymore. You must run it in - a GIT clone instead. - Added two images to contrib/pngsuite (1-bit and 2-bit transparent grayscale), - and renamed three whose names were inconsistent with those in - pngsuite/README.txt. - -Version 1.6.0beta08 [February 1, 2012] - Fixed Image::colormap misalignment in pngstest.c - Check libtool/libtoolize version number (2.4.2) in configure.ac - Divide test-pngstest.sh into separate pngstest runs for basic and - transparent images. - Moved automake options to AM_INIT_AUTOMAKE in configure.ac - Added color-tests, silent-rules (Not yet implemented in Makefile.am) and - version checking to configure.ac - Improved pngstest speed by not doing redundant tests and add const to - the background parameter of png_image_finish_read. The --background - option is now done automagically only when required, so that commandline - option no longer exists. - Cleaned up pngpriv.h to consistently declare all functions and data. - Also eliminated PNG_CONST_DATA, which is apparently not needed but we - can't be sure until it is gone. - Added symbol prefixing that allows all the libpng external symbols - to be prefixed (suggested by Reuben Hawkins). - Updated "ftbb*.png" list in the owatcom and vstudio projects. - Fixed 'prefix' builds on clean systems. The generation of pngprefix.h - should not require itself. - Updated INSTALL to explain that autogen.sh must be run in a GIT clone, - not in a libpng directory extracted from a tar distribution. - -Version 1.6.0beta09 [February 1, 2012] - Reverted the prebuilt configure files to libpng-1.6.0beta05 condition. - -Version 1.6.0beta10 [February 3, 2012] - Added Z_SOLO for zlib-1.2.6+ and correct pngstest tests - Updated list of test images in CMakeLists.txt - Updated the prebuilt configure files to current condition. - Revised INSTALL information about autogen.sh; it works in tar distributions. - -Version 1.6.0beta11 [February 16, 2012] - Fix character count in pngstest command in projects/owatcom/pngstest.tgt - Revised test-pngstest.sh to report PASS/FAIL for each image. - Updated documentation about the simplified API. - Corrected estimate of error in libpng png_set_rgb_to_gray API. The API is - extremely inaccurate for sRGB conversions because it uses an 8-bit - intermediate linear value and it does not use the sRGB transform, so it - suffers from the known instability in gamma transforms for values close - to 0 (see Poynton). The net result is that the calculation has a maximum - error of 14.99/255; 0.5/255^(1/2.2). pngstest now uses 15 for the - permitted 8-bit error. This may still not be enough because of arithmetic - error. - Removed some unused arrays (with #ifdef) from png_read_push_finish_row(). - Fixed a memory overwrite bug in simplified read of RGB PNG with - non-linear gamma Also bugs in the error checking in pngread.c and changed - quite a lot of the checks in pngstest.c to be correct; either correctly - written or not over-optimistic. The pngstest changes are insufficient to - allow all possible RGB transforms to be passed; pngstest cmppixel needs - to be rewritten to make it clearer which errors it allows and then changed - to permit known inaccuracies. - Removed tests for no-longer-used *_EMPTY_PLTE_SUPPORTED from pngstruct.h - Fixed fixed/float API export conditionals. 1) If FIXED_POINT or - FLOATING_POINT options were switched off, png.h ended up with lone ';' - characters. This is not valid ANSI-C outside a function. The ';' - characters have been moved inside the definition of PNG_FP_EXPORT and - PNG_FIXED_EXPORT. 2) If either option was switched off, the declaration - of the corresponding functions were completely omitted, even though some - of them are still used internally. The result is still valid, but - produces warnings from gcc with some warning options (including -Wall). The - fix is to cause png.h to declare the functions with PNG_INTERNAL_FUNCTION - when png.h is included from pngpriv.h. - Check for invalid palette index while reading paletted PNG. When one is - found, issue a warning and increase png_ptr->num_palette accordingly. - Apps are responsible for checking to see if that happened. - -Version 1.6.0beta12 [February 18, 2012] - Do not increase num_palette on invalid_index. - Relocated check for invalid palette index to pngrtran.c, after unpacking - the sub-8-bit pixels. - Fixed CVE-2011-3026 buffer overrun bug. This bug was introduced when - iCCP chunk support was added at libpng-1.0.6. Deal more correctly with the - test on iCCP chunk length. Also removed spurious casts that may hide - problems on 16-bit systems. - -Version 1.6.0beta13 [February 24, 2012] - Eliminated redundant png_push_read_tEXt|zTXt|iTXt|unknown code from - pngpread.c and use the sequential png_handle_tEXt, etc., in pngrutil.c; - now that png_ptr->buffer is inaccessible to applications, the special - handling is no longer useful. - Added PNG_SAFE_LIMITS feature to pnglibconf.dfa, pngpriv.h, and new - pngusr.dfa to reset the user limits to safe ones if PNG_SAFE_LIMITS is - defined. To enable, use "CPPFLAGS=-DPNG_SAFE_LIMITS_SUPPORTED=1" on the - configure command or put #define PNG_SAFE_LIMITS_SUPPORTED in - pnglibconf.h.prebuilt and pnglibconf.h. - -Version 1.6.0beta14 [February 27, 2012] - Added information about the new limits in the manual. - Updated Makefile.in - -Version 1.6.0beta15 [March 2, 2012] - Removed unused "current_text" members of png_struct and the png_free() - of png_ptr->current_text from pngread.c - Rewrote pngstest.c for substantial speed improvement. - Fixed transparent pixel and 16-bit rgb tests in pngstest and removed a - spurious check in pngwrite.c - Added PNG_IMAGE_FLAG_FAST for the benefit of applications that store - intermediate files, or intermediate in-memory data, while processing - image data with the simplified API. The option makes the files larger - but faster to write and read. pngstest now uses this by default; this - can be disabled with the --slow option. - Improved pngstest fine tuning of error numbers, new test file generator. - The generator generates images that test the full range of sample values, - allow the error numbers in pngstest to be tuned and checked. makepng - also allows generation of images with extra chunks, although this is - still work-in-progress. - Added check for invalid palette index while reading. - Fixed some bugs in ICC profile writing. The code should now accept - all potentially valid ICC profiles and reject obviously invalid ones. - It now uses png_error() to do so rather than casually writing a PNG - without the necessary color data. - Removed whitespace from the end of lines in all source files and scripts. - -Version 1.6.0beta16 [March 6, 2012] - Relocated palette-index checking function from pngrutil.c to pngtrans.c - Added palette-index checking while writing. - Changed png_inflate() and calling routines to avoid overflow problems. - This is an intermediate check-in that solves the immediate problems and - introduces one performance improvement (avoiding a copy via png_ptr->zbuf.) - Further changes will be made to make ICC profile handling more secure. - Fixed build warnings (MSVC, GCC, GCC v3). Cygwin GCC with default options - declares 'index' as a global, causing a warning if it is used as a local - variable. GCC 64-bit warns about assigning a (size_t) (unsigned 64-bit) - to an (int) (signed 32-bit). MSVC, however, warns about using the - unary '-' operator on an unsigned value (even though it is well defined - by ANSI-C to be ~x+1). The padding calculation was changed to use a - different method. Removed the tests on png_ptr->pass. - Added contrib/libtests/tarith.c to test internal arithmetic functions from - png.c. This is a libpng maintainer program used to validate changes to the - internal arithmetic functions. - Made read 'inflate' handling like write 'deflate' handling. The read - code now claims and releases png_ptr->zstream, like the write code. - The bug whereby the progressive reader failed to release the zstream - is now fixed, all initialization is delayed, and the code checks for - changed parameters on deflate rather than always calling - deflatedEnd/deflateInit. - Validate the zTXt strings in pngvalid. - Added code to validate the windowBits value passed to deflateInit2(). - If the call to deflateInit2() is wrong a png_warning will be issued - (in fact this is harmless, but the PNG data produced may be sub-optimal). - -Version 1.6.0beta17 [March 10, 2012] - Fixed PNG_LIBPNG_BUILD_BASE_TYPE definition. - Reject all iCCP chunks after the first, even if the first one is invalid. - Deflate/inflate was reworked to move common zlib calls into single - functions [rw]util.c. A new shared keyword check routine was also added - and the 'zbuf' is no longer allocated on progressive read. It is now - possible to call png_inflate() incrementally. A warning is no longer - issued if the language tag or translated keyword in the iTXt chunk - has zero length. - If benign errors are disabled use maximum window on ancilliary inflate. - This works round a bug introduced in 1.5.4 where compressed ancillary - chunks could end up with a too-small windowBits value in the deflate - header. - -Version 1.6.0beta18 [March 16, 2012] - Issue a png_benign_error() instead of png_warning() about bad palette index. - In pngtest, treat benign errors as errors if "-strict" is present. - Fixed an off-by-one error in the palette index checking function. - Fixed a compiler warning under Cygwin (Windows-7, 32-bit system) - Revised example.c to put text strings in a temporary character array - instead of directly assigning string constants to png_textp members. - This avoids compiler warnings when -Wwrite-strings is enabled. - Added output flushing to aid debugging under Visual Studio. Unfortunately - this is necessary because the VS2010 output window otherwise simply loses - the error messages on error (they weren't flushed to the window before - the process exited, apparently!) - Added configuration support for benign errors and changed the read - default. Also changed some warnings in the iCCP and sRGB handling - from to benign errors. Configuration now makes read benign - errors warnings and write benign errors to errors by default (thus - changing the behavior on read). The simplified API always forces - read benign errors to warnings (regardless of the system default, unless - this is disabled in which case the simplified API can't be built.) - -Version 1.6.0beta19 [March 18, 2012] - Work around for duplicate row start calls; added warning messages. - This turns on PNG_FLAG_DETECT_UNINITIALIZED to detect app code that - fails to call one of the 'start' routines (not enabled in libpng-1.5 - because it is technically an API change, since it did normally work - before.) It also makes duplicate calls to png_read_start_row (an - internal function called at the start of the image read) benign, as - they were before changes to use png_inflate_claim. Somehow webkit is - causing this to happen; this is probably a mis-feature in the zlib - changes so this commit is only a work-round. - Removed erroneous setting of DETECT_UNINITIALIZED and added more - checks. The code now does a png_error if an attempt is made to do the - row initialization twice; this is an application error and it has - serious consequences because the transform data in png_struct is - changed by each call. - Added application error reporting and added chunk names to read - benign errors; also added --strict to pngstest - not enabled - yet because a warning is produced. - Avoid the double gamma correction warning in the simplified API. - This allows the --strict option to pass in the pngstest checks - -Version 1.6.0beta20 [March 29, 2012] - Changed chunk handler warnings into benign errors, incrementally load iCCP - Added checksum-icc.c to contrib/tools - Prevent PNG_EXPAND+PNG_SHIFT doing the shift twice. - Recognize known sRGB ICC profiles while reading; prefer writing the - iCCP profile over writing the sRGB chunk, controlled by the - PNG_sRGB_PROFILE_CHECKS option. - Revised png_set_text_2() to avoid potential memory corruption (fixes - CVE-2011-3048, also known as CVE-2012-3425). - -Version 1.6.0beta21 [April 27, 2012] - Revised scripts/makefile.darwin: use system zlib; remove quotes around - architecture list; add missing ppc architecture; add architecture options - to shared library link; don't try to create a shared lib based on missing - RELEASE variable. - Enable png_set_check_for_invalid_index() for both read and write. - Removed #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED in pngpriv.h around - declaration of png_handle_unknown(). - Added -lssp_nonshared in a comment in scripts/makefile.freebsd - and changed deprecated NOOBJ and NOPROFILE to NO_OBJ and NO_PROFILE. - -Version 1.6.0beta22 [May 23, 2012] - Removed need for -Wno-cast-align with clang. clang correctly warns on - alignment increasing pointer casts when -Wcast-align is passed. This - fixes the cases that clang warns about either by eliminating the - casts from png_bytep to png_uint_16p (pngread.c), or, for pngrutil.c - where the cast is previously verified or pngstest.c where it is OK, by - introducing new png_aligncast macros to do the cast in a way that clang - accepts. - -Version 1.6.0beta23 [June 6, 2012] - Revised CMakeLists.txt to not attempt to make a symlink under mingw. - Made fixes for new optimization warnings from gcc 4.7.0. The compiler - performs an optimization which is safe; however it then warns about it. - Changing the type of 'palette_number' in pngvalid.c removes the warning. - Do not depend upon a GCC feature macro being available for use in generating - the linker mapfile symbol prefix. - Improved performance of new do_check_palette_indexes() function (only - update the value when it actually increases, move test for whether - the check is wanted out of the function. - -Version 1.6.0beta24 [June 7, 2012] - Don't check palette indexes if num_palette is 0 (as it can be in MNG files). - -Version 1.6.0beta25 [June 16, 2012] - Revised png_set_keep_unknown_chunks() so num_chunks < 0 means ignore all - unknown chunks and all known chunks except for IHDR, PLTE, tRNS, IDAT, - and IEND. Previously it only meant ignore all unknown chunks, the - same as num_chunks == 0. Revised png_image_skip_unused_chunks() to - provide a list of chunks to be processed instead of a list of chunks to - ignore. Revised contrib/gregbook/readpng2.c accordingly. - -Version 1.6.0beta26 [July 10, 2012] - Removed scripts/makefile.cegcc from the *.zip and *.7z distributions; it - depends on configure, which is not included in those archives. - Moved scripts/chkfmt to contrib/tools. - Changed "a+w" to "u+w" in Makefile.in to fix CVE-2012-3386. - -Version 1.6.0beta27 [August 11, 2012] - Do not compile PNG_DEPRECATED, PNG_ALLOC and PNG_PRIVATE when __GNUC__ < 3. - Do not use __restrict when GNUC is <= 3.1 - Removed references to png_zalloc() and png_zfree() from the manual. - Fixed configurations where floating point is completely disabled. Because - of the changes to support symbol prefixing PNG_INTERNAL_FUNCTION declares - floating point APIs during libpng builds even if they are completely - disabled. This requires the png floating point types (png_double*) to be - declared even though the functions are never actually defined. This - change provides a dummy definition so that the declarations work, yet any - implementation will fail to compile because of an incomplete type. - Re-eliminated the use of strcpy() in pngtest.c. An unncessary use of - strcpy() was accidentally re-introduced in libpng16; this change replaces - it with strncpy(). - Eliminated use of png_sizeof(); use sizeof() instead. - Use a consistent style for (sizeof type) and (sizeof (array)) - Cleanup of png_set_filler(). This function does very different things on - read and write. In libpng 1.6 the two cases can be distinguished and - considerable code cleanup, and extra error checking, is possible. This - makes calls on the write side that have no effect be ignored with a - png_app_error(), which can be disabled in the app using - png_set_benign_errors(), and removes the spurious use of usr_channels - on the read side. - Insist on autotools 1.12.1 for git builds because there are security issues - with 1.12 and insisting on anything less would allow 1.12 to be used. - Removed info_ptr->signature[8] from WRITE-only builds. - Add some conditions for compiling png_fixed(). This is a small function - but it requires "-lm" on some platforms. - Cause pngtest --strict to fail on any warning from libpng (not just errors) - and cause it not to fail at the comparison step if libpng lacks support - for writing chunks that it reads from the input (currently only implemented - for compressed text chunks). - Make all three "make check" test programs work without READ or WRITE support. - Now "make check" will succeed even if libpng is compiled with -DPNG_NO_READ - or -DPNG_NO_WRITE. The tests performed are reduced, but the basic reading - and writing of a PNG file is always tested by one or more of the tests. - Consistently use strlen(), memset(), memcpy(), and memcmp() instead of the - png_strlen(), png_memset(), png_memcpy(), and png_memcmp() macros. - Removed the png_sizeof(), png_strlen(), png_memset(), png_memcpy(), and - png_memcmp() macros. - Work around gcc 3.x and Microsoft Visual Studio 2010 complaints. Both object - to the split initialization of num_chunks. - -Version 1.6.0beta28 [August 29, 2012] - Unknown handling fixes and clean up. This adds more correct option - control of the unknown handling, corrects the pre-existing bug where - the per-chunk 'keep' setting is ignored and makes it possible to skip - IDAT chunks in the sequential reader (broken in earlier 1.6 versions). - There is a new test program, test-unknown.c, which is a work in progress - (not currently part of the test suite). Comments in the header files now - explain how the unknown handling works. - Allow fine grain control of unknown chunk APIs. This change allows - png_set_keep_unknown_chunks() to be turned off if not required and causes - both read and write to behave appropriately (on read this is only possible - if the user callback is used to handle unknown chunks). The change - also removes the support for storing unknown chunks in the info_struct - if the only unknown handling enabled is via the callback, allowing libpng - to be configured with callback reading and none of the unnecessary code. - Corrected fix for unknown handling in pngtest. This reinstates the - libpng handling of unknown chunks other than vpAg and sTER (including - unsafe-to-copy chunks which were dropped before) and eliminates the - repositioning of vpAg and sTER in pngtest.png by changing pngtest.png - (so the chunks are where libpng would put them). - Added "tunknown" test and corrected a logic error in png_handle_unknown() - when SAVE support is absent. Moved the shell test scripts for - contrib/libtests from the libpng top directory to contrib/libtests. - png_handle_unknown() must always read or skip the chunk, if - SAVE_UNKNOWN_CHUNKS is turned off *and* the application does not set - a user callback an unknown chunk will not be read, leading to a read - error, which was revealed by the "tunknown" test. - Cleaned up and corrected ICC profile handling. - contrib/libtests/makepng: corrected 'rgb' and 'gray' cases. profile_error - messages could be truncated; made a correct buffer size calculation and - adjusted pngerror.c appropriately. png_icc_check_* checking improved; - changed the functions to receive the correct color type of the PNG on read - or write and check that it matches the color space of the profile (despite - what the comments said before, there is danger in assuming the app will - cope correctly with an RGB profile on a grayscale image and, since it - violates the PNG spec, allowing it is certain to produce inconsistent - app behavior and might even cause app crashes.) Check that profiles - contain the tags needed to process the PNG (tags all required by the ICC - spec). Removed unused PNG_STATIC from pngpriv.h. - -Version 1.6.0beta29 [September 4, 2012] - Fixed the simplified API example programs to add the *colormap parameter - to several of he API and improved the error message if the version field - is not set. - Added contrib/examples/* to the *.zip and *.7z distributions. - Updated simplified API synopses and description of the png_image structure - in the manual. - Made makepng and pngtest produce identical PNGs, add "--relaxed" option - to pngtest. The "--relaxed" option turns off the benign errors that are - enabled by default in pre-RC builds. makepng can now write ICC profiles - where the length has not been extended to a multiple of 4, and pngtest - now intercepts all libpng errors, allowing the previously-introduced - "--strict test" on no warnings to actually work. - Improved ICC profile handling including cHRM chunk generation and fixed - Cygwin+MSVC build errors. The ICC profile handling now includes more - checking. Several errors that caused rejection of the profile are now - handled with a warning in such a way that the invalid profiles will be - read by default in release (but not pre-RC) builds but will not be - written by default. The easy part of handling the cHRM chunk is written, - where the ICC profile contains the required data. The more difficult - part plus guessing a gAMA value requires code to pass selected RGB values - through the profile. - -Version 1.6.0beta30 [October 24, 2012] - Changed ICC profile matrix/vector types to not depend on array type rules. - By the ANSI-C standard the new types should be identical to the previous - versions, and all known versions of gcc tested with the previous versions - except for GCC-4.2.1 work with this version. The change makes the ANSI-C - rule that const applied to an array of elements applies instead to the - elements in the array moot by explicitly applying const to the base - elements of the png_icc_matrix and png_icc_vector types. The accidental - (harmless) 'const' previously applied to the parameters of two of the - functions have also been removed. - Added a work around for GCC 4.2 optimization bug. - Marked the broken (bad white point) original HP sRGB profiles correctly and - correct comments. - Added -DZ_SOLO to contrib/pngminim/*/makefile to work with zlib-1.2.7 - Use /MDd for vstudio debug builds. Also added pngunkown to the vstudio - builds, fixed build errors and corrected a minor exit code error in - pngvalid if the 'touch' file name is invalid. - Add updated WARNING file to projects/vstudio from libpng 1.5/vstudio - Fixed build when using #define PNG_NO_READ_GAMMA in png_do_compose() in - pngrtran.c (Domani Hannes). - -Version 1.6.0beta31 [November 1, 2012] - Undid the erroneous change to vstudio/pngvalid build in libpng-1.6.0beta30. - Made pngvalid so that it will build outside the libpng source tree. - Made builds -DPNG_NO_READ_GAMMA compile (the unit tests still fail). - Made PNG_NO_READ_GAMMA switch off interfaces that depend on READ_GAMMA. - Prior to 1.6.0 switching off READ_GAMMA did unpredictable things to the - interfaces that use it (specifically, png_do_background in 1.4 would - simply display composite for grayscale images but do composition - with the incorrect arithmetic for color ones). In 1.6 the semantic - of -DPNG_NO_READ_GAMMA is changed to simply disable any interface that - depends on it; this obliges people who set it to consider whether they - really want it off if they happen to use any of the interfaces in - question (typically most users who disable it won't). - Fixed GUIDs in projects/vstudio. Some were duplicated or missing, - resulting in VS2010 having to update the files. - Removed non-working ICC profile support code that was mostly added to - libpng-1.6.0beta29 and beta30. There was too much code for too little - gain; implementing full ICC color correction may be desireable but is left - up to applications. - -Version 1.6.0beta32 [November 25, 2012] - Fixed an intermittent SEGV in pngstest due to an uninitialized array element. - Added the ability for contrib/libtests/makepng.c to make a PNG with just one - color. This is useful for debugging pngstest color inaccuracy reports. - Fixed error checking in the simplified write API (Olaf van der Spek) - Made png_user_version_check() ok to use with libpng version 1.10.x and later. - -Version 1.6.0beta33 [December 15, 2012] - Fixed typo in png.c (PNG_SET_CHUNK_MALLOC_MAX should be PNG_CHUNK_MALLOC_MAX) - that causes the MALLOC_MAX limit not to work (John Bowler) - Change png_warning() to png_app_error() in pngwrite.c and comment the - fall-through condition. - Change png_warning() to png_app_warning() in png_write_tRNS(). - Rearranged the ARM-NEON optimizations: Isolated the machine specific code - to the hardware subdirectory and added comments to pngrutil.c so that - implementors of other optimizations know what to do. - Fixed cases of unquoted DESTDIR in Makefile.am - Rebuilt Makefile.in, etc., with autoconf-2.69 and automake-1.12.5. - -Version 1.6.0beta34 [December 19, 2012] - Cleaned up whitespace in the synopsis portion of the manpage "libpng.3" - Disassembled the version number in scripts/options.awk (necessary for - building on SunOs). - -Version 1.6.0beta35 [December 23, 2012] - Made default Zlib compression settings be configurable. This adds #defines to - pnglibconf.h to control the defaults. - Fixed Windows build issues, enabled ARM compilation. Various warnings issued - by earlier versions of GCC fixed for Cygwin and Min/GW (which both use old - GCCs.) ARM support is enabled by default in zlib.props (unsupported by - Microsoft) and ARM compilation is made possible by deleting the check for - x86. The test programs cannot be run because they are not signed. - -Version 1.6.0beta36 [January 2, 2013] - Discontinued distributing libpng-1.x.x.tar.bz2. - Discontinued distributing libpng-1.7.0-1.6.0-diff.txt and similar. - Rebuilt configure with autoconf-2.69 (inadvertently not done in beta33) - Fixed 'make distcheck' on SUN OS - libpng.so was not being removed - -Version 1.6.0beta37 [January 10, 2013] - Fixed conceivable but difficult to repro overflow. Also added two test - programs to generate and test a PNG which should have the problem. - -Version 1.6.0beta39 [January 19, 2013] - Again corrected attempt at overflow detection in png_set_unknown_chunks() - (CVE-2013-7353). Added overflow detection in png_set_sPLT() and - png_set_text_2() (CVE-2013-7354). - -Version 1.6.0beta40 [January 20, 2013] - Use consistent handling of overflows in text, sPLT and unknown png_set_* APIs - -Version 1.6.0rc01 [January 26, 2013] - No changes. - -Version 1.6.0rc02 [February 4, 2013] - Added png_get_palette_max() function. - -Version 1.6.0rc03 [February 5, 2013] - Fixed the png_get_palette_max API. - -Version 1.6.0rc04 [February 7, 2013] - Turn serial tests back on (recently turned off by autotools upgrade). - -Version 1.6.0rc05 [February 8, 2013] - Update manual about png_get_palette_max(). - -Version 1.6.0rc06 [February 9, 2013] - Fixed missing dependency in --prefix builds The intermediate - internal 'prefix.h' file can only be generated correctly after - pnglibconf.h, however the dependency was not in Makefile.am. The - symptoms are unpredictable depending on the order make chooses to - build pngprefix.h and pnglibconf.h, often the error goes unnoticed - because there is a system pnglibconf.h to use instead. - -Version 1.6.0rc07 [February 10, 2013] - Enclosed the new png_get_palette_max in #ifdef PNG_GET_PALETTE_MAX_SUPPORTED - block, and revised pnglibconf.h and pnglibconf.h.prebuilt accordingly. - -Version 1.6.0rc08 [February 10, 2013] - Fix typo in png.h #ifdef - -Version 1.6.0 [February 14, 2013] - No changes. - -Version 1.6.1beta01 [February 16, 2013] - Made symbol prefixing work with the ARM neon optimizations. Also allow - pngpriv.h to be included for preprocessor definitions only, so it can - be used in non-C/C++ files. Back ported from libpng 1.7. - Made sRGB check numbers consistent. - Ported libpng 1.5 options.awk/dfn file handling to 1.6, fixed one bug. - Removed cc -E workround, corrected png_get_palette_max API Tested on - SUN OS cc 5.9, which demonstrates the tokenization problem previously - avoided by using /lib/cpp. Since all .dfn output is now protected in - double quotes unless it is to be macro substituted the fix should - work everywhere. - Enabled parallel tests - back ported from libpng-1.7. - scripts/pnglibconf.dfa formatting improvements back ported from libpng17. - Fixed a race condition in the creation of the build 'scripts' directory - while building with a parallel make. - Use approved/supported Android method to check for NEON, use Linux/POSIX - 1003.1 API to check /proc/self/auxv avoiding buffer allocation and other - library calls (ported from libpng15). - -Version 1.6.1beta02 [February 19, 2013] - Use parentheses more consistently in "#if defined(MACRO)" tests. - Folded long lines. - Reenabled code to allow zero length PLTE chunks for MNG. - -Version 1.6.1beta03 [February 22, 2013] - Fixed ALIGNED_MEMORY support. - Added a new configure option: - --enable-arm-neon=always will stop the run-time checks. New checks - within arm/arm_init.c will cause the code not to be compiled unless - __ARM_NEON__ is set. This should make it fail safe (if someone asks - for it on then the build will fail if it can't be done.) - Updated the INSTALL document. - -Version 1.6.1beta04 [February 27, 2013] - Revised INSTALL to recommend using CPPFLAGS instead of INCLUDES. - Revised scripts/makefile.freebsd to respect ZLIBLIB and ZLIBINC. - Revised scripts/dfn.awk to work with the buggy MSYS awk that has trouble - with CRLF line endings. - -Version 1.6.1beta05 [March 1, 2013] - Avoid a possible memory leak in contrib/gregbook/readpng.c - -Version 1.6.1beta06 [March 4, 2013] - Better documentation of unknown handling API interactions. - Corrected Android builds and corrected libpng.vers with symbol - prefixing. It also makes those tests compile and link on Android. - Added an API png_set_option() to set optimization options externally, - providing an alternative and general solution for the non-portable - run-time tests used by the ARM Neon code, using the PNG_ARM_NEON option. - The order of settings vs options in pnglibconf.h is reversed to allow - settings to depend on options and options can now set (or override) the - defaults for settings. - -Version 1.6.1beta07 [March 7, 2013] - Corrected simplified API default gamma for color-mapped output, added - a flag to change default. In 1.6.0 when the simplified API was used - to produce color-mapped output from an input image with no gamma - information the gamma assumed for the input could be different from - that assumed for non-color-mapped output. In particular 16-bit depth - input files were assumed to be sRGB encoded, whereas in the 'direct' - case they were assumed to have linear data. This was an error. The - fix makes the simplified API treat all input files the same way and - adds a new flag to the png_image::flags member to allow the - application/user to specify that 16-bit files contain sRGB data - rather than the default linear. - Fixed bugs in the pngpixel and makepng test programs. - -Version 1.6.1beta08 [March 7, 2013] - Fixed CMakelists.txt to allow building a single variant of the library - (Claudio Bley): - Introduced a PNG_LIB_TARGETS variable that lists all activated library - targets. It is an error if this variable ends up empty, ie. you have - to build at least one library variant. - Made the *_COPY targets only depend on library targets actually being build. - Use PNG_LIB_TARGETS to unify a code path. - Changed the CREATE_SYMLINK macro to expect the full path to a file as the - first argument. When symlinking the filename component of that path is - determined and used as the link target. - Use copy_if_different in the CREATE_SYMLINK macro. - -Version 1.6.1beta09 [March 13, 2013] - Eliminated two warnings from the Intel C compiler. The warnings are - technically valid, although a reasonable treatment of division would - show it to be incorrect. - -Version 1.6.1rc01 [March 21, 2013] - No changes. - -Version 1.6.1 [March 28, 2013] - No changes. - -Version 1.6.2beta01 [April 14, 2013] - Updated documentation of 1.5.x to 1.6.x changes in iCCP chunk handling. - Fixed incorrect warning of excess deflate data. End condition - the - warning would be produced if the end of the deflate stream wasn't read - in the last row. The warning is harmless. - Corrected the test on user transform changes on read. It was in the - png_set of the transform function, but that doesn't matter unless the - transform function changes the rowbuf size, and that is only valid if - transform_info is called. - Corrected a misplaced closing bracket in contrib/libtests/pngvalid.c - (Flavio Medeiros). - Corrected length written to uncompressed iTXt chunks (Samuli Suominen). - Bug was introduced in libpng-1.6.0. - -Version 1.6.2rc01 [April 18, 2013] - Added contrib/tools/fixitxt.c, to repair the erroneous iTXt chunk length - written by libpng-1.6.0 and 1.6.1. - Disallow storing sRGB information when the sRGB is not supported. - -Version 1.6.2rc02 [April 18, 2013] - Merge pngtest.c with libpng-1.7.0 - -Version 1.6.2rc03 [April 22, 2013] - Trivial spelling cleanup. - -Version 1.6.2rc04 and 1.6.2rc05 [omitted] - -Version 1.6.2rc06 [April 24, 2013] - Reverted to version 1.6.2rc03. Recent changes to arm/neon support - have been ported to libpng-1.7.0beta09 and will reappear in version - 1.6.3beta01. - -Version 1.6.2 [April 25, 2013] - No changes. - -Version 1.6.3beta01 [April 25, 2013] - Revised stack marking in arm/filter_neon.S and configure.ac. - Ensure that NEON filter stuff is completely disabled when switched 'off'. - Previously the ARM NEON specific files were still built if the option - was switched 'off' as opposed to being explicitly disabled. - -Version 1.6.3beta02 [April 26, 2013] - Test for 'arm*' not just 'arm' in the host_cpu configure variable. - Rebuilt the configure scripts. - -Version 1.6.3beta03 [April 30, 2013] - Expanded manual paragraph about writing private chunks, particularly - the need to call png_set_keep_unknown_chunks() when writing them. - Avoid dereferencing NULL pointer possibly returned from - png_create_write_struct() (Andrew Church). - -Version 1.6.3beta05 [May 9, 2013] - Calculate our own zlib windowBits when decoding rather than trusting the - CMF bytes in the PNG datastream. - Added an option to force maximum window size for inflating, which was - the behavior of libpng15 and earlier, via a new PNG_MAXIMUM_INFLATE_WINDOW - option for png_set_options(). - Added png-fix-itxt and png-fix-too-far-back to the built programs and - removed warnings from the source code and timepng that are revealed as - a result. - Detect wrong libpng versions linked to png-fix-too-far-back, which currently - only works with libpng versions that can be made to reliably fail when - the deflate data contains an out-of-window reference. This means only - 1.6 and later. - Fixed gnu issues: g++ needs a static_cast, gcc 4.4.7 has a broken warning - message which it is easier to work round than ignore. - Updated contrib/pngminus/pnm2png.c (Paul Stewart): - Check for EOF - Ignore "#" delimited comments in input file to pnm2png.c. - Fixed whitespace handling - Added a call to png_set_packing() - Initialize dimension values so if sscanf fails at least we have known - invalid values. - Attempt to detect configuration issues with png-fix-too-far-back, which - requires both the correct libpng and the correct zlib to function - correctly. - Check ZLIB_VERNUM for mismatches, enclose #error in quotes - Added information in the documentation about problems with and fixes for - the bad CRC and bad iTXt chunk situations. - -Version 1.6.3beta06 [May 12, 2013] - Allow contrib/pngminus/pnm2png.c to compile without WRITE_INVERT and - WRITE_PACK supported (writes error message that it can't read P1 or - P4 PBM files). - Improved png-fix-too-far-back usage message, added --suffix option. - Revised contrib/pngminim/*/makefile to generate pnglibconf.h with the - right zlib header files. - Separated CPPFLAGS and CFLAGS in contrib/pngminim/*/makefile - -Version 1.6.3beta07 [June 8, 2013] - Removed a redundant test in png_set_IHDR(). - Added set(CMAKE_CONFIGURATION_TYPES ...) to CMakeLists.txt (Andrew Hundt) - Deleted set(CMAKE_BUILD_TYPE) block from CMakeLists.txt - Enclose the prototypes for the simplified write API in - #ifdef PNG_STDIO_SUPPORTED/#endif - Make ARM NEON support work at compile time (not just configure time). - This moves the test on __ARM_NEON__ into pngconf.h to avoid issues when - using a compiler that compiles for multiple architectures at one time. - Removed PNG_FILTER_OPTIMIZATIONS and PNG_ARM_NEON_SUPPORTED from - pnglibconf.h, allowing more of the decisions to be made internally - (pngpriv.h) during the compile. Without this, symbol prefixing is broken - under certain circumstances on ARM platforms. Now only the API parts of - the optimizations ('check' vs 'api') are exposed in the public header files - except that the new setting PNG_ARM_NEON_OPT documents how libpng makes the - decision about whether or not to use the optimizations. - Protect symbol prefixing against CC/CPPFLAGS/CFLAGS useage. - Previous iOS/Xcode fixes for the ARM NEON optimizations moved the test - on __ARM_NEON__ from configure time to compile time. This breaks symbol - prefixing because the definition of the special png_init_filter_functions - call was hidden at configure time if the relevant compiler arguments are - passed in CFLAGS as opposed to CC. This change attempts to avoid all - the confusion that would result by declaring the init function even when - it is not used, so that it will always get prefixed. - -Version 1.6.3beta08 [June 18, 2013] - Revised libpng.3 so that "doclifter" can process it. - -Version 1.6.3beta09 [June 27, 2013] - Revised example.c to illustrate use of PNG_DEFAULT_sRGB and PNG_GAMMA_MAC_18 - as parameters for png_set_gamma(). These have been available since - libpng-1.5.4. - Renamed contrib/tools/png-fix-too-far-back.c to pngfix.c and revised it - to check all compressed chunks known to libpng. - -Version 1.6.3beta10 [July 5, 2013] - Updated documentation to show default behavior of benign errors correctly. - Only compile ARM code when PNG_READ_SUPPORTED is defined. - Fixed undefined behavior in contrib/tools/pngfix.c and added new strip - option. pngfix relied on undefined behavior and even a simple change from - gcc to g++ caused it to fail. The new strip option 'unsafe' has been - implemented and is the default if --max is given. Option names have - been clarified, with --strip=transform now stripping the bKGD chunk, - which was stripped previously with --strip=unused. - Added all documented chunk types to pngpriv.h - Unified pngfix.c source with libpng17. - -Version 1.6.3rc01 [July 11, 2013] - No changes. - -Version 1.6.3 [July 18, 2013] - Revised manual about changes in iTXt chunk handling made in libpng-1.6.0. - Added "/* SAFE */" comments in pngrutil.c and pngrtran.c where warnings - may be erroneously issued by code-checking applications. - -Version 1.6.4beta01 [August 21, 2013] - Added information about png_set_options() to the manual. - Delay calling png_init_filter_functions() until a row with nonzero filter - is found. - -Version 1.6.4beta02 [August 30, 2013] - Fixed inconsistent conditional compilation of png_chunk_unknown_handling() - prototype, definition, and usage. Made it depend on - PNG_HANDLE_AS_UNKNOWN_SUPPORTED everywhere. - -Version 1.6.4rc01 [September 5, 2013] - No changes. - -Version 1.6.4 [September 12, 2013] - No changes. - -Version 1.6.5 [September 14, 2013] - Removed two stray lines of code from arm/arm_init.c. - -Version 1.6.6 [September 16, 2013] - Removed two stray lines of code from arm/arm_init.c, again. - -Version 1.6.7beta01 [September 30, 2013] - Revised unknown chunk code to correct several bugs in the NO_SAVE_/NO_WRITE - combination - Allow HANDLE_AS_UNKNOWN to work when other options are configured off. Also - fixed the pngminim makefiles to work when $(MAKEFLAGS) contains stuff - which terminates the make options (as by default in recent versions of - Gentoo). - Avoid up-cast warnings in pngvalid.c. On ARM the alignment requirements of - png_modifier are greater than that of png_store and as a consequence - compilation of pngvalid.c results in a warning about increased alignment - requirements because of the bare cast to (png_modifier*). The code is safe, - because the pointer is known to point to a stack allocated png_modifier, - but this change avoids the warning. - Fixed default behavior of ARM_NEON_API. If the ARM NEON API option was - compiled without the CHECK option it defaulted to on, not off. - Check user callback behavior in pngunknown.c. Previous versions compiled - if SAVE_UNKNOWN was not available but did nothing since the callback - was never implemented. - Merged pngunknown.c with 1.7 version and back ported 1.7 improvements/fixes - -Version 1.6.7beta02 [October 12, 2013] - Made changes for compatibility with automake 1.14: - 1) Added the 'compile' program to the list of programs that must be cleaned - in autogen.sh - 2) Added 'subdir-objects' which causes .c files in sub-directories to be - compiled such that the corresponding .o files are also in the - sub-directory. This is because automake 1.14 warns that the - current behavior of compiling to the top level directory may be removed - in the future. - 3) Updated dependencies on pnglibconf.h to match the new .o locations and - added all the files in contrib/libtests and contrib/tools that depend - on pnglibconf.h - 4) Added 'BUILD_SOURCES = pnglibconf.h'; this is the automake recommended - way of handling the dependencies of sources that are machine generated; - unfortunately it only works if the user does 'make all' or 'make check', - so the dependencies (3) are still required. - Cleaned up (char*) casts of zlib messages. The latest version of the Intel C - compiler complains about casting a string literal as (char*), so copied the - treatment of z_const from the library code into pngfix.c - Simplified error message code in pngunknown. The simplification has the - useful side effect of avoiding a bogus warning generated by the latest - version of the Intel C compiler (it objects to - condition ? string-literal : string-literal). - Make autogen.sh work with automake 1.13 as well as 1.14. Do this by always - removing the 1.14 'compile' script but never checking for it. - -Version 1.6.7beta03 [October 19, 2013] - Added ARMv8 support (James Yu ). Added file - arm/filter_neon_intrinsics.c; enable with -mfpu=neon. - Revised pngvalid to generate size images with as many filters as it can - manage, limited by the number of rows. - Cleaned up ARM NEON compilation handling. The tests are now in pngpriv.h - and detect the broken GCC compilers. - -Version 1.6.7beta04 [October 26, 2013] - Allow clang derived from older GCC versions to use ARM intrinsics. This - causes all clang builds that use -mfpu=neon to use the intrinsics code, - not the assembler code. This has only been tested on iOS 7. It may be - necessary to exclude some earlier clang versions but this seems unlikely. - Changed NEON implementation selection mechanism. This allows assembler - or intrinsics to be turned on at compile time during the build by defining - PNG_ARM_NEON_IMPLEMENTATION to the correct value (2 or 1). This macro - is undefined by default and the build type is selected in pngpriv.h. - -Version 1.6.7rc01 [November 2, 2013] - No changes. - -Version 1.6.7rc02 [November 7, 2013] - Fixed #include in filter_neon_intrinsics.c and ctype macros. The ctype char - checking macros take an unsigned char argument, not a signed char. - -Version 1.6.7 [November 14, 2013] - No changes. - -Version 1.6.8beta01 [November 24, 2013] - Moved prototype for png_handle_unknown() in pngpriv.h outside of - the #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED/#endif block. - Added "-Wall" to CFLAGS in contrib/pngminim/*/makefile - Conditionally compile some unused functions reported by -Wall in - pngminim. - Fixed 'minimal' builds. Various obviously useful minimal configurations - don't build because of missing contrib/libtests test programs and - overly complex dependencies in scripts/pnglibconf.dfa. This change - adds contrib/conftest/*.dfa files that can be used in automatic build - scripts to ensure that these configurations continue to build. - Enabled WRITE_INVERT and WRITE_PACK in contrib/pngminim/encoder. - Fixed pngvalid 'fail' function declaration on the Intel C Compiler. - This reverts to the previous 'static' implementation and works round - the 'unused static function' warning by using PNG_UNUSED(). - -Version 1.6.8beta02 [November 30, 2013] - Removed or marked PNG_UNUSED some harmless "dead assignments" reported - by clang scan-build. - Changed tabs to 3 spaces in png_debug macros and changed '"%s"m' - to '"%s" m' to improve portability among compilers. - Changed png_free_default() to free() in pngtest.c - -Version 1.6.8rc01 [December 12, 2013] - Tidied up pngfix inits and fixed pngtest no-write builds. - -Version 1.6.8rc02 [December 14, 2013] - Handle zero-length PLTE chunk or NULL palette with png_error() - instead of png_chunk_report(), which by default issues a warning - rather than an error, leading to later reading from a NULL pointer - (png_ptr->palette) in png_do_expand_palette(). This is CVE-2013-6954 - and VU#650142. Libpng-1.6.1 through 1.6.7 are vulnerable. - Libpng-1.6.0 and earlier do not have this bug. - -Version 1.6.8 [December 19, 2013] - No changes. - -Version 1.6.9beta01 [December 26, 2013] - Bookkeeping: Moved functions around (no changes). Moved transform - function definitions before the place where they are called so that - they can be made static. Move the intrapixel functions and the - grayscale palette builder out of the png?tran.c files. The latter - isn't a transform function and is no longer used internally, and the - former MNG specific functions are better placed in pngread/pngwrite.c - Made transform implementation functions static. This makes the internal - functions called by png_do_{read|write}_transformations static. On an - x86-64 DLL build (Gentoo Linux) this reduces the size of the text - segment of the DLL by 1208 bytes, about 0.6%. It also simplifies - maintenance by removing the declarations from pngpriv.h and allowing - easier changes to the internal interfaces. - Rebuilt configure scripts with automake-1.14.1 and autoconf-2.69 - in the tar distributions. - -Version 1.6.9beta02 [January 1, 2014] - Added checks for libpng 1.5 to pngvalid.c. This supports the use of - this version of pngvalid in libpng 1.5 - Merged with pngvalid.c from libpng-1.7 changes to create a single - pngvalid.c - Removed #error macro from contrib/tools/pngfix.c (Thomas Klausner). - Merged pngrio.c, pngtrans.c, pngwio.c, and pngerror.c with libpng-1.7.0 - Merged libpng-1.7.0 changes to make no-interlace configurations work - with test programs. - Revised pngvalid.c to support libpng 1.5, which does not support the - PNG_MAXIMUM_INFLATE_WINDOW option, so #define it out when appropriate in - pngvalid.c - Allow unversioned links created on install to be disabled in configure. - In configure builds 'make install' changes/adds links like png.h - and libpng.a to point to the newly installed, versioned, files (e.g. - libpng17/png.h and libpng17.a). Three new configure options and some - rearrangement of Makefile.am allow creation of these links to be disabled. - -Version 1.6.9beta03 [January 10, 2014] - Removed potentially misleading warning from png_check_IHDR(). - -Version 1.6.9beta04 [January 20, 2014] - Updated scripts/makefile.* to use CPPFLAGS (Cosmin). - Added clang attribute support (Cosmin). - -Version 1.6.9rc01 [January 28, 2014] - No changes. - -Version 1.6.9rc02 [January 30, 2014] - Quiet an uninitialized memory warning from VC2013 in png_get_png(). - -Version 1.6.9 [February 6, 2014] - -Version 1.6.10beta01 [February 9, 2014] - Backported changes from libpng-1.7.0beta30 and beta31: - Fixed a large number of instances where PNGCBAPI was omitted from - function definitions. - Added pngimage test program for png_read_png() and png_write_png() - with two new test scripts. - Removed dependence on !PNG_READ_EXPAND_SUPPORTED for calling - png_set_packing() in png_read_png(). - Fixed combination of ~alpha with shift. On read invert alpha, processing - occurred after shift processing, which causes the final values to be - outside the range that should be produced by the shift. Reversing the - order on read makes the two transforms work together correctly and mirrors - the order used on write. - Do not read invalid sBIT chunks. Previously libpng only checked sBIT - values on write, so a malicious PNG writer could therefore cause - the read code to return an invalid sBIT chunk, which might lead to - application errors or crashes. Such chunks are now skipped (with - chunk_benign_error). - Make png_read_png() and png_write_png() prototypes in png.h depend - upon PNG_READ_SUPPORTED and PNG_WRITE_SUPPORTED. - Support builds with unsupported PNG_TRANSFORM_* values. All of the - PNG_TRANSFORM_* values are always defined in png.h and, because they - are used for both read and write in some cases, it is not reliable - to #if out ones that are totally unsupported. This change adds error - detection in png_read_image() and png_write_image() to do a - png_app_error() if the app requests something that cannot be done - and it adds corresponding code to pngimage.c to handle such options - by not attempting to test them. - -Version 1.6.10beta02 [February 23, 2014] - Moved redefines of png_error(), png_warning(), png_chunk_error(), - and png_chunk_warning() from pngpriv.h to png.h to make them visible - to libpng-calling applications. - Moved OS dependent code from arm/arm_init.c, to allow the included - implementation of the ARM NEON discovery function to be set at - build-time and provide sample implementations from the current code in the - contrib/arm-neon subdirectory. The __linux__ code has also been changed to - compile and link on Android by using /proc/cpuinfo, and the old linux code - is in contrib/arm-neon/linux-auxv.c. The new code avoids POSIX and Linux - dependencies apart from opening /proc/cpuinfo and is C90 compliant. - Check for info_ptr == NULL early in png_read_end() so we don't need to - run all the png_handle_*() and depend on them to return if info_ptr == NULL. - This improves the performance of png_read_end(png_ptr, NULL) and makes - it more robust against future programming errors. - Check for __has_extension before using it in pngconf.h, to - support older Clang versions (Jeremy Sequoia). - Treat CRC error handling with png_set_crc_action(), instead of with - png_set_benign_errors(), which has been the case since libpng-1.6.0beta18. - Use a user warning handler in contrib/gregbook/readpng2.c instead of default, - so warnings will be put on stderr even if libpng has CONSOLE_IO disabled. - Added png_ptr->process_mode = PNG_READ_IDAT_MODE in png_push_read_chunk - after recognizing the IDAT chunk, which avoids an infinite loop while - reading a datastream whose first IDAT chunk is of zero-length. - This fixes CERT VU#684412 and CVE-2014-0333. - Don't recognize known sRGB profiles as sRGB if they have been hacked, - but don't reject them and don't issue a copyright violation warning. - -Version 1.6.10beta03 [February 25, 2014] - Moved some documentation from png.h to libpng.3 and libpng-manual.txt - Minor editing of contrib/arm-neon/README and contrib/examples/*.c - -Version 1.6.10rc01 [February 27, 2014] - Fixed typos in the manual and in scripts/pnglibconf.dfa (CFLAGS -> CPPFLAGS - and PNG_USR_CONFIG -> PNG_USER_CONFIG). - -Version 1.6.10rc02 [February 28, 2014] - Removed unreachable return statement after png_chunk_error() - in pngrutil.c - -Version 1.6.10rc03 [March 4, 2014] - Un-deprecated png_data_freer(). - -Version 1.6.10 [March 6, 2014] - No changes. - -Version 1.6.11beta01 [March 17, 2014] - Use "if (value != 0)" instead of "if (value)" consistently. - Changed ZlibSrcDir from 1.2.5 to 1.2.8 in projects/vstudio. - Moved configuration information from the manual to the INSTALL file. - -Version 1.6.11beta02 [April 6, 2014] - Removed #if/#else/#endif from inside two pow() calls in pngvalid.c because - they were handled improperly by Portland Group's PGI-14.1 - PGI-14.3 - when using its "__builtin_pow()" function. - Silence 'unused parameter' build warnings (Cosmin Truta). - $(CP) is now used alongside $(RM_F). Also, use 'copy' instead of 'cp' - where applicable, and applied other minor makefile changes (Cosmin). - Don't warn about invalid dimensions exceeding user limits (Cosmin). - Allow an easy replacement of the default pre-built configuration - header with a custom header, via the make PNGLIBCONF_H_PREBUILT - macro (Cosmin). - -Version 1.6.11beta03 [April 6, 2014] - Fixed a typo in pngrutil.c, introduced in libpng-1.5.6, that interferes - with "blocky" expansion of sub-8-bit interlaced PNG files (Eric Huss). - Optionally use __builtin_bswap16() in png_do_swap(). - -Version 1.6.11beta04 [April 19, 2014] - Made progressive reading of interlaced images consistent with the - behavior of the sequential reader and consistent with the manual, by - moving some code out of the PNG_READ_INTERLACING_SUPPORTED blocks. The - row_callback now receives the proper pass number and unexpanded rows, when - png_combine_row() isn't built or used, and png_set_interlace_handling() - is not called. - Allow PNG_sRGB_PROFILE_CHECKING = (-1) to mean no sRGB profile checking. - -Version 1.6.11beta05 [April 26, 2014] - Do not reject ICC V2 profiles that lack padding (Kai-Uwe Behrmann). - Relocated closing bracket of the sRGB profile test loop to avoid getting - "Not recognizing known sRGB profile that has been edited" warning for - ICC V2 profiles that lack the MD5 signature in the profile header. - -Version 1.6.11beta06 [May 19, 2014] - Added PNG_SKIP_sRGB_CHECK_PROFILE choice for png_set_option(). - -Version 1.6.11rc01 [May 27, 2014] - No changes. - -Version 1.6.11rc02 [June 3, 2014] - Test ZLIB_VERNUM instead of PNG_ZLIB_VERNUM in contrib/tools/pngfix.c - -Version 1.6.11 [June 5, 2014] - No changes. - -Version 1.6.12rc01 [June 6, 2014] - Relocated new code from 1.6.11beta06 in png.c to a point after the - declarations (Max Stepin). - -Version 1.6.12rc02 [June 7, 2014] - Changed file permissions of contrib/tools/intgamma.sh, - test-driver, and compile from 0644 to 0755 (Cosmin). - -Version 1.6.12rc03 [June 8, 2014] - Ensure "__has_attribute()" macro exists before trying to use it with - old clang compilers (MacPorts Ticket #43939). - -Version 1.6.12 [June 12, 2014] - No changes. - -Version 1.6.13beta01 [July 4, 2014] - Quieted -Wsign-compare and -Wclobber compiler warnings in - contrib/pngminus/*.c - Added "(void) png_ptr;" where needed in contrib/gregbook to quiet - compiler complaints about unused pointers. - Split a long output string in contrib/gregbook/rpng2-x.c. - Added "PNG_SET_OPTION" requirement for sRGB chunk support to pnglibconf.dfa, - Needed for write-only support (John Bowler). - Changed "if defined(__ARM_NEON__)" to - "if (defined(__ARM_NEON__) || defined(__ARM_NEON))" (James Wu). - Fixed clang no-warning builds: png_digit was defined but never used. - -Version 1.6.13beta02 [July 21, 2014] - Fixed an incorrect separator ("/" should be "\") in scripts/makefile.vcwin32 - (bug report from Wolfgang S. Kechel). Bug was introduced in libpng-1.6.11. - Also fixed makefile.bc32, makefile.bor, makefile.msc, makefile.intel, and - makefile.tc3 similarly. - -Version 1.6.13beta03 [August 3, 2014] - Removed scripts/makefile.elf. It has not worked since libpng-1.5.0beta14 - due to elimination of the PNG_FUNCTION_EXPORT and PNG_DATA_EXPORT - definitions from pngconf.h. - Ensure that CMakeLists.txt makes the target "lib" directory before making - symbolic link into it (SourceForge bug report #226 by Rolf Timmermans). - -Version 1.6.13beta04 [August 8, 2014] - Added opinion that the ECCN (Export Control Classification Number) for - libpng is EAR99 to the README file. - Eliminated use of "$<" in makefile explicit rules, when copying - $PNGLIBCONF_H_PREBUILT. This does not work on some versions of make; - bug introduced in libpng version 1.6.11. - -Version 1.6.13rc01 [August 14, 2014] - Made "ccopts" agree with "CFLAGS" in scripts/makefile.hp* and makefile.*sunu - -Version 1.6.13 [August 21, 2014] - No changes. - -Version 1.6.14beta01 [September 14, 2014] - Guard usage of png_ptr->options with #ifdef PNG_SET_OPTION_SUPPORTED. - Do not build contrib/tools/pngfix.c when PNG_SETJMP_NOT_SUPPORTED, - to allow "make" to complete without setjmp support (bug report by - Claudio Fontana) - Add "#include " to contrib/tools/pngfix.c (John Bowler) - -Version 1.6.14beta02 [September 18, 2014] - Use nanosleep() instead of usleep() in contrib/gregbook/rpng2-x.c - because usleep() is deprecated. - Define usleep() in contrib/gregbook/rpng2-x.c if not already defined - in unistd.h and nanosleep() is not available; fixes error introduced - in libpng-1.6.13. - Disable floating point exception handling in pngvalid.c when - PNG_FLOATING_ARITHMETIC is not supported (bug report by "zootus - at users.sourceforge.net"). - -Version 1.6.14beta03 [September 19, 2014] - Define FE_DIVBYZERO, FE_INVALID, and FE_OVERFLOW in pngvalid.c if not - already defined. Revert floating point exception handling in pngvalid.c - to version 1.6.14beta01 behavior. - -Version 1.6.14beta04 [September 27, 2014] - Fixed incorrect handling of the iTXt compression flag in pngrutil.c - (bug report by Shunsaku Hirata). Bug was introduced in libpng-1.6.0. - -Version 1.6.14beta05 [October 1, 2014] - Added "option READ_iCCP enables READ_COMPRESSED_TEXT" to pnglibconf.dfa - -Version 1.6.14beta06 [October 5, 2014] - Removed unused "text_len" parameter from private function png_write_zTXt(). - Conditionally compile some code in png_deflate_claim(), when - PNG_WARNINGS_SUPPORTED and PNG_ERROR_TEXT_SUPPORTED are disabled. - Replaced repeated code in pngpread.c with PNG_PUSH_SAVE_BUFFER_IF_FULL. - Added "chunk iTXt enables TEXT" and "chunk zTXt enables TEXT" - to pnglibconf.dfa. - Removed "option READ_COMPRESSED_TEXT enables READ_TEXT" from pnglibconf.dfa, - to make it possible to configure a libpng that supports iCCP but not TEXT. - -Version 1.6.14beta07 [October 7, 2014] - Removed "option WRITE_COMPRESSED_TEXT enables WRITE_TEXT" from pnglibconf.dfa - Only mark text chunks as written after successfully writing them. - -Version 1.6.14rc01 [October 15, 2014] - Fixed some typos in comments. - -Version 1.6.14rc02 [October 17, 2014] - Changed png_convert_to_rfc_1123() to png_convert_to_rfc_1123_buffer() - in the manual, to reflect the change made in libpng-1.6.0. - Updated README file to explain that direct access to the png_struct - and info_struct members has not been permitted since libpng-1.5.0. - -Version 1.6.14 [October 23, 2014] - No changes. - -Version 1.6.15beta01 [October 29, 2014] - Changed "if (!x)" to "if (x == 0)" and "if (x)" to "if (x != 0)" - Simplified png_free_data(). - Added missing "ptr = NULL" after some instances of png_free(). - -Version 1.6.15beta02 [November 1, 2014] - Changed remaining "if (!x)" to "if (x == 0)" and "if (x)" to "if (x != 0)" - -Version 1.6.15beta03 [November 3, 2014] - Added PNG_USE_ARM_NEON configuration flag (Marcin Juszkiewicz). - -Version 1.6.15beta04 [November 4, 2014] - Removed new PNG_USE_ARM_NEON configuration flag and made a one-line - revision to configure.ac to support ARM on aarch64 instead (John Bowler). - -Version 1.6.15beta05 [November 5, 2014] - Use png_get_libpng_ver(NULL) instead of PNG_LIBPNG_VER_STRING in - example.c, pngtest.c, and applications in the contrib directory. - Avoid out-of-bounds memory access in png_user_version_check(). - Simplified and future-proofed png_user_version_check(). - Fixed GCC unsigned int->float warnings. Various versions of GCC - seem to generate warnings when an unsigned value is implicitly - converted to double. This is probably a GCC bug but this change - avoids the issue by explicitly converting to (int) where safe. - Free all allocated memory in pngimage. The file buffer cache was left - allocated at the end of the program, harmless but it causes memory - leak reports from clang. - Fixed array size calculations to avoid warnings. At various points - in the code the number of elements in an array is calculated using - sizeof. This generates a compile time constant of type (size_t) which - is then typically assigned to an (unsigned int) or (int). Some versions - of GCC on 64-bit systems warn about the apparent narrowing, even though - the same compiler does apparently generate the correct, in-range, - numeric constant. This adds appropriate, safe, casts to make the - warnings go away. - -Version 1.6.15beta06 [November 6, 2014] - Reverted use png_get_libpng_ver(NULL) instead of PNG_LIBPNG_VER_STRING - in the manual, example.c, pngtest.c, and applications in the contrib - directory. It was incorrect advice. - -Version 1.6.15beta07 [November 7, 2014] - Removed #ifdef PNG_16BIT_SUPPORTED/#endif around png_product2(); it is - needed by png_reciprocal2(). - Added #ifdef PNG_16BIT_SUPPORTED/#endif around png_log16bit() and - png_do_swap(). - Changed all "#endif /* PNG_FEATURE_SUPPORTED */" to "#endif /* FEATURE */" - -Version 1.6.15beta08 [November 8, 2014] - More housecleaning in *.h - -Version 1.6.15rc01 [November 13, 2014] - -Version 1.6.15rc02 [November 14, 2014] - The macros passed in the command line to Borland make were ignored if - similarly-named macros were already defined in makefiles. This behavior - is different from POSIX make and other make programs. Surround the - macro definitions with ifndef guards (Cosmin). - -Version 1.6.15rc03 [November 16, 2014] - Added "-D_CRT_SECURE_NO_WARNINGS" to CFLAGS in scripts/makefile.vcwin32. - Removed the obsolete $ARCH variable from scripts/makefile.darwin. - -Version 1.6.15 [November 20, 2014] - No changes. - -Version 1.6.16beta01 [December 14, 2014] - Added ".align 2" to arm/filter_neon.S to support old GAS assemblers that - don't do alignment correctly. - Revised Makefile.am and scripts/symbols.dfn to work with MinGW/MSYS - (Bob Friesenhahn). - -Version 1.6.16beta02 [December 15, 2014] - Revised Makefile.am and scripts/*.dfn again to work with MinGW/MSYS; - renamed scripts/*.dfn to scripts/*.c (John Bowler). - -Version 1.6.16beta03 [December 21, 2014] - Quiet a "comparison always true" warning in pngstest.c (John Bowler). - -Version 1.6.16rc01 [December 21, 2014] - Restored a test on width that was removed from png.c at libpng-1.6.9 - (Bug report by Alex Eubanks, CVE-2015-0973). - -Version 1.6.16rc02 [December 21, 2014] - Undid the update to pngrutil.c in 1.6.16rc01. - -Version 1.6.16rc03 [December 21, 2014] - Fixed an overflow in png_combine_row() with very wide interlaced images - (Bug report and fix by John Bowler, CVE-2014-9495). - -Version 1.6.16 [December 22, 2014] - No changes. - -Version 1.6.17beta01 [January 29, 2015] - Removed duplicate PNG_SAFE_LIMITS_SUPPORTED handling from pngconf.h - Corrected the width limit calculation in png_check_IHDR(). - Removed user limits from pngfix. Also pass NULL pointers to - png_read_row to skip the unnecessary row de-interlace stuff. - Added testing of png_set_packing() to pngvalid.c - Regenerated configure scripts in the *.tar distributions with libtool-2.4.4 - Implement previously untested cases of libpng transforms in pngvalid.c - Fixed byte order in png_do_read_filler() with 16-bit input. Previously - the high and low bytes of the filler, from png_set_filler() or from - png_set_add_alpha(), were read in the wrong order. - Made the check for out-of-range values in png_set_tRNS() detect - values that are exactly 2^bit_depth, and work on 16-bit platforms. - Merged some parts of libpng-1.6.17beta01 and libpng-1.7.0beta47. - Added #ifndef __COVERITY__ where needed in png.c, pngrutil.c and - pngset.c to avoid warnings about dead code. - Added "& 0xff" to many instances of expressions that are typecast - to (png_byte), to avoid Coverity warnings. - -Version 1.6.17beta02 [February 7, 2015] - Work around one more Coverity-scan dead-code warning. - Do not build png_product2() when it is unused. - -Version 1.6.17beta03 [February 17, 2015] - Display user limits in the output from pngtest. - Eliminated the PNG_SAFE_LIMITS macro and restored the 1-million-column - and 1-million-row default limits in pnglibconf.dfa, that can be reset - by the user at build time or run time. This provides a more robust - defense against DOS and as-yet undiscovered overflows. - -Version 1.6.17beta04 [February 21, 2015] - Added PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED macro, on by default. - Allow user to call png_get_IHDR() with NULL arguments (Reuben Hawkins). - Rebuilt configure scripts with automake-1.15 and libtool-2.4.6 - -Version 1.6.17beta05 [February 25, 2015] - Restored compiling of png_reciprocal2 with PNG_NO_16BIT. - -Version 1.6.17beta06 [February 27, 2015] - Moved png_set_filter() prototype into a PNG_WRITE_SUPPORTED block - of png.h. - Avoid runtime checks when converting integer to png_byte with - Visual Studio (Sergey Kosarevsky) - -Version 1.6.17rc01 [March 4, 2015] - No changes. - -Version 1.6.17rc02 [March 9, 2015] - Removed some comments that the configure script did not handle - properly from scripts/pnglibconf.dfa and pnglibconf.h.prebuilt. - Free the unknown_chunks structure even when it contains no data. - -Version 1.6.17rc03 [March 12, 2015] - Updated CMakeLists.txt to add OSX framework, change YES/NO to ON/OFF - for consistency, and remove some useless tests (Alexey Petruchik). - -Version 1.6.17rc04 [March 16, 2015] - Remove pnglibconf.h, pnglibconf.c, and pnglibconf.out instead of - pnglibconf.* in "make clean" (Cosmin). - Fix bug in calculation of maxbits, in png_write_sBIT, introduced - in libpng-1.6.17beta01 (John Bowler). - -Version 1.6.17rc05 [March 21, 2015] - Define PNG_FILTER_* and PNG_FILTER_VALUE_* in png.h even when WRITE - is not supported (John Bowler). This fixes an error introduced in - libpng-1.6.17beta06. - Reverted "& 0xff" additions of version 1.6.17beta01. Libpng passes - the Coverity scan without them. - -Version 1.6.17rc06 [March 23, 2015] - Remove pnglibconf.dfn and pnglibconf.pre with "make clean". - Reformatted some "&0xff" instances to "& 0xff". - Fixed simplified 8-bit-linear to sRGB alpha. The calculated alpha - value was wrong. It's not clear if this affected the final stored - value; in the obvious code path the upper and lower 8-bits of the - alpha value were identical and the alpha was truncated to 8-bits - rather than dividing by 257 (John Bowler). - -Version 1.6.17 [March 26, 2015] - No changes. - -Version 1.6.18beta01 [April 1, 2015] - Removed PNG_SET_CHUNK_[CACHE|MALLOC]_LIMIT_SUPPORTED macros. They - have been combined with PNG_SET_USER_LIMITS_SUPPORTED (resolves - bug report by Andrew Church). - Fixed rgb_to_gray checks and added tRNS checks to pngvalid.c. This - fixes some arithmetic errors that caused some tests to fail on - some 32-bit platforms (Bug reports by Peter Breitenlohner [i686] - and Petr Gajdos [i586]). - -Version 1.6.18beta02 [April 26, 2015] - Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler - (Bug report by Viktor Szakats). - -Version 1.6.18beta03 [May 6, 2015] - Replaced "unexpected" with an integer (0xabadca11) in pngset.c - where a long was expected, to avoid a compiler warning when PNG_DEBUG > 1. - Added contrib/examples/simpleover.c, to demonstrate how to handle - alpha compositing of multiple images, using the "simplified API" - and an example PNG generation tool, contrib/examples/genpng.c - (John Bowler). - -Version 1.6.18beta04 [May 20, 2015] - PNG_RELEASE_BUILD replaces tests where the code depended on the build base - type and can be defined on the command line, allowing testing in beta - builds (John Bowler). - Avoid Coverity issue 80858 (REVERSE NULL) in pngtest.c PNG_DEBUG builds. - Avoid a harmless potential integer overflow in png_XYZ_from_xy() (Bug - report from Christopher Ferris). - -Version 1.6.18beta05 [May 31, 2015] - Backport filter selection code from libpng-1.7.0beta51, to combine - sub_row, up_row, avg_row, and paeth_row into try_row and tst_row. - Changed png_voidcast(), etc., to voidcast(), etc., in contrib/tools/pngfix.c - to avoid confusion with the libpng private macros. - Fixed old cut&paste bug in the weighted filter selection code in - pngwutil.c, introduced in libpng-0.95, March 1997. - -Version 1.6.18beta06 [June 1, 2015] - Removed WRITE_WEIGHTED_FILTERED code, to save a few kbytes of the - compiled library size. It never worked properly and as far as we can - tell, no one uses it. The png_set_filter_heuristics() and - png_set_filter_heuristics_fixed() APIs are retained but deprecated - and do nothing. - -Version 1.6.18beta07 [June 6, 2015] - Removed non-working progressive reader 'skip' function. This - function has apparently never been used. It was implemented - to support back-door modification of png_struct in libpng-1.4.x - but (because it does nothing and cannot do anything) was apparently - never tested (John Bowler). - Fixed cexcept.h in which GCC 5 now reports that one of the auto - variables in the Try macro needs to be volatile to prevent value - being lost over the setjmp (John Bowler). - Fixed NO_WRITE_FILTER and -Wconversion build breaks (John Bowler). - Fix g++ build breaks (John Bowler). - Quieted some Coverity issues in pngfix.c, png-fix-itxt.c, pngvalid.c, - pngstest.c, and pngimage.c. Most seem harmless, but png-fix-itxt - would only work with iTXt chunks with length 255 or less. - Added #ifdef's to contrib/examples programs so people don't try - to compile them without the minimum required support enabled - (suggested by Flavio Medeiros). - -Version 1.6.18beta08 [June 30, 2015] - Eliminated the final two Coverity defects (insecure temporary file - handling in contrib/libtests/pngstest.c; possible overflow of - unsigned char in contrib/tools/png-fix-itxt.c). To use the "secure" - file handling, define PNG_USE_MKSTEMP, otherwise "tmpfile()" will - be used. - Removed some unused WEIGHTED_FILTER macros from png.h and pngstruct.h - -Version 1.6.18beta09 [July 5, 2015] - Removed some useless typecasts from contrib/tools/png-fix-itxt.c - Fixed a new signed-unsigned comparison in pngrtran.c (Max Stepin). - Replaced arbitrary use of 'extern' with #define PNG_LINKAGE_*. To - preserve API compatibility, the new defines all default to "extern" - (requested by Jan Nijtmans). - -Version 1.6.18rc01 [July 9, 2015] - Belatedly added Mans Rullgard and James Yu to the list of Contributing - Authors. - -Version 1.6.18rc02 [July 12, 2015] - Restored unused FILTER_HEURISTIC macros removed at libpng-1.6.18beta08 - to png.h to avoid compatibility warnings. - -Version 1.6.18rc03 [July 15, 2015] - Minor changes to the man page - -Version 1.6.18 [July 23, 2015] - No changes. - -Version 1.6.19beta01 [July 30, 2015] - Updated obsolete information about the simplified API macros in the - manual pages (Bug report by Arc Riley). - Avoid potentially dereferencing NULL info_ptr in png_info_init_3(). - Rearranged png.h to put the major sections in the same order as - in libpng17. - Eliminated unused PNG_COST_SHIFT, PNG_WEIGHT_SHIFT, PNG_COST_FACTOR, and - PNG_WEIGHT_FACTOR macros. - Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler - (Bug report by Viktor Szakats). Several warnings remain and are - unavoidable, where we test for overflow. - Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c - Fixed uninitialized variable in contrib/gregbook/rpng2-x.c - -Version 1.6.19beta02 [August 19, 2015] - Moved config.h.in~ from the "libpng_autotools_files" list to the - "libpng_autotools_extra" list in autogen.sh because it was causing a - false positive for missing files (bug report by Robert C. Seacord). - Removed unreachable "break" statements in png.c, pngread.c, and pngrtran.c - to suppress clang warnings (Bug report by Viktor Szakats). - Fixed some bad links in the man page. - Changed "n bit" to "n-bit" in comments. - Added signed/unsigned 16-bit safety net. This removes the dubious - 0x8000 flag definitions on 16-bit systems. They aren't supported - yet the defs *probably* work, however it seems much safer to do this - and be advised if anyone, contrary to advice, is building libpng 1.6 - on a 16-bit system. It also adds back various switch default clauses - for GCC; GCC errors out if they are not present (with an appropriately - high level of warnings). - Safely convert num_bytes to a png_byte in png_set_sig_bytes() (Robert - Seacord). - Fixed the recently reported 1's complement security issue by replacing - the value that is illegal in the PNG spec, in both signed and unsigned - values, with 0. Illegal unsigned values (anything greater than or equal - to 0x80000000) can still pass through, but since these are not illegal - in ANSI-C (unlike 0x80000000 in the signed case) the checking that - occurs later can catch them (John Bowler). - -Version 1.6.19beta03 [September 26, 2015] - Fixed png_save_int_32 when int is not 2's complement (John Bowler). - Updated libpng16 with all the recent test changes from libpng17, - including changes to pngvalid.c to ensure that the original, - distributed, version of contrib/visupng/cexcept.h can be used - (John Bowler). - pngvalid contains the correction to the use of SAVE/STORE_ - UNKNOWN_CHUNKS; a bug revealed by changes in libpng 1.7. More - tests contain the --strict option to detect warnings and the - pngvalid-standard test has been corrected so that it does not - turn on progressive-read. There is a separate test which does - that. (John Bowler) - Also made some signed/unsigned fixes. - Make pngstest error limits version specific. Splitting the machine - generated error structs out to a file allows the values to be updated - without changing pngstest.c itself. Since libpng 1.6 and 1.7 have - slightly different error limits this simplifies maintenance. The - makepngs.sh script has also been updated to more accurately reflect - current problems in libpng 1.7 (John Bowler). - Incorporated new test PNG files into make check. tests/pngstest-* - are changed so that the new test files are divided into 8 groups by - gamma and alpha channel. These tests have considerably better code - and pixel-value coverage than contrib/pngsuite; however,coverage is - still incomplete (John Bowler). - Removed the '--strict' in 1.6 because of the double-gamma-correction - warning, updated pngstest-errors.h for the errors detected with the - new contrib/testspngs PNG test files (John Bowler). - -Version 1.6.19beta04 [October 15, 2015] - Worked around rgb-to-gray issues in libpng 1.6. The previous - attempts to ignore the errors in the code aren't quite enough to - deal with the 'channel selection' encoding added to libpng 1.7; abort. - pngvalid.c is changed to drop this encoding in prior versions. - Fixed 'pow' macros in pngvalid.c. It is legal for 'pow' to be a - macro, therefore the argument list cannot contain preprocessing - directives. Make sure pow is a function where this happens. This is - a minimal safe fix, the issue only arises in non-performance-critical - code (bug report by Curtis Leach, fix by John Bowler). - Added sPLT support to pngtest.c - -Version 1.6.19rc01 [October 23, 2015] - No changes. - -Version 1.6.19rc02 [October 31, 2015] - Prevent setting or writing over-length PLTE chunk (Cosmin Truta). - Silently truncate over-length PLTE chunk while reading. - Libpng incorrectly calculated the output rowbytes when the application - decreased either the number of channels or the bit depth (or both) in - a user transform. This was safe; libpng overallocated buffer space - (potentially by quite a lot; up to 4 times the amount required) but, - from 1.5.4 on, resulted in a png_error (John Bowler). - -Version 1.6.19rc03 [November 3, 2015] - Fixed some inconsequential cut-and-paste typos in png_set_cHRM_XYZ_fixed(). - Clarified COPYRIGHT information to state explicitly that versions - are derived from previous versions. - Removed much of the long list of previous versions from png.h and - libpng.3. - -Version 1.6.19rc04 [November 5, 2015] - Fixed new bug with CRC error after reading an over-length palette - (bug report by Cosmin Truta). - -Version 1.6.19 [November 12, 2015] - Cleaned up coding style in png_handle_PLTE(). - -Send comments/corrections/commendations to png-mng-implement at lists.sf.net -(subscription required; visit -https://lists.sourceforge.net/lists/listinfo/png-mng-implement -to subscribe) -or to glennrp at users.sourceforge.net - -Glenn R-P -#endif diff --git a/extern/libpng/CMakeLists.txt b/extern/libpng/CMakeLists.txt deleted file mode 100644 index 5c3476da0..000000000 --- a/extern/libpng/CMakeLists.txt +++ /dev/null @@ -1,75 +0,0 @@ -if (APPLE) - if (NOT PNG_DIR) - # hint at macports libpng (build with +universal) - set(PNG_DIR /opt/local/lib) - endif () - list(LENGTH CMAKE_OSX_ARCHITECTURES num_archs) - if (num_archs GREATER 1) - # disable default search paths so we don't use homebrew's non-universal libpng - set(PNG_SEARCH NO_DEFAULT_PATHS NO_CMAKE_FIND_ROOT_PATH NO_CMAKE_SYSTEM_PATH) - endif () - # only consider static libs - find_library(PNG_LIB NAMES libpng.a HINTS ${PNG_DIR} ${PNG_SEARCH}) - if (PNG_LIB) - find_path(PNG_INCLUDE_DIR png.h HINTS "${PNG_LIB}/../../include" NO_DEFAULT_PATHS NO_CMAKE_FIND_ROOT_PATH NO_CMAKE_SYSTEM_PATH) - add_library(png STATIC IMPORTED GLOBAL) - set_target_properties(png PROPERTIES IMPORTED_LOCATION ${PNG_LIB}) - target_include_directories(png INTERFACE ${PNG_INCLUDE_DIR}) - target_link_libraries(png INTERFACE ${ZLIB_LIBRARIES}) - set(PNG_LIBRARIES png CACHE PATH "PNG libraries" FORCE) - message(STATUS "Using static libpng at ${PNG_LIB}, include: ${PNG_INCLUDE_DIR}") - set(PNG_FOUND YES) - endif () -else () - find_package(PNG) - if (PNG_FOUND) - set_target_properties(PNG::PNG PROPERTIES IMPORTED_GLOBAL TRUE) - set(PNG_LIBRARIES PNG::PNG CACHE STRING "PNG libraries" FORCE) - endif () -endif () -if (NOT PNG_FOUND) - message(STATUS "Using built-in libpng") - if ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "arm(64)?" OR (APPLE AND "arm64" IN_LIST CMAKE_OSX_ARCHITECTURES)) - list(APPEND INTRINSICS - arm/arm_init.c - arm/filter_neon.S - arm/filter_neon_intrinsics.c - arm/palette_neon_intrinsics.c) - endif () - if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" OR (APPLE AND "x86_64" IN_LIST CMAKE_OSX_ARCHITECTURES)) - list(APPEND INTRINSICS - intel/filter_sse2_intrinsics.c - intel/intel_init.c) - endif () - add_library(png - png.h - pngconf.h - pngdebug.h - pnginfo.h - pngpriv.h - pngstruct.h - pnglibconf.h - - png.c - pngerror.c - pngget.c - pngmem.c - pngpread.c - pngread.c - pngrio.c - pngrtran.c - pngrutil.c - pngset.c - pngtrans.c - pngwio.c - pngwrite.c - pngwtran.c - pngwutil.c - ${INTRINSICS}) - if (APPLE) - target_compile_options(png PRIVATE -Wno-implicit-fallthrough) - endif () - target_link_libraries(png PUBLIC ${ZLIB_LIBRARIES}) - target_include_directories(png INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) - set(PNG_LIBRARIES png CACHE PATH "PNG libraries" FORCE) -endif () diff --git a/extern/libpng/README b/extern/libpng/README deleted file mode 100644 index cfc1f0e3d..000000000 --- a/extern/libpng/README +++ /dev/null @@ -1,183 +0,0 @@ -README for libpng version 1.6.37 - April 14, 2019 -================================================= - -See the note about version numbers near the top of png.h. -See INSTALL for instructions on how to install libpng. - -Libpng comes in several distribution formats. Get libpng-*.tar.gz or -libpng-*.tar.xz or if you want UNIX-style line endings in the text -files, or lpng*.7z or lpng*.zip if you want DOS-style line endings. - -Version 0.89 was the first official release of libpng. Don't let the -fact that it's the first release fool you. The libpng library has been -in extensive use and testing since mid-1995. By late 1997 it had -finally gotten to the stage where there hadn't been significant -changes to the API in some time, and people have a bad feeling about -libraries with versions < 1.0. Version 1.0.0 was released in -March 1998. - -**** -Note that some of the changes to the png_info structure render this -version of the library binary incompatible with libpng-0.89 or -earlier versions if you are using a shared library. The type of the -"filler" parameter for png_set_filler() has changed from png_byte to -png_uint_32, which will affect shared-library applications that use -this function. - -To avoid problems with changes to the internals of the png info_struct, -new APIs have been made available in 0.95 to avoid direct application -access to info_ptr. These functions are the png_set_ and -png_get_ functions. These functions should be used when -accessing/storing the info_struct data, rather than manipulating it -directly, to avoid such problems in the future. - -It is important to note that the APIs did not make current programs -that access the info struct directly incompatible with the new -library, through libpng-1.2.x. In libpng-1.4.x, which was meant to -be a transitional release, members of the png_struct and the -info_struct can still be accessed, but the compiler will issue a -warning about deprecated usage. Since libpng-1.5.0, direct access -to these structs is not allowed, and the definitions of the structs -reside in private pngstruct.h and pnginfo.h header files that are not -accessible to applications. It is strongly suggested that new -programs use the new APIs (as shown in example.c and pngtest.c), and -older programs be converted to the new format, to facilitate upgrades -in the future. -**** - -Additions since 0.90 include the ability to compile libpng as a -Windows DLL, and new APIs for accessing data in the info struct. -Experimental functions include the ability to set weighting and cost -factors for row filter selection, direct reads of integers from buffers -on big-endian processors that support misaligned data access, faster -methods of doing alpha composition, and more accurate 16->8 bit color -conversion. - -The additions since 0.89 include the ability to read from a PNG stream -which has had some (or all) of the signature bytes read by the calling -application. This also allows the reading of embedded PNG streams that -do not have the PNG file signature. As well, it is now possible to set -the library action on the detection of chunk CRC errors. It is possible -to set different actions based on whether the CRC error occurred in a -critical or an ancillary chunk. - -For a detailed description on using libpng, read libpng-manual.txt. -For examples of libpng in a program, see example.c and pngtest.c. For -usage information and restrictions (what little they are) on libpng, -see png.h. For a description on using zlib (the compression library -used by libpng) and zlib's restrictions, see zlib.h - -I have included a general makefile, as well as several machine and -compiler specific ones, but you may have to modify one for your own -needs. - -You should use zlib 1.0.4 or later to run this, but it MAY work with -versions as old as zlib 0.95. Even so, there are bugs in older zlib -versions which can cause the output of invalid compression streams for -some images. - -You should also note that zlib is a compression library that is useful -for more things than just PNG files. You can use zlib as a drop-in -replacement for fread() and fwrite(), if you are so inclined. - -zlib should be available at the same place that libpng is, or at -https://zlib.net. - -You may also want a copy of the PNG specification. It is available -as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find -these at http://www.libpng.org/pub/png/pngdocs.html . - -This code is currently being archived at libpng.sourceforge.io in the -[DOWNLOAD] area, and at http://libpng.download/src . - -This release, based in a large way on Glenn's, Guy's and Andreas' -earlier work, was created and will be supported by myself and the PNG -development group. - -Send comments/corrections/commendations to png-mng-implement at -lists.sourceforge.net (subscription required; visit -https://lists.sourceforge.net/lists/listinfo/png-mng-implement -to subscribe). - -Send general questions about the PNG specification to png-mng-misc -at lists.sourceforge.net (subscription required; visit -https://lists.sourceforge.net/lists/listinfo/png-mng-misc to -subscribe). - -Files in this distribution: - - ANNOUNCE => Announcement of this version, with recent changes - AUTHORS => List of contributing authors - CHANGES => Description of changes between libpng versions - KNOWNBUG => List of known bugs and deficiencies - LICENSE => License to use and redistribute libpng - README => This file - TODO => Things not implemented in the current library - TRADEMARK => Trademark information - example.c => Example code for using libpng functions - libpng.3 => manual page for libpng (includes libpng-manual.txt) - libpng-manual.txt => Description of libpng and its functions - libpngpf.3 => manual page for libpng's private functions - png.5 => manual page for the PNG format - png.c => Basic interface functions common to library - png.h => Library function and interface declarations (public) - pngpriv.h => Library function and interface declarations (private) - pngconf.h => System specific library configuration (public) - pngstruct.h => png_struct declaration (private) - pnginfo.h => png_info struct declaration (private) - pngdebug.h => debugging macros (private) - pngerror.c => Error/warning message I/O functions - pngget.c => Functions for retrieving info from struct - pngmem.c => Memory handling functions - pngbar.png => PNG logo, 88x31 - pngnow.png => PNG logo, 98x31 - pngpread.c => Progressive reading functions - pngread.c => Read data/helper high-level functions - pngrio.c => Lowest-level data read I/O functions - pngrtran.c => Read data transformation functions - pngrutil.c => Read data utility functions - pngset.c => Functions for storing data into the info_struct - pngtest.c => Library test program - pngtest.png => Library test sample image - pngtrans.c => Common data transformation functions - pngwio.c => Lowest-level write I/O functions - pngwrite.c => High-level write functions - pngwtran.c => Write data transformations - pngwutil.c => Write utility functions - arm => Contains optimized code for the ARM platform - powerpc => Contains optimized code for the PowerPC platform - contrib => Contributions - arm-neon => Optimized code for ARM-NEON platform - powerpc-vsx => Optimized code for POWERPC-VSX platform - examples => Example programs - gregbook => source code for PNG reading and writing, from - Greg Roelofs' "PNG: The Definitive Guide", - O'Reilly, 1999 - libtests => Test programs - mips-msa => Optimized code for MIPS-MSA platform - pngminim => Minimal decoder, encoder, and progressive decoder - programs demonstrating use of pngusr.dfa - pngminus => Simple pnm2png and png2pnm programs - pngsuite => Test images - testpngs - tools => Various tools - visupng => Contains a MSVC workspace for VisualPng - intel => Optimized code for INTEL-SSE2 platform - mips => Optimized code for MIPS platform - projects => Contains project files and workspaces for - building a DLL - owatcom => Contains a WATCOM project for building libpng - visualc71 => Contains a Microsoft Visual C++ (MSVC) - workspace for building libpng and zlib - vstudio => Contains a Microsoft Visual C++ (MSVC) - workspace for building libpng and zlib - scripts => Directory containing scripts for building libpng: - (see scripts/README.txt for the list of scripts) - -Good luck, and happy coding! - - * Cosmin Truta (current maintainer, since 2018) - * Glenn Randers-Pehrson (former maintainer, 1998-2018) - * Andreas Eric Dilger (former maintainer, 1996-1997) - * Guy Eric Schalnat (original author and former maintainer, 1995-1996) - (formerly of Group 42, Inc.) diff --git a/extern/libpng/TODO b/extern/libpng/TODO deleted file mode 100644 index 72633774f..000000000 --- a/extern/libpng/TODO +++ /dev/null @@ -1,29 +0,0 @@ -/* -TODO - list of things to do for libpng: - -Final bug fixes. -Better C++ wrapper/full C++ implementation? -Fix problem with C++ and EXTERN "C". -cHRM transformation. -Remove setjmp/longjmp usage in favor of returning error codes. -Palette creation. -Add "grayscale->palette" transformation and "palette->grayscale" detection. -Improved dithering. -Multi-lingual error and warning message support. -Complete sRGB transformation (presently it simply uses gamma=0.45455). -Make profile checking optional via a png_set_something() call. -Man pages for function calls. -Better documentation. -Better filter selection - (counting huffman bits/precompression? filter inertia? filter costs?). -Histogram creation. -Text conversion between different code pages (Latin-1 -> Mac and DOS). -Avoid building gamma tables whenever possible. -Use greater precision when changing to linear gamma for compositing against - background and doing rgb-to-gray transformation. -Investigate pre-incremented loop counters and other loop constructions. -Add interpolated method of handling interlacing. -Switch to the simpler zlib (zlib/libpng) license if legally possible. -Extend pngvalid.c to validate more of the libpng transformations. - -*/ diff --git a/extern/libpng/arm/arm_init.c b/extern/libpng/arm/arm_init.c deleted file mode 100644 index a34ecdbef..000000000 --- a/extern/libpng/arm/arm_init.c +++ /dev/null @@ -1,136 +0,0 @@ - -/* arm_init.c - NEON optimised filter functions - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 2014,2016 Glenn Randers-Pehrson - * Written by Mans Rullgard, 2011. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are - * called. - */ -#define _POSIX_SOURCE 1 - -#include "../pngpriv.h" - -#ifdef PNG_READ_SUPPORTED - -#if PNG_ARM_NEON_OPT > 0 -#ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */ -/* WARNING: it is strongly recommended that you do not build libpng with - * run-time checks for CPU features if at all possible. In the case of the ARM - * NEON instructions there is no processor-specific way of detecting the - * presence of the required support, therefore run-time detection is extremely - * OS specific. - * - * You may set the macro PNG_ARM_NEON_FILE to the file name of file containing - * a fragment of C source code which defines the png_have_neon function. There - * are a number of implementations in contrib/arm-neon, but the only one that - * has partial support is contrib/arm-neon/linux.c - a generic Linux - * implementation which reads /proc/cpufino. - */ -#ifndef PNG_ARM_NEON_FILE -# ifdef __linux__ -# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c" -# endif -#endif - -#ifdef PNG_ARM_NEON_FILE - -#include /* for sig_atomic_t */ -static int png_have_neon(png_structp png_ptr); -#include PNG_ARM_NEON_FILE - -#else /* PNG_ARM_NEON_FILE */ -# error "PNG_ARM_NEON_FILE undefined: no support for run-time ARM NEON checks" -#endif /* PNG_ARM_NEON_FILE */ -#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ - -#ifndef PNG_ALIGNED_MEMORY_SUPPORTED -# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED" -#endif - -void -png_init_filter_functions_neon(png_structp pp, unsigned int bpp) -{ - /* The switch statement is compiled in for ARM_NEON_API, the call to - * png_have_neon is compiled in for ARM_NEON_CHECK. If both are defined - * the check is only performed if the API has not set the NEON option on - * or off explicitly. In this case the check controls what happens. - * - * If the CHECK is not compiled in and the option is UNSET the behavior prior - * to 1.6.7 was to use the NEON code - this was a bug caused by having the - * wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF, - * as documented in png.h - */ - png_debug(1, "in png_init_filter_functions_neon"); -#ifdef PNG_ARM_NEON_API_SUPPORTED - switch ((pp->options >> PNG_ARM_NEON) & 3) - { - case PNG_OPTION_UNSET: - /* Allow the run-time check to execute if it has been enabled - - * thus both API and CHECK can be turned on. If it isn't supported - * this case will fall through to the 'default' below, which just - * returns. - */ -#endif /* PNG_ARM_NEON_API_SUPPORTED */ -#ifdef PNG_ARM_NEON_CHECK_SUPPORTED - { - static volatile sig_atomic_t no_neon = -1; /* not checked */ - - if (no_neon < 0) - no_neon = !png_have_neon(pp); - - if (no_neon) - return; - } -#ifdef PNG_ARM_NEON_API_SUPPORTED - break; -#endif -#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ - -#ifdef PNG_ARM_NEON_API_SUPPORTED - default: /* OFF or INVALID */ - return; - - case PNG_OPTION_ON: - /* Option turned on */ - break; - } -#endif - - /* IMPORTANT: any new external functions used here must be declared using - * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the - * 'prefix' option to configure works: - * - * ./configure --with-libpng-prefix=foobar_ - * - * Verify you have got this right by running the above command, doing a build - * and examining pngprefix.h; it must contain a #define for every external - * function you add. (Notice that this happens automatically for the - * initialization function.) - */ - pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon; - - if (bpp == 3) - { - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon; - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth3_neon; - } - - else if (bpp == 4) - { - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon; - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth4_neon; - } -} -#endif /* PNG_ARM_NEON_OPT > 0 */ -#endif /* READ */ diff --git a/extern/libpng/arm/filter_neon.S b/extern/libpng/arm/filter_neon.S deleted file mode 100644 index 2308aad13..000000000 --- a/extern/libpng/arm/filter_neon.S +++ /dev/null @@ -1,253 +0,0 @@ - -/* filter_neon.S - NEON optimised filter functions - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 2014,2017 Glenn Randers-Pehrson - * Written by Mans Rullgard, 2011. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* This is required to get the symbol renames, which are #defines, and the - * definitions (or not) of PNG_ARM_NEON_OPT and PNG_ARM_NEON_IMPLEMENTATION. - */ -#define PNG_VERSION_INFO_ONLY -#include "../pngpriv.h" - -#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__) -.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */ -#endif - -#ifdef PNG_READ_SUPPORTED - -/* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for - * ARM64). The code in arm/filter_neon_intrinsics.c supports ARM64, however it - * only works if -mfpu=neon is specified on the GCC command line. See pngpriv.h - * for the logic which sets PNG_USE_ARM_NEON_ASM: - */ -#if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */ - -#if PNG_ARM_NEON_OPT > 0 - -#ifdef __ELF__ -# define ELF -#else -# define ELF @ -#endif - - .arch armv7-a - .fpu neon - -.macro func name, export=0 - .macro endfunc -ELF .size \name, . - \name - .endfunc - .purgem endfunc - .endm - .text - - /* Explicitly specifying alignment here because some versions of - * GAS don't align code correctly. This is harmless in correctly - * written versions of GAS. - */ - .align 2 - - .if \export - .global \name - .endif -ELF .type \name, STT_FUNC - .func \name -\name: -.endm - -func png_read_filter_row_sub4_neon, export=1 - ldr r3, [r0, #4] @ rowbytes - vmov.i8 d3, #0 -1: - vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] - vadd.u8 d0, d3, d4 - vadd.u8 d1, d0, d5 - vadd.u8 d2, d1, d6 - vadd.u8 d3, d2, d7 - vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! - subs r3, r3, #16 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_sub3_neon, export=1 - ldr r3, [r0, #4] @ rowbytes - vmov.i8 d3, #0 - mov r0, r1 - mov r2, #3 - mov r12, #12 - vld1.8 {q11}, [r0], r12 -1: - vext.8 d5, d22, d23, #3 - vadd.u8 d0, d3, d22 - vext.8 d6, d22, d23, #6 - vadd.u8 d1, d0, d5 - vext.8 d7, d23, d23, #1 - vld1.8 {q11}, [r0], r12 - vst1.32 {d0[0]}, [r1,:32], r2 - vadd.u8 d2, d1, d6 - vst1.32 {d1[0]}, [r1], r2 - vadd.u8 d3, d2, d7 - vst1.32 {d2[0]}, [r1], r2 - vst1.32 {d3[0]}, [r1], r2 - subs r3, r3, #12 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_up_neon, export=1 - ldr r3, [r0, #4] @ rowbytes -1: - vld1.8 {q0}, [r1,:128] - vld1.8 {q1}, [r2,:128]! - vadd.u8 q0, q0, q1 - vst1.8 {q0}, [r1,:128]! - subs r3, r3, #16 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_avg4_neon, export=1 - ldr r12, [r0, #4] @ rowbytes - vmov.i8 d3, #0 -1: - vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] - vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]! - vhadd.u8 d0, d3, d16 - vadd.u8 d0, d0, d4 - vhadd.u8 d1, d0, d17 - vadd.u8 d1, d1, d5 - vhadd.u8 d2, d1, d18 - vadd.u8 d2, d2, d6 - vhadd.u8 d3, d2, d19 - vadd.u8 d3, d3, d7 - vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! - subs r12, r12, #16 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_avg3_neon, export=1 - push {r4,lr} - ldr r12, [r0, #4] @ rowbytes - vmov.i8 d3, #0 - mov r0, r1 - mov r4, #3 - mov lr, #12 - vld1.8 {q11}, [r0], lr -1: - vld1.8 {q10}, [r2], lr - vext.8 d5, d22, d23, #3 - vhadd.u8 d0, d3, d20 - vext.8 d17, d20, d21, #3 - vadd.u8 d0, d0, d22 - vext.8 d6, d22, d23, #6 - vhadd.u8 d1, d0, d17 - vext.8 d18, d20, d21, #6 - vadd.u8 d1, d1, d5 - vext.8 d7, d23, d23, #1 - vld1.8 {q11}, [r0], lr - vst1.32 {d0[0]}, [r1,:32], r4 - vhadd.u8 d2, d1, d18 - vst1.32 {d1[0]}, [r1], r4 - vext.8 d19, d21, d21, #1 - vadd.u8 d2, d2, d6 - vhadd.u8 d3, d2, d19 - vst1.32 {d2[0]}, [r1], r4 - vadd.u8 d3, d3, d7 - vst1.32 {d3[0]}, [r1], r4 - subs r12, r12, #12 - bgt 1b - - pop {r4,pc} -endfunc - -.macro paeth rx, ra, rb, rc - vaddl.u8 q12, \ra, \rb @ a + b - vaddl.u8 q15, \rc, \rc @ 2*c - vabdl.u8 q13, \rb, \rc @ pa - vabdl.u8 q14, \ra, \rc @ pb - vabd.u16 q15, q12, q15 @ pc - vcle.u16 q12, q13, q14 @ pa <= pb - vcle.u16 q13, q13, q15 @ pa <= pc - vcle.u16 q14, q14, q15 @ pb <= pc - vand q12, q12, q13 @ pa <= pb && pa <= pc - vmovn.u16 d28, q14 - vmovn.u16 \rx, q12 - vbsl d28, \rb, \rc - vbsl \rx, \ra, d28 -.endm - -func png_read_filter_row_paeth4_neon, export=1 - ldr r12, [r0, #4] @ rowbytes - vmov.i8 d3, #0 - vmov.i8 d20, #0 -1: - vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] - vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]! - paeth d0, d3, d16, d20 - vadd.u8 d0, d0, d4 - paeth d1, d0, d17, d16 - vadd.u8 d1, d1, d5 - paeth d2, d1, d18, d17 - vadd.u8 d2, d2, d6 - paeth d3, d2, d19, d18 - vmov d20, d19 - vadd.u8 d3, d3, d7 - vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! - subs r12, r12, #16 - bgt 1b - - bx lr -endfunc - -func png_read_filter_row_paeth3_neon, export=1 - push {r4,lr} - ldr r12, [r0, #4] @ rowbytes - vmov.i8 d3, #0 - vmov.i8 d4, #0 - mov r0, r1 - mov r4, #3 - mov lr, #12 - vld1.8 {q11}, [r0], lr -1: - vld1.8 {q10}, [r2], lr - paeth d0, d3, d20, d4 - vext.8 d5, d22, d23, #3 - vadd.u8 d0, d0, d22 - vext.8 d17, d20, d21, #3 - paeth d1, d0, d17, d20 - vst1.32 {d0[0]}, [r1,:32], r4 - vext.8 d6, d22, d23, #6 - vadd.u8 d1, d1, d5 - vext.8 d18, d20, d21, #6 - paeth d2, d1, d18, d17 - vext.8 d7, d23, d23, #1 - vld1.8 {q11}, [r0], lr - vst1.32 {d1[0]}, [r1], r4 - vadd.u8 d2, d2, d6 - vext.8 d19, d21, d21, #1 - paeth d3, d2, d19, d18 - vst1.32 {d2[0]}, [r1], r4 - vmov d4, d19 - vadd.u8 d3, d3, d7 - vst1.32 {d3[0]}, [r1], r4 - subs r12, r12, #12 - bgt 1b - - pop {r4,pc} -endfunc -#endif /* PNG_ARM_NEON_OPT > 0 */ -#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */ -#endif /* READ */ diff --git a/extern/libpng/arm/filter_neon_intrinsics.c b/extern/libpng/arm/filter_neon_intrinsics.c deleted file mode 100644 index 553c0be21..000000000 --- a/extern/libpng/arm/filter_neon_intrinsics.c +++ /dev/null @@ -1,402 +0,0 @@ - -/* filter_neon_intrinsics.c - NEON optimised filter functions - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 2014,2016 Glenn Randers-Pehrson - * Written by James Yu , October 2013. - * Based on filter_neon.S, written by Mans Rullgard, 2011. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "../pngpriv.h" - -#ifdef PNG_READ_SUPPORTED - -/* This code requires -mfpu=neon on the command line: */ -#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */ - -#if defined(_MSC_VER) && defined(_M_ARM64) -# include -#else -# include -#endif - -/* libpng row pointers are not necessarily aligned to any particular boundary, - * however this code will only work with appropriate alignment. arm/arm_init.c - * checks for this (and will not compile unless it is done). This code uses - * variants of png_aligncast to avoid compiler warnings. - */ -#define png_ptr(type,pointer) png_aligncast(type *,pointer) -#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer) - -/* The following relies on a variable 'temp_pointer' being declared with type - * 'type'. This is written this way just to hide the GCC strict aliasing - * warning; note that the code is safe because there never is an alias between - * the input and output pointers. - * - * When compiling with MSVC ARM64, the png_ldr macro can't be passed directly - * to vst4_lane_u32, because of an internal compiler error inside MSVC. - * To avoid this compiler bug, we use a temporary variable (vdest_val) to store - * the result of png_ldr. - */ -#define png_ldr(type,pointer)\ - (temp_pointer = png_ptr(type,pointer), *temp_pointer) - -#if PNG_ARM_NEON_OPT > 0 - -void -png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - png_const_bytep pp = prev_row; - - png_debug(1, "in png_read_filter_row_up_neon"); - - for (; rp < rp_stop; rp += 16, pp += 16) - { - uint8x16_t qrp, qpp; - - qrp = vld1q_u8(rp); - qpp = vld1q_u8(pp); - qrp = vaddq_u8(qrp, qpp); - vst1q_u8(rp, qrp); - } -} - -void -png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - - uint8x16_t vtmp = vld1q_u8(rp); - uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp); - uint8x8x2_t vrp = *vrpt; - - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - png_debug(1, "in png_read_filter_row_sub3_neon"); - - for (; rp < rp_stop;) - { - uint8x8_t vtmp1, vtmp2; - uint32x2_t *temp_pointer; - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); - vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); - vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6); - vdest.val[1] = vadd_u8(vdest.val[0], vtmp1); - - vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); - vdest.val[2] = vadd_u8(vdest.val[1], vtmp2); - vdest.val[3] = vadd_u8(vdest.val[2], vtmp1); - - vtmp = vld1q_u8(rp + 12); - vrpt = png_ptr(uint8x8x2_t, &vtmp); - vrp = *vrpt; - - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); - rp += 3; - } - - PNG_UNUSED(prev_row) -} - -void -png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - png_debug(1, "in png_read_filter_row_sub4_neon"); - - for (; rp < rp_stop; rp += 16) - { - uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp)); - uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp); - uint8x8x4_t vrp = *vrpt; - uint32x2x4_t *temp_pointer; - uint32x2x4_t vdest_val; - - vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); - vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]); - vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]); - vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]); - - vdest_val = png_ldr(uint32x2x4_t, &vdest); - vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); - } - - PNG_UNUSED(prev_row) -} - -void -png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_const_bytep pp = prev_row; - png_bytep rp_stop = row + row_info->rowbytes; - - uint8x16_t vtmp; - uint8x8x2_t *vrpt; - uint8x8x2_t vrp; - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - vtmp = vld1q_u8(rp); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - png_debug(1, "in png_read_filter_row_avg3_neon"); - - for (; rp < rp_stop; pp += 12) - { - uint8x8_t vtmp1, vtmp2, vtmp3; - - uint8x8x2_t *vppt; - uint8x8x2_t vpp; - - uint32x2_t *temp_pointer; - - vtmp = vld1q_u8(pp); - vppt = png_ptr(uint8x8x2_t,&vtmp); - vpp = *vppt; - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); - vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - - vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); - vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6); - vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2); - vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); - - vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6); - vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); - - vtmp = vld1q_u8(rp + 12); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2); - vdest.val[2] = vadd_u8(vdest.val[2], vtmp3); - - vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); - - vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2); - vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); - - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); - rp += 3; - } -} - -void -png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - png_const_bytep pp = prev_row; - - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - png_debug(1, "in png_read_filter_row_avg4_neon"); - - for (; rp < rp_stop; rp += 16, pp += 16) - { - uint32x2x4_t vtmp; - uint8x8x4_t *vrpt, *vppt; - uint8x8x4_t vrp, vpp; - uint32x2x4_t *temp_pointer; - uint32x2x4_t vdest_val; - - vtmp = vld4_u32(png_ptr(uint32_t,rp)); - vrpt = png_ptr(uint8x8x4_t,&vtmp); - vrp = *vrpt; - vtmp = vld4_u32(png_ptrc(uint32_t,pp)); - vppt = png_ptr(uint8x8x4_t,&vtmp); - vpp = *vppt; - - vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]); - vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); - vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]); - vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); - vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]); - vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); - - vdest_val = png_ldr(uint32x2x4_t, &vdest); - vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); - } -} - -static uint8x8_t -paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c) -{ - uint8x8_t d, e; - uint16x8_t p1, pa, pb, pc; - - p1 = vaddl_u8(a, b); /* a + b */ - pc = vaddl_u8(c, c); /* c * 2 */ - pa = vabdl_u8(b, c); /* pa */ - pb = vabdl_u8(a, c); /* pb */ - pc = vabdq_u16(p1, pc); /* pc */ - - p1 = vcleq_u16(pa, pb); /* pa <= pb */ - pa = vcleq_u16(pa, pc); /* pa <= pc */ - pb = vcleq_u16(pb, pc); /* pb <= pc */ - - p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */ - - d = vmovn_u16(pb); - e = vmovn_u16(p1); - - d = vbsl_u8(d, b, c); - e = vbsl_u8(e, a, d); - - return e; -} - -void -png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_const_bytep pp = prev_row; - png_bytep rp_stop = row + row_info->rowbytes; - - uint8x16_t vtmp; - uint8x8x2_t *vrpt; - uint8x8x2_t vrp; - uint8x8_t vlast = vdup_n_u8(0); - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - vtmp = vld1q_u8(rp); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - png_debug(1, "in png_read_filter_row_paeth3_neon"); - - for (; rp < rp_stop; pp += 12) - { - uint8x8x2_t *vppt; - uint8x8x2_t vpp; - uint8x8_t vtmp1, vtmp2, vtmp3; - uint32x2_t *temp_pointer; - - vtmp = vld1q_u8(pp); - vppt = png_ptr(uint8x8x2_t,&vtmp); - vpp = *vppt; - - vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); - vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); - vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]); - vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); - - vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6); - vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6); - vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2); - vdest.val[2] = vadd_u8(vdest.val[2], vtmp1); - - vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); - vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); - - vtmp = vld1q_u8(rp + 12); - vrpt = png_ptr(uint8x8x2_t,&vtmp); - vrp = *vrpt; - - vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3); - vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); - - vlast = vtmp2; - - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); - rp += 3; - vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); - rp += 3; - } -} - -void -png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; - png_const_bytep pp = prev_row; - - uint8x8_t vlast = vdup_n_u8(0); - uint8x8x4_t vdest; - vdest.val[3] = vdup_n_u8(0); - - png_debug(1, "in png_read_filter_row_paeth4_neon"); - - for (; rp < rp_stop; rp += 16, pp += 16) - { - uint32x2x4_t vtmp; - uint8x8x4_t *vrpt, *vppt; - uint8x8x4_t vrp, vpp; - uint32x2x4_t *temp_pointer; - uint32x2x4_t vdest_val; - - vtmp = vld4_u32(png_ptr(uint32_t,rp)); - vrpt = png_ptr(uint8x8x4_t,&vtmp); - vrp = *vrpt; - vtmp = vld4_u32(png_ptrc(uint32_t,pp)); - vppt = png_ptr(uint8x8x4_t,&vtmp); - vpp = *vppt; - - vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); - vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); - vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]); - vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); - vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]); - vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); - vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]); - vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); - - vlast = vpp.val[3]; - - vdest_val = png_ldr(uint32x2x4_t, &vdest); - vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); - } -} - -#endif /* PNG_ARM_NEON_OPT > 0 */ -#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */ -#endif /* READ */ diff --git a/extern/libpng/arm/palette_neon_intrinsics.c b/extern/libpng/arm/palette_neon_intrinsics.c deleted file mode 100644 index b4d1fd2ab..000000000 --- a/extern/libpng/arm/palette_neon_intrinsics.c +++ /dev/null @@ -1,149 +0,0 @@ - -/* palette_neon_intrinsics.c - NEON optimised palette expansion functions - * - * Copyright (c) 2018-2019 Cosmin Truta - * Copyright (c) 2017-2018 Arm Holdings. All rights reserved. - * Written by Richard Townsend , February 2017. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "../pngpriv.h" - -#if PNG_ARM_NEON_IMPLEMENTATION == 1 - -#if defined(_MSC_VER) && defined(_M_ARM64) -# include -#else -# include -#endif - -/* Build an RGBA8 palette from the separate RGB and alpha palettes. */ -void -png_riffle_palette_neon(png_structrp png_ptr) -{ - png_const_colorp palette = png_ptr->palette; - png_bytep riffled_palette = png_ptr->riffled_palette; - png_const_bytep trans_alpha = png_ptr->trans_alpha; - int num_trans = png_ptr->num_trans; - int i; - - png_debug(1, "in png_riffle_palette_neon"); - - /* Initially black, opaque. */ - uint8x16x4_t w = {{ - vdupq_n_u8(0x00), - vdupq_n_u8(0x00), - vdupq_n_u8(0x00), - vdupq_n_u8(0xff), - }}; - - /* First, riffle the RGB colours into an RGBA8 palette. - * The alpha component is set to opaque for now. - */ - for (i = 0; i < 256; i += 16) - { - uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i)); - w.val[0] = v.val[0]; - w.val[1] = v.val[1]; - w.val[2] = v.val[2]; - vst4q_u8(riffled_palette + (i << 2), w); - } - - /* Fix up the missing transparency values. */ - for (i = 0; i < num_trans; i++) - riffled_palette[(i << 2) + 3] = trans_alpha[i]; -} - -/* Expands a palettized row into RGBA8. */ -int -png_do_expand_palette_rgba8_neon(png_structrp png_ptr, png_row_infop row_info, - png_const_bytep row, png_bytepp ssp, png_bytepp ddp) -{ - png_uint_32 row_width = row_info->width; - const png_uint_32 *riffled_palette = - (const png_uint_32 *)png_ptr->riffled_palette; - const png_int_32 pixels_per_chunk = 4; - int i; - - png_debug(1, "in png_do_expand_palette_rgba8_neon"); - - if (row_width < pixels_per_chunk) - return 0; - - /* This function originally gets the last byte of the output row. - * The NEON part writes forward from a given position, so we have - * to seek this back by 4 pixels x 4 bytes. - */ - *ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1); - - for (i = 0; i < row_width; i += pixels_per_chunk) - { - uint32x4_t cur; - png_bytep sp = *ssp - i, dp = *ddp - (i << 2); - cur = vld1q_dup_u32 (riffled_palette + *(sp - 3)); - cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1); - cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2); - cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3); - vst1q_u32((void *)dp, cur); - } - if (i != row_width) - { - /* Remove the amount that wasn't processed. */ - i -= pixels_per_chunk; - } - - /* Decrement output pointers. */ - *ssp = *ssp - i; - *ddp = *ddp - (i << 2); - return i; -} - -/* Expands a palettized row into RGB8. */ -int -png_do_expand_palette_rgb8_neon(png_structrp png_ptr, png_row_infop row_info, - png_const_bytep row, png_bytepp ssp, png_bytepp ddp) -{ - png_uint_32 row_width = row_info->width; - png_const_bytep palette = (png_const_bytep)png_ptr->palette; - const png_uint_32 pixels_per_chunk = 8; - int i; - - png_debug(1, "in png_do_expand_palette_rgb8_neon"); - - if (row_width <= pixels_per_chunk) - return 0; - - /* Seeking this back by 8 pixels x 3 bytes. */ - *ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1); - - for (i = 0; i < row_width; i += pixels_per_chunk) - { - uint8x8x3_t cur; - png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i); - cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7))); - cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1); - cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2); - cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3); - cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4); - cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5); - cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6); - cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7); - vst3_u8((void *)dp, cur); - } - - if (i != row_width) - { - /* Remove the amount that wasn't processed. */ - i -= pixels_per_chunk; - } - - /* Decrement output pointers. */ - *ssp = *ssp - i; - *ddp = *ddp - ((i << 1) + i); - return i; -} - -#endif /* PNG_ARM_NEON_IMPLEMENTATION */ diff --git a/extern/libpng/intel/filter_sse2_intrinsics.c b/extern/libpng/intel/filter_sse2_intrinsics.c deleted file mode 100644 index f52aaa800..000000000 --- a/extern/libpng/intel/filter_sse2_intrinsics.c +++ /dev/null @@ -1,391 +0,0 @@ - -/* filter_sse2_intrinsics.c - SSE2 optimized filter functions - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 2016-2017 Glenn Randers-Pehrson - * Written by Mike Klein and Matt Sarett - * Derived from arm/filter_neon_intrinsics.c - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "../pngpriv.h" - -#ifdef PNG_READ_SUPPORTED - -#if PNG_INTEL_SSE_IMPLEMENTATION > 0 - -#include - -/* Functions in this file look at most 3 pixels (a,b,c) to predict the 4th (d). - * They're positioned like this: - * prev: c b - * row: a d - * The Sub filter predicts d=a, Avg d=(a+b)/2, and Paeth predicts d to be - * whichever of a, b, or c is closest to p=a+b-c. - */ - -static __m128i load4(const void* p) { - int tmp; - memcpy(&tmp, p, sizeof(tmp)); - return _mm_cvtsi32_si128(tmp); -} - -static void store4(void* p, __m128i v) { - int tmp = _mm_cvtsi128_si32(v); - memcpy(p, &tmp, sizeof(int)); -} - -static __m128i load3(const void* p) { - png_uint_32 tmp = 0; - memcpy(&tmp, p, 3); - return _mm_cvtsi32_si128(tmp); -} - -static void store3(void* p, __m128i v) { - int tmp = _mm_cvtsi128_si32(v); - memcpy(p, &tmp, 3); -} - -void png_read_filter_row_sub3_sse2(png_row_infop row_info, png_bytep row, - png_const_bytep prev) -{ - /* The Sub filter predicts each pixel as the previous pixel, a. - * There is no pixel to the left of the first pixel. It's encoded directly. - * That works with our main loop if we just say that left pixel was zero. - */ - size_t rb; - - __m128i a, d = _mm_setzero_si128(); - - png_debug(1, "in png_read_filter_row_sub3_sse2"); - - rb = row_info->rowbytes; - while (rb >= 4) { - a = d; d = load4(row); - d = _mm_add_epi8(d, a); - store3(row, d); - - row += 3; - rb -= 3; - } - if (rb > 0) { - a = d; d = load3(row); - d = _mm_add_epi8(d, a); - store3(row, d); - - row += 3; - rb -= 3; - } - PNG_UNUSED(prev) -} - -void png_read_filter_row_sub4_sse2(png_row_infop row_info, png_bytep row, - png_const_bytep prev) -{ - /* The Sub filter predicts each pixel as the previous pixel, a. - * There is no pixel to the left of the first pixel. It's encoded directly. - * That works with our main loop if we just say that left pixel was zero. - */ - size_t rb; - - __m128i a, d = _mm_setzero_si128(); - - png_debug(1, "in png_read_filter_row_sub4_sse2"); - - rb = row_info->rowbytes+4; - while (rb > 4) { - a = d; d = load4(row); - d = _mm_add_epi8(d, a); - store4(row, d); - - row += 4; - rb -= 4; - } - PNG_UNUSED(prev) -} - -void png_read_filter_row_avg3_sse2(png_row_infop row_info, png_bytep row, - png_const_bytep prev) -{ - /* The Avg filter predicts each pixel as the (truncated) average of a and b. - * There's no pixel to the left of the first pixel. Luckily, it's - * predicted to be half of the pixel above it. So again, this works - * perfectly with our loop if we make sure a starts at zero. - */ - - size_t rb; - - const __m128i zero = _mm_setzero_si128(); - - __m128i b; - __m128i a, d = zero; - - png_debug(1, "in png_read_filter_row_avg3_sse2"); - rb = row_info->rowbytes; - while (rb >= 4) { - __m128i avg; - b = load4(prev); - a = d; d = load4(row ); - - /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */ - avg = _mm_avg_epu8(a,b); - /* ...but we can fix it up by subtracting off 1 if it rounded up. */ - avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b), - _mm_set1_epi8(1))); - d = _mm_add_epi8(d, avg); - store3(row, d); - - prev += 3; - row += 3; - rb -= 3; - } - if (rb > 0) { - __m128i avg; - b = load3(prev); - a = d; d = load3(row ); - - /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */ - avg = _mm_avg_epu8(a,b); - /* ...but we can fix it up by subtracting off 1 if it rounded up. */ - avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b), - _mm_set1_epi8(1))); - - d = _mm_add_epi8(d, avg); - store3(row, d); - - prev += 3; - row += 3; - rb -= 3; - } -} - -void png_read_filter_row_avg4_sse2(png_row_infop row_info, png_bytep row, - png_const_bytep prev) -{ - /* The Avg filter predicts each pixel as the (truncated) average of a and b. - * There's no pixel to the left of the first pixel. Luckily, it's - * predicted to be half of the pixel above it. So again, this works - * perfectly with our loop if we make sure a starts at zero. - */ - size_t rb; - const __m128i zero = _mm_setzero_si128(); - __m128i b; - __m128i a, d = zero; - - png_debug(1, "in png_read_filter_row_avg4_sse2"); - - rb = row_info->rowbytes+4; - while (rb > 4) { - __m128i avg; - b = load4(prev); - a = d; d = load4(row ); - - /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */ - avg = _mm_avg_epu8(a,b); - /* ...but we can fix it up by subtracting off 1 if it rounded up. */ - avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b), - _mm_set1_epi8(1))); - - d = _mm_add_epi8(d, avg); - store4(row, d); - - prev += 4; - row += 4; - rb -= 4; - } -} - -/* Returns |x| for 16-bit lanes. */ -static __m128i abs_i16(__m128i x) { -#if PNG_INTEL_SSE_IMPLEMENTATION >= 2 - return _mm_abs_epi16(x); -#else - /* Read this all as, return x<0 ? -x : x. - * To negate two's complement, you flip all the bits then add 1. - */ - __m128i is_negative = _mm_cmplt_epi16(x, _mm_setzero_si128()); - - /* Flip negative lanes. */ - x = _mm_xor_si128(x, is_negative); - - /* +1 to negative lanes, else +0. */ - x = _mm_sub_epi16(x, is_negative); - return x; -#endif -} - -/* Bytewise c ? t : e. */ -static __m128i if_then_else(__m128i c, __m128i t, __m128i e) { -#if PNG_INTEL_SSE_IMPLEMENTATION >= 3 - return _mm_blendv_epi8(e,t,c); -#else - return _mm_or_si128(_mm_and_si128(c, t), _mm_andnot_si128(c, e)); -#endif -} - -void png_read_filter_row_paeth3_sse2(png_row_infop row_info, png_bytep row, - png_const_bytep prev) -{ - /* Paeth tries to predict pixel d using the pixel to the left of it, a, - * and two pixels from the previous row, b and c: - * prev: c b - * row: a d - * The Paeth function predicts d to be whichever of a, b, or c is nearest to - * p=a+b-c. - * - * The first pixel has no left context, and so uses an Up filter, p = b. - * This works naturally with our main loop's p = a+b-c if we force a and c - * to zero. - * Here we zero b and d, which become c and a respectively at the start of - * the loop. - */ - size_t rb; - const __m128i zero = _mm_setzero_si128(); - __m128i c, b = zero, - a, d = zero; - - png_debug(1, "in png_read_filter_row_paeth3_sse2"); - - rb = row_info->rowbytes; - while (rb >= 4) { - /* It's easiest to do this math (particularly, deal with pc) with 16-bit - * intermediates. - */ - __m128i pa,pb,pc,smallest,nearest; - c = b; b = _mm_unpacklo_epi8(load4(prev), zero); - a = d; d = _mm_unpacklo_epi8(load4(row ), zero); - - /* (p-a) == (a+b-c - a) == (b-c) */ - - pa = _mm_sub_epi16(b,c); - - /* (p-b) == (a+b-c - b) == (a-c) */ - pb = _mm_sub_epi16(a,c); - - /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */ - pc = _mm_add_epi16(pa,pb); - - pa = abs_i16(pa); /* |p-a| */ - pb = abs_i16(pb); /* |p-b| */ - pc = abs_i16(pc); /* |p-c| */ - - smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb)); - - /* Paeth breaks ties favoring a over b over c. */ - nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a, - if_then_else(_mm_cmpeq_epi16(smallest, pb), b, - c)); - - /* Note `_epi8`: we need addition to wrap modulo 255. */ - d = _mm_add_epi8(d, nearest); - store3(row, _mm_packus_epi16(d,d)); - - prev += 3; - row += 3; - rb -= 3; - } - if (rb > 0) { - /* It's easiest to do this math (particularly, deal with pc) with 16-bit - * intermediates. - */ - __m128i pa,pb,pc,smallest,nearest; - c = b; b = _mm_unpacklo_epi8(load3(prev), zero); - a = d; d = _mm_unpacklo_epi8(load3(row ), zero); - - /* (p-a) == (a+b-c - a) == (b-c) */ - pa = _mm_sub_epi16(b,c); - - /* (p-b) == (a+b-c - b) == (a-c) */ - pb = _mm_sub_epi16(a,c); - - /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */ - pc = _mm_add_epi16(pa,pb); - - pa = abs_i16(pa); /* |p-a| */ - pb = abs_i16(pb); /* |p-b| */ - pc = abs_i16(pc); /* |p-c| */ - - smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb)); - - /* Paeth breaks ties favoring a over b over c. */ - nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a, - if_then_else(_mm_cmpeq_epi16(smallest, pb), b, - c)); - - /* Note `_epi8`: we need addition to wrap modulo 255. */ - d = _mm_add_epi8(d, nearest); - store3(row, _mm_packus_epi16(d,d)); - - prev += 3; - row += 3; - rb -= 3; - } -} - -void png_read_filter_row_paeth4_sse2(png_row_infop row_info, png_bytep row, - png_const_bytep prev) -{ - /* Paeth tries to predict pixel d using the pixel to the left of it, a, - * and two pixels from the previous row, b and c: - * prev: c b - * row: a d - * The Paeth function predicts d to be whichever of a, b, or c is nearest to - * p=a+b-c. - * - * The first pixel has no left context, and so uses an Up filter, p = b. - * This works naturally with our main loop's p = a+b-c if we force a and c - * to zero. - * Here we zero b and d, which become c and a respectively at the start of - * the loop. - */ - size_t rb; - const __m128i zero = _mm_setzero_si128(); - __m128i pa,pb,pc,smallest,nearest; - __m128i c, b = zero, - a, d = zero; - - png_debug(1, "in png_read_filter_row_paeth4_sse2"); - - rb = row_info->rowbytes+4; - while (rb > 4) { - /* It's easiest to do this math (particularly, deal with pc) with 16-bit - * intermediates. - */ - c = b; b = _mm_unpacklo_epi8(load4(prev), zero); - a = d; d = _mm_unpacklo_epi8(load4(row ), zero); - - /* (p-a) == (a+b-c - a) == (b-c) */ - pa = _mm_sub_epi16(b,c); - - /* (p-b) == (a+b-c - b) == (a-c) */ - pb = _mm_sub_epi16(a,c); - - /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */ - pc = _mm_add_epi16(pa,pb); - - pa = abs_i16(pa); /* |p-a| */ - pb = abs_i16(pb); /* |p-b| */ - pc = abs_i16(pc); /* |p-c| */ - - smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb)); - - /* Paeth breaks ties favoring a over b over c. */ - nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a, - if_then_else(_mm_cmpeq_epi16(smallest, pb), b, - c)); - - /* Note `_epi8`: we need addition to wrap modulo 255. */ - d = _mm_add_epi8(d, nearest); - store4(row, _mm_packus_epi16(d,d)); - - prev += 4; - row += 4; - rb -= 4; - } -} - -#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */ -#endif /* READ */ diff --git a/extern/libpng/intel/intel_init.c b/extern/libpng/intel/intel_init.c deleted file mode 100644 index 2f8168b7c..000000000 --- a/extern/libpng/intel/intel_init.c +++ /dev/null @@ -1,52 +0,0 @@ - -/* intel_init.c - SSE2 optimized filter functions - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 2016-2017 Glenn Randers-Pehrson - * Written by Mike Klein and Matt Sarett, Google, Inc. - * Derived from arm/arm_init.c - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "../pngpriv.h" - -#ifdef PNG_READ_SUPPORTED -#if PNG_INTEL_SSE_IMPLEMENTATION > 0 - -void -png_init_filter_functions_sse2(png_structp pp, unsigned int bpp) -{ - /* The techniques used to implement each of these filters in SSE operate on - * one pixel at a time. - * So they generally speed up 3bpp images about 3x, 4bpp images about 4x. - * They can scale up to 6 and 8 bpp images and down to 2 bpp images, - * but they'd not likely have any benefit for 1bpp images. - * Most of these can be implemented using only MMX and 64-bit registers, - * but they end up a bit slower than using the equally-ubiquitous SSE2. - */ - png_debug(1, "in png_init_filter_functions_sse2"); - if (bpp == 3) - { - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_sse2; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_sse2; - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth3_sse2; - } - else if (bpp == 4) - { - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_sse2; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_sse2; - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth4_sse2; - } - - /* No need optimize PNG_FILTER_VALUE_UP. The compiler should - * autovectorize. - */ -} - -#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */ -#endif /* PNG_READ_SUPPORTED */ diff --git a/extern/libpng/png.c b/extern/libpng/png.c deleted file mode 100644 index 757c755f9..000000000 --- a/extern/libpng/png.c +++ /dev/null @@ -1,4607 +0,0 @@ - -/* png.c - location for general purpose libpng functions - * - * Copyright (c) 2018-2019 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -/* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_37 Your_png_h_is_not_version_1_6_37; - -#ifdef __GNUC__ -/* The version tests may need to be added to, but the problem warning has - * consistently been fixed in GCC versions which obtain wide-spread release. - * The problem is that many versions of GCC rearrange comparison expressions in - * the optimizer in such a way that the results of the comparison will change - * if signed integer overflow occurs. Such comparisons are not permitted in - * ANSI C90, however GCC isn't clever enough to work out that that do not occur - * below in png_ascii_from_fp and png_muldiv, so it produces a warning with - * -Wextra. Unfortunately this is highly dependent on the optimizer and the - * machine architecture so the warning comes and goes unpredictably and is - * impossible to "fix", even were that a good idea. - */ -#if __GNUC__ == 7 && __GNUC_MINOR__ == 1 -#define GCC_STRICT_OVERFLOW 1 -#endif /* GNU 7.1.x */ -#endif /* GNU */ -#ifndef GCC_STRICT_OVERFLOW -#define GCC_STRICT_OVERFLOW 0 -#endif - -/* Tells libpng that we have already handled the first "num_bytes" bytes - * of the PNG file signature. If the PNG data is embedded into another - * stream we can set num_bytes = 8 so that libpng will not attempt to read - * or write any of the magic bytes before it starts on the IHDR. - */ - -#ifdef PNG_READ_SUPPORTED -void PNGAPI -png_set_sig_bytes(png_structrp png_ptr, int num_bytes) -{ - unsigned int nb = (unsigned int)num_bytes; - - png_debug(1, "in png_set_sig_bytes"); - - if (png_ptr == NULL) - return; - - if (num_bytes < 0) - nb = 0; - - if (nb > 8) - png_error(png_ptr, "Too many bytes for PNG signature"); - - png_ptr->sig_bytes = (png_byte)nb; -} - -/* Checks whether the supplied bytes match the PNG signature. We allow - * checking less than the full 8-byte signature so that those apps that - * already read the first few bytes of a file to determine the file type - * can simply check the remaining bytes for extra assurance. Returns - * an integer less than, equal to, or greater than zero if sig is found, - * respectively, to be less than, to match, or be greater than the correct - * PNG signature (this is the same behavior as strcmp, memcmp, etc). - */ -int PNGAPI -png_sig_cmp(png_const_bytep sig, size_t start, size_t num_to_check) -{ - png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - - if (num_to_check > 8) - num_to_check = 8; - - else if (num_to_check < 1) - return (-1); - - if (start > 7) - return (-1); - - if (start + num_to_check > 8) - num_to_check = 8 - start; - - return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check))); -} - -#endif /* READ */ - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -/* Function to allocate memory for zlib */ -PNG_FUNCTION(voidpf /* PRIVATE */, -png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED) -{ - png_alloc_size_t num_bytes = size; - - if (png_ptr == NULL) - return NULL; - - if (items >= (~(png_alloc_size_t)0)/size) - { - png_warning (png_voidcast(png_structrp, png_ptr), - "Potential overflow in png_zalloc()"); - return NULL; - } - - num_bytes *= items; - return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes); -} - -/* Function to free memory for zlib */ -void /* PRIVATE */ -png_zfree(voidpf png_ptr, voidpf ptr) -{ - png_free(png_voidcast(png_const_structrp,png_ptr), ptr); -} - -/* Reset the CRC variable to 32 bits of 1's. Care must be taken - * in case CRC is > 32 bits to leave the top bits 0. - */ -void /* PRIVATE */ -png_reset_crc(png_structrp png_ptr) -{ - /* The cast is safe because the crc is a 32-bit value. */ - png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0); -} - -/* Calculate the CRC over a section of data. We can only pass as - * much data to this routine as the largest single buffer size. We - * also check that this data will actually be used before going to the - * trouble of calculating it. - */ -void /* PRIVATE */ -png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, size_t length) -{ - int need_crc = 1; - - if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) - { - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == - (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) - need_crc = 0; - } - - else /* critical */ - { - if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) - need_crc = 0; - } - - /* 'uLong' is defined in zlib.h as unsigned long; this means that on some - * systems it is a 64-bit value. crc32, however, returns 32 bits so the - * following cast is safe. 'uInt' may be no more than 16 bits, so it is - * necessary to perform a loop here. - */ - if (need_crc != 0 && length > 0) - { - uLong crc = png_ptr->crc; /* Should never issue a warning */ - - do - { - uInt safe_length = (uInt)length; -#ifndef __COVERITY__ - if (safe_length == 0) - safe_length = (uInt)-1; /* evil, but safe */ -#endif - - crc = crc32(crc, ptr, safe_length); - - /* The following should never issue compiler warnings; if they do the - * target system has characteristics that will probably violate other - * assumptions within the libpng code. - */ - ptr += safe_length; - length -= safe_length; - } - while (length > 0); - - /* And the following is always safe because the crc is only 32 bits. */ - png_ptr->crc = (png_uint_32)crc; - } -} - -/* Check a user supplied version number, called from both read and write - * functions that create a png_struct. - */ -int -png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver) -{ - /* Libpng versions 1.0.0 and later are binary compatible if the version - * string matches through the second '.'; we must recompile any - * applications that use any older library version. - */ - - if (user_png_ver != NULL) - { - int i = -1; - int found_dots = 0; - - do - { - i++; - if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i]) - png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; - if (user_png_ver[i] == '.') - found_dots++; - } while (found_dots < 2 && user_png_ver[i] != 0 && - PNG_LIBPNG_VER_STRING[i] != 0); - } - - else - png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; - - if ((png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) != 0) - { -#ifdef PNG_WARNINGS_SUPPORTED - size_t pos = 0; - char m[128]; - - pos = png_safecat(m, (sizeof m), pos, - "Application built with libpng-"); - pos = png_safecat(m, (sizeof m), pos, user_png_ver); - pos = png_safecat(m, (sizeof m), pos, " but running with "); - pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING); - PNG_UNUSED(pos) - - png_warning(png_ptr, m); -#endif - -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - png_ptr->flags = 0; -#endif - - return 0; - } - - /* Success return. */ - return 1; -} - -/* Generic function to create a png_struct for either read or write - this - * contains the common initialization. - */ -PNG_FUNCTION(png_structp /* PRIVATE */, -png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) -{ - png_struct create_struct; -# ifdef PNG_SETJMP_SUPPORTED - jmp_buf create_jmp_buf; -# endif - - /* This temporary stack-allocated structure is used to provide a place to - * build enough context to allow the user provided memory allocator (if any) - * to be called. - */ - memset(&create_struct, 0, (sizeof create_struct)); - - /* Added at libpng-1.2.6 */ -# ifdef PNG_USER_LIMITS_SUPPORTED - create_struct.user_width_max = PNG_USER_WIDTH_MAX; - create_struct.user_height_max = PNG_USER_HEIGHT_MAX; - -# ifdef PNG_USER_CHUNK_CACHE_MAX - /* Added at libpng-1.2.43 and 1.4.0 */ - create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; -# endif - -# ifdef PNG_USER_CHUNK_MALLOC_MAX - /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists - * in png_struct regardless. - */ - create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; -# endif -# endif - - /* The following two API calls simply set fields in png_struct, so it is safe - * to do them now even though error handling is not yet set up. - */ -# ifdef PNG_USER_MEM_SUPPORTED - png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn); -# else - PNG_UNUSED(mem_ptr) - PNG_UNUSED(malloc_fn) - PNG_UNUSED(free_fn) -# endif - - /* (*error_fn) can return control to the caller after the error_ptr is set, - * this will result in a memory leak unless the error_fn does something - * extremely sophisticated. The design lacks merit but is implicit in the - * API. - */ - png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn); - -# ifdef PNG_SETJMP_SUPPORTED - if (!setjmp(create_jmp_buf)) -# endif - { -# ifdef PNG_SETJMP_SUPPORTED - /* Temporarily fake out the longjmp information until we have - * successfully completed this function. This only works if we have - * setjmp() support compiled in, but it is safe - this stuff should - * never happen. - */ - create_struct.jmp_buf_ptr = &create_jmp_buf; - create_struct.jmp_buf_size = 0; /*stack allocation*/ - create_struct.longjmp_fn = longjmp; -# endif - /* Call the general version checker (shared with read and write code): - */ - if (png_user_version_check(&create_struct, user_png_ver) != 0) - { - png_structrp png_ptr = png_voidcast(png_structrp, - png_malloc_warn(&create_struct, (sizeof *png_ptr))); - - if (png_ptr != NULL) - { - /* png_ptr->zstream holds a back-pointer to the png_struct, so - * this can only be done now: - */ - create_struct.zstream.zalloc = png_zalloc; - create_struct.zstream.zfree = png_zfree; - create_struct.zstream.opaque = png_ptr; - -# ifdef PNG_SETJMP_SUPPORTED - /* Eliminate the local error handling: */ - create_struct.jmp_buf_ptr = NULL; - create_struct.jmp_buf_size = 0; - create_struct.longjmp_fn = 0; -# endif - - *png_ptr = create_struct; - - /* This is the successful return point */ - return png_ptr; - } - } - } - - /* A longjmp because of a bug in the application storage allocator or a - * simple failure to allocate the png_struct. - */ - return NULL; -} - -/* Allocate the memory for an info_struct for the application. */ -PNG_FUNCTION(png_infop,PNGAPI -png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED) -{ - png_inforp info_ptr; - - png_debug(1, "in png_create_info_struct"); - - if (png_ptr == NULL) - return NULL; - - /* Use the internal API that does not (or at least should not) error out, so - * that this call always returns ok. The application typically sets up the - * error handling *after* creating the info_struct because this is the way it - * has always been done in 'example.c'. - */ - info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr, - (sizeof *info_ptr))); - - if (info_ptr != NULL) - memset(info_ptr, 0, (sizeof *info_ptr)); - - return info_ptr; -} - -/* This function frees the memory associated with a single info struct. - * Normally, one would use either png_destroy_read_struct() or - * png_destroy_write_struct() to free an info struct, but this may be - * useful for some applications. From libpng 1.6.0 this function is also used - * internally to implement the png_info release part of the 'struct' destroy - * APIs. This ensures that all possible approaches free the same data (all of - * it). - */ -void PNGAPI -png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr) -{ - png_inforp info_ptr = NULL; - - png_debug(1, "in png_destroy_info_struct"); - - if (png_ptr == NULL) - return; - - if (info_ptr_ptr != NULL) - info_ptr = *info_ptr_ptr; - - if (info_ptr != NULL) - { - /* Do this first in case of an error below; if the app implements its own - * memory management this can lead to png_free calling png_error, which - * will abort this routine and return control to the app error handler. - * An infinite loop may result if it then tries to free the same info - * ptr. - */ - *info_ptr_ptr = NULL; - - png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); - memset(info_ptr, 0, (sizeof *info_ptr)); - png_free(png_ptr, info_ptr); - } -} - -/* Initialize the info structure. This is now an internal function (0.89) - * and applications using it are urged to use png_create_info_struct() - * instead. Use deprecated in 1.6.0, internal use removed (used internally it - * is just a memset). - * - * NOTE: it is almost inconceivable that this API is used because it bypasses - * the user-memory mechanism and the user error handling/warning mechanisms in - * those cases where it does anything other than a memset. - */ -PNG_FUNCTION(void,PNGAPI -png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size), - PNG_DEPRECATED) -{ - png_inforp info_ptr = *ptr_ptr; - - png_debug(1, "in png_info_init_3"); - - if (info_ptr == NULL) - return; - - if ((sizeof (png_info)) > png_info_struct_size) - { - *ptr_ptr = NULL; - /* The following line is why this API should not be used: */ - free(info_ptr); - info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL, - (sizeof *info_ptr))); - if (info_ptr == NULL) - return; - *ptr_ptr = info_ptr; - } - - /* Set everything to 0 */ - memset(info_ptr, 0, (sizeof *info_ptr)); -} - -/* The following API is not called internally */ -void PNGAPI -png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr, - int freer, png_uint_32 mask) -{ - png_debug(1, "in png_data_freer"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (freer == PNG_DESTROY_WILL_FREE_DATA) - info_ptr->free_me |= mask; - - else if (freer == PNG_USER_WILL_FREE_DATA) - info_ptr->free_me &= ~mask; - - else - png_error(png_ptr, "Unknown freer parameter in png_data_freer"); -} - -void PNGAPI -png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask, - int num) -{ - png_debug(1, "in png_free_data"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - -#ifdef PNG_TEXT_SUPPORTED - /* Free text item num or (if num == -1) all text items */ - if (info_ptr->text != NULL && - ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0) - { - if (num != -1) - { - png_free(png_ptr, info_ptr->text[num].key); - info_ptr->text[num].key = NULL; - } - - else - { - int i; - - for (i = 0; i < info_ptr->num_text; i++) - png_free(png_ptr, info_ptr->text[i].key); - - png_free(png_ptr, info_ptr->text); - info_ptr->text = NULL; - info_ptr->num_text = 0; - info_ptr->max_text = 0; - } - } -#endif - -#ifdef PNG_tRNS_SUPPORTED - /* Free any tRNS entry */ - if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0) - { - info_ptr->valid &= ~PNG_INFO_tRNS; - png_free(png_ptr, info_ptr->trans_alpha); - info_ptr->trans_alpha = NULL; - info_ptr->num_trans = 0; - } -#endif - -#ifdef PNG_sCAL_SUPPORTED - /* Free any sCAL entry */ - if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->scal_s_width); - png_free(png_ptr, info_ptr->scal_s_height); - info_ptr->scal_s_width = NULL; - info_ptr->scal_s_height = NULL; - info_ptr->valid &= ~PNG_INFO_sCAL; - } -#endif - -#ifdef PNG_pCAL_SUPPORTED - /* Free any pCAL entry */ - if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->pcal_purpose); - png_free(png_ptr, info_ptr->pcal_units); - info_ptr->pcal_purpose = NULL; - info_ptr->pcal_units = NULL; - - if (info_ptr->pcal_params != NULL) - { - int i; - - for (i = 0; i < info_ptr->pcal_nparams; i++) - png_free(png_ptr, info_ptr->pcal_params[i]); - - png_free(png_ptr, info_ptr->pcal_params); - info_ptr->pcal_params = NULL; - } - info_ptr->valid &= ~PNG_INFO_pCAL; - } -#endif - -#ifdef PNG_iCCP_SUPPORTED - /* Free any profile entry */ - if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->iccp_name); - png_free(png_ptr, info_ptr->iccp_profile); - info_ptr->iccp_name = NULL; - info_ptr->iccp_profile = NULL; - info_ptr->valid &= ~PNG_INFO_iCCP; - } -#endif - -#ifdef PNG_sPLT_SUPPORTED - /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ - if (info_ptr->splt_palettes != NULL && - ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0) - { - if (num != -1) - { - png_free(png_ptr, info_ptr->splt_palettes[num].name); - png_free(png_ptr, info_ptr->splt_palettes[num].entries); - info_ptr->splt_palettes[num].name = NULL; - info_ptr->splt_palettes[num].entries = NULL; - } - - else - { - int i; - - for (i = 0; i < info_ptr->splt_palettes_num; i++) - { - png_free(png_ptr, info_ptr->splt_palettes[i].name); - png_free(png_ptr, info_ptr->splt_palettes[i].entries); - } - - png_free(png_ptr, info_ptr->splt_palettes); - info_ptr->splt_palettes = NULL; - info_ptr->splt_palettes_num = 0; - info_ptr->valid &= ~PNG_INFO_sPLT; - } - } -#endif - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED - if (info_ptr->unknown_chunks != NULL && - ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0) - { - if (num != -1) - { - png_free(png_ptr, info_ptr->unknown_chunks[num].data); - info_ptr->unknown_chunks[num].data = NULL; - } - - else - { - int i; - - for (i = 0; i < info_ptr->unknown_chunks_num; i++) - png_free(png_ptr, info_ptr->unknown_chunks[i].data); - - png_free(png_ptr, info_ptr->unknown_chunks); - info_ptr->unknown_chunks = NULL; - info_ptr->unknown_chunks_num = 0; - } - } -#endif - -#ifdef PNG_eXIf_SUPPORTED - /* Free any eXIf entry */ - if (((mask & PNG_FREE_EXIF) & info_ptr->free_me) != 0) - { -# ifdef PNG_READ_eXIf_SUPPORTED - if (info_ptr->eXIf_buf) - { - png_free(png_ptr, info_ptr->eXIf_buf); - info_ptr->eXIf_buf = NULL; - } -# endif - if (info_ptr->exif) - { - png_free(png_ptr, info_ptr->exif); - info_ptr->exif = NULL; - } - info_ptr->valid &= ~PNG_INFO_eXIf; - } -#endif - -#ifdef PNG_hIST_SUPPORTED - /* Free any hIST entry */ - if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->hist); - info_ptr->hist = NULL; - info_ptr->valid &= ~PNG_INFO_hIST; - } -#endif - - /* Free any PLTE entry that was internally allocated */ - if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0) - { - png_free(png_ptr, info_ptr->palette); - info_ptr->palette = NULL; - info_ptr->valid &= ~PNG_INFO_PLTE; - info_ptr->num_palette = 0; - } - -#ifdef PNG_INFO_IMAGE_SUPPORTED - /* Free any image bits attached to the info structure */ - if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0) - { - if (info_ptr->row_pointers != NULL) - { - png_uint_32 row; - for (row = 0; row < info_ptr->height; row++) - png_free(png_ptr, info_ptr->row_pointers[row]); - - png_free(png_ptr, info_ptr->row_pointers); - info_ptr->row_pointers = NULL; - } - info_ptr->valid &= ~PNG_INFO_IDAT; - } -#endif - - if (num != -1) - mask &= ~PNG_FREE_MUL; - - info_ptr->free_me &= ~mask; -} -#endif /* READ || WRITE */ - -/* This function returns a pointer to the io_ptr associated with the user - * functions. The application should free any memory associated with this - * pointer before png_write_destroy() or png_read_destroy() are called. - */ -png_voidp PNGAPI -png_get_io_ptr(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return (NULL); - - return (png_ptr->io_ptr); -} - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -# ifdef PNG_STDIO_SUPPORTED -/* Initialize the default input/output functions for the PNG file. If you - * use your own read or write routines, you can call either png_set_read_fn() - * or png_set_write_fn() instead of png_init_io(). If you have defined - * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a - * function of your own because "FILE *" isn't necessarily available. - */ -void PNGAPI -png_init_io(png_structrp png_ptr, png_FILE_p fp) -{ - png_debug(1, "in png_init_io"); - - if (png_ptr == NULL) - return; - - png_ptr->io_ptr = (png_voidp)fp; -} -# endif - -# ifdef PNG_SAVE_INT_32_SUPPORTED -/* PNG signed integers are saved in 32-bit 2's complement format. ANSI C-90 - * defines a cast of a signed integer to an unsigned integer either to preserve - * the value, if it is positive, or to calculate: - * - * (UNSIGNED_MAX+1) + integer - * - * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the - * negative integral value is added the result will be an unsigned value - * correspnding to the 2's complement representation. - */ -void PNGAPI -png_save_int_32(png_bytep buf, png_int_32 i) -{ - png_save_uint_32(buf, (png_uint_32)i); -} -# endif - -# ifdef PNG_TIME_RFC1123_SUPPORTED -/* Convert the supplied time into an RFC 1123 string suitable for use in - * a "Creation Time" or other text-based time string. - */ -int PNGAPI -png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime) -{ - static const char short_months[12][4] = - {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - - if (out == NULL) - return 0; - - if (ptime->year > 9999 /* RFC1123 limitation */ || - ptime->month == 0 || ptime->month > 12 || - ptime->day == 0 || ptime->day > 31 || - ptime->hour > 23 || ptime->minute > 59 || - ptime->second > 60) - return 0; - - { - size_t pos = 0; - char number_buf[5]; /* enough for a four-digit year */ - -# define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string)) -# define APPEND_NUMBER(format, value)\ - APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value))) -# define APPEND(ch) if (pos < 28) out[pos++] = (ch) - - APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day); - APPEND(' '); - APPEND_STRING(short_months[(ptime->month - 1)]); - APPEND(' '); - APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year); - APPEND(' '); - APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour); - APPEND(':'); - APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute); - APPEND(':'); - APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second); - APPEND_STRING(" +0000"); /* This reliably terminates the buffer */ - PNG_UNUSED (pos) - -# undef APPEND -# undef APPEND_NUMBER -# undef APPEND_STRING - } - - return 1; -} - -# if PNG_LIBPNG_VER < 10700 -/* To do: remove the following from libpng-1.7 */ -/* Original API that uses a private buffer in png_struct. - * Deprecated because it causes png_struct to carry a spurious temporary - * buffer (png_struct::time_buffer), better to have the caller pass this in. - */ -png_const_charp PNGAPI -png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime) -{ - if (png_ptr != NULL) - { - /* The only failure above if png_ptr != NULL is from an invalid ptime */ - if (png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime) == 0) - png_warning(png_ptr, "Ignoring invalid time value"); - - else - return png_ptr->time_buffer; - } - - return NULL; -} -# endif /* LIBPNG_VER < 10700 */ -# endif /* TIME_RFC1123 */ - -#endif /* READ || WRITE */ - -png_const_charp PNGAPI -png_get_copyright(png_const_structrp png_ptr) -{ - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ -#ifdef PNG_STRING_COPYRIGHT - return PNG_STRING_COPYRIGHT -#else - return PNG_STRING_NEWLINE \ - "libpng version 1.6.37" PNG_STRING_NEWLINE \ - "Copyright (c) 2018-2019 Cosmin Truta" PNG_STRING_NEWLINE \ - "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ - PNG_STRING_NEWLINE \ - "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ - "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ - PNG_STRING_NEWLINE; -#endif -} - -/* The following return the library version as a short string in the - * format 1.0.0 through 99.99.99zz. To get the version of *.h files - * used with your application, print out PNG_LIBPNG_VER_STRING, which - * is defined in png.h. - * Note: now there is no difference between png_get_libpng_ver() and - * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard, - * it is guaranteed that png.c uses the correct version of png.h. - */ -png_const_charp PNGAPI -png_get_libpng_ver(png_const_structrp png_ptr) -{ - /* Version of *.c files used when building libpng */ - return png_get_header_ver(png_ptr); -} - -png_const_charp PNGAPI -png_get_header_ver(png_const_structrp png_ptr) -{ - /* Version of *.h files used when building libpng */ - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ - return PNG_LIBPNG_VER_STRING; -} - -png_const_charp PNGAPI -png_get_header_version(png_const_structrp png_ptr) -{ - /* Returns longer string containing both version and date */ - PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ -#ifdef __STDC__ - return PNG_HEADER_VERSION_STRING -# ifndef PNG_READ_SUPPORTED - " (NO READ SUPPORT)" -# endif - PNG_STRING_NEWLINE; -#else - return PNG_HEADER_VERSION_STRING; -#endif -} - -#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED -/* NOTE: this routine is not used internally! */ -/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth - * large of png_color. This lets grayscale images be treated as - * paletted. Most useful for gamma correction and simplification - * of code. This API is not used internally. - */ -void PNGAPI -png_build_grayscale_palette(int bit_depth, png_colorp palette) -{ - int num_palette; - int color_inc; - int i; - int v; - - png_debug(1, "in png_do_build_grayscale_palette"); - - if (palette == NULL) - return; - - switch (bit_depth) - { - case 1: - num_palette = 2; - color_inc = 0xff; - break; - - case 2: - num_palette = 4; - color_inc = 0x55; - break; - - case 4: - num_palette = 16; - color_inc = 0x11; - break; - - case 8: - num_palette = 256; - color_inc = 1; - break; - - default: - num_palette = 0; - color_inc = 0; - break; - } - - for (i = 0, v = 0; i < num_palette; i++, v += color_inc) - { - palette[i].red = (png_byte)(v & 0xff); - palette[i].green = (png_byte)(v & 0xff); - palette[i].blue = (png_byte)(v & 0xff); - } -} -#endif - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -int PNGAPI -png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name) -{ - /* Check chunk_name and return "keep" value if it's on the list, else 0 */ - png_const_bytep p, p_end; - - if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0) - return PNG_HANDLE_CHUNK_AS_DEFAULT; - - p_end = png_ptr->chunk_list; - p = p_end + png_ptr->num_chunk_list*5; /* beyond end */ - - /* The code is the fifth byte after each four byte string. Historically this - * code was always searched from the end of the list, this is no longer - * necessary because the 'set' routine handles duplicate entries correctly. - */ - do /* num_chunk_list > 0, so at least one */ - { - p -= 5; - - if (memcmp(chunk_name, p, 4) == 0) - return p[4]; - } - while (p > p_end); - - /* This means that known chunks should be processed and unknown chunks should - * be handled according to the value of png_ptr->unknown_default; this can be - * confusing because, as a result, there are two levels of defaulting for - * unknown chunks. - */ - return PNG_HANDLE_CHUNK_AS_DEFAULT; -} - -#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ - defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) -int /* PRIVATE */ -png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name) -{ - png_byte chunk_string[5]; - - PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name); - return png_handle_as_unknown(png_ptr, chunk_string); -} -#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */ -#endif /* SET_UNKNOWN_CHUNKS */ - -#ifdef PNG_READ_SUPPORTED -/* This function, added to libpng-1.0.6g, is untested. */ -int PNGAPI -png_reset_zstream(png_structrp png_ptr) -{ - if (png_ptr == NULL) - return Z_STREAM_ERROR; - - /* WARNING: this resets the window bits to the maximum! */ - return (inflateReset(&png_ptr->zstream)); -} -#endif /* READ */ - -/* This function was added to libpng-1.0.7 */ -png_uint_32 PNGAPI -png_access_version_number(void) -{ - /* Version of *.c files used when building libpng */ - return((png_uint_32)PNG_LIBPNG_VER); -} - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -/* Ensure that png_ptr->zstream.msg holds some appropriate error message string. - * If it doesn't 'ret' is used to set it to something appropriate, even in cases - * like Z_OK or Z_STREAM_END where the error code is apparently a success code. - */ -void /* PRIVATE */ -png_zstream_error(png_structrp png_ptr, int ret) -{ - /* Translate 'ret' into an appropriate error string, priority is given to the - * one in zstream if set. This always returns a string, even in cases like - * Z_OK or Z_STREAM_END where the error code is a success code. - */ - if (png_ptr->zstream.msg == NULL) switch (ret) - { - default: - case Z_OK: - png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code"); - break; - - case Z_STREAM_END: - /* Normal exit */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream"); - break; - - case Z_NEED_DICT: - /* This means the deflate stream did not have a dictionary; this - * indicates a bogus PNG. - */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary"); - break; - - case Z_ERRNO: - /* gz APIs only: should not happen */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error"); - break; - - case Z_STREAM_ERROR: - /* internal libpng error */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib"); - break; - - case Z_DATA_ERROR: - png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream"); - break; - - case Z_MEM_ERROR: - png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory"); - break; - - case Z_BUF_ERROR: - /* End of input or output; not a problem if the caller is doing - * incremental read or write. - */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated"); - break; - - case Z_VERSION_ERROR: - png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version"); - break; - - case PNG_UNEXPECTED_ZLIB_RETURN: - /* Compile errors here mean that zlib now uses the value co-opted in - * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above - * and change pngpriv.h. Note that this message is "... return", - * whereas the default/Z_OK one is "... return code". - */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return"); - break; - } -} - -/* png_convert_size: a PNGAPI but no longer in png.h, so deleted - * at libpng 1.5.5! - */ - -/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ -#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */ -static int -png_colorspace_check_gamma(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_fixed_point gAMA, int from) - /* This is called to check a new gamma value against an existing one. The - * routine returns false if the new gamma value should not be written. - * - * 'from' says where the new gamma value comes from: - * - * 0: the new gamma value is the libpng estimate for an ICC profile - * 1: the new gamma value comes from a gAMA chunk - * 2: the new gamma value comes from an sRGB chunk - */ -{ - png_fixed_point gtest; - - if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && - (png_muldiv(>est, colorspace->gamma, PNG_FP_1, gAMA) == 0 || - png_gamma_significant(gtest) != 0)) - { - /* Either this is an sRGB image, in which case the calculated gamma - * approximation should match, or this is an image with a profile and the - * value libpng calculates for the gamma of the profile does not match the - * value recorded in the file. The former, sRGB, case is an error, the - * latter is just a warning. - */ - if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2) - { - png_chunk_report(png_ptr, "gamma value does not match sRGB", - PNG_CHUNK_ERROR); - /* Do not overwrite an sRGB value */ - return from == 2; - } - - else /* sRGB tag not involved */ - { - png_chunk_report(png_ptr, "gamma value does not match libpng estimate", - PNG_CHUNK_WARNING); - return from == 1; - } - } - - return 1; -} - -void /* PRIVATE */ -png_colorspace_set_gamma(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_fixed_point gAMA) -{ - /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't - * occur. Since the fixed point representation is asymmetrical it is - * possible for 1/gamma to overflow the limit of 21474 and this means the - * gamma value must be at least 5/100000 and hence at most 20000.0. For - * safety the limits here are a little narrower. The values are 0.00016 to - * 6250.0, which are truly ridiculous gamma values (and will produce - * displays that are all black or all white.) - * - * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk - * handling code, which only required the value to be >0. - */ - png_const_charp errmsg; - - if (gAMA < 16 || gAMA > 625000000) - errmsg = "gamma value out of range"; - -# ifdef PNG_READ_gAMA_SUPPORTED - /* Allow the application to set the gamma value more than once */ - else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && - (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0) - errmsg = "duplicate"; -# endif - - /* Do nothing if the colorspace is already invalid */ - else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return; - - else - { - if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA, - 1/*from gAMA*/) != 0) - { - /* Store this gamma value. */ - colorspace->gamma = gAMA; - colorspace->flags |= - (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA); - } - - /* At present if the check_gamma test fails the gamma of the colorspace is - * not updated however the colorspace is not invalidated. This - * corresponds to the case where the existing gamma comes from an sRGB - * chunk or profile. An error message has already been output. - */ - return; - } - - /* Error exit - errmsg has been set. */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR); -} - -void /* PRIVATE */ -png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr) -{ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) - { - /* Everything is invalid */ - info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB| - PNG_INFO_iCCP); - -# ifdef PNG_COLORSPACE_SUPPORTED - /* Clean up the iCCP profile now if it won't be used. */ - png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/); -# else - PNG_UNUSED(png_ptr) -# endif - } - - else - { -# ifdef PNG_COLORSPACE_SUPPORTED - /* Leave the INFO_iCCP flag set if the pngset.c code has already set - * it; this allows a PNG to contain a profile which matches sRGB and - * yet still have that profile retrievable by the application. - */ - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0) - info_ptr->valid |= PNG_INFO_sRGB; - - else - info_ptr->valid &= ~PNG_INFO_sRGB; - - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - info_ptr->valid |= PNG_INFO_cHRM; - - else - info_ptr->valid &= ~PNG_INFO_cHRM; -# endif - - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0) - info_ptr->valid |= PNG_INFO_gAMA; - - else - info_ptr->valid &= ~PNG_INFO_gAMA; - } -} - -#ifdef PNG_READ_SUPPORTED -void /* PRIVATE */ -png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr) -{ - if (info_ptr == NULL) /* reduce code size; check here not in the caller */ - return; - - info_ptr->colorspace = png_ptr->colorspace; - png_colorspace_sync_info(png_ptr, info_ptr); -} -#endif -#endif /* GAMMA */ - -#ifdef PNG_COLORSPACE_SUPPORTED -/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for - * cHRM, as opposed to using chromaticities. These internal APIs return - * non-zero on a parameter error. The X, Y and Z values are required to be - * positive and less than 1.0. - */ -static int -png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ) -{ - png_int_32 d, dwhite, whiteX, whiteY; - - d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z; - if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0) - return 1; - if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0) - return 1; - dwhite = d; - whiteX = XYZ->red_X; - whiteY = XYZ->red_Y; - - d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z; - if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0) - return 1; - if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0) - return 1; - dwhite += d; - whiteX += XYZ->green_X; - whiteY += XYZ->green_Y; - - d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z; - if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0) - return 1; - if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0) - return 1; - dwhite += d; - whiteX += XYZ->blue_X; - whiteY += XYZ->blue_Y; - - /* The reference white is simply the sum of the end-point (X,Y,Z) vectors, - * thus: - */ - if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0) - return 1; - if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0) - return 1; - - return 0; -} - -static int -png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy) -{ - png_fixed_point red_inverse, green_inverse, blue_scale; - png_fixed_point left, right, denominator; - - /* Check xy and, implicitly, z. Note that wide gamut color spaces typically - * have end points with 0 tristimulus values (these are impossible end - * points, but they are used to cover the possible colors). We check - * xy->whitey against 5, not 0, to avoid a possible integer overflow. - */ - if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1; - if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1; - if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1; - if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1; - if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1; - if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1; - if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1; - if (xy->whitey < 5 || xy->whitey > PNG_FP_1-xy->whitex) return 1; - - /* The reverse calculation is more difficult because the original tristimulus - * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8 - * derived values were recorded in the cHRM chunk; - * (red,green,blue,white)x(x,y). This loses one degree of freedom and - * therefore an arbitrary ninth value has to be introduced to undo the - * original transformations. - * - * Think of the original end-points as points in (X,Y,Z) space. The - * chromaticity values (c) have the property: - * - * C - * c = --------- - * X + Y + Z - * - * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the - * three chromaticity values (x,y,z) for each end-point obey the - * relationship: - * - * x + y + z = 1 - * - * This describes the plane in (X,Y,Z) space that intersects each axis at the - * value 1.0; call this the chromaticity plane. Thus the chromaticity - * calculation has scaled each end-point so that it is on the x+y+z=1 plane - * and chromaticity is the intersection of the vector from the origin to the - * (X,Y,Z) value with the chromaticity plane. - * - * To fully invert the chromaticity calculation we would need the three - * end-point scale factors, (red-scale, green-scale, blue-scale), but these - * were not recorded. Instead we calculated the reference white (X,Y,Z) and - * recorded the chromaticity of this. The reference white (X,Y,Z) would have - * given all three of the scale factors since: - * - * color-C = color-c * color-scale - * white-C = red-C + green-C + blue-C - * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale - * - * But cHRM records only white-x and white-y, so we have lost the white scale - * factor: - * - * white-C = white-c*white-scale - * - * To handle this the inverse transformation makes an arbitrary assumption - * about white-scale: - * - * Assume: white-Y = 1.0 - * Hence: white-scale = 1/white-y - * Or: red-Y + green-Y + blue-Y = 1.0 - * - * Notice the last statement of the assumption gives an equation in three of - * the nine values we want to calculate. 8 more equations come from the - * above routine as summarised at the top above (the chromaticity - * calculation): - * - * Given: color-x = color-X / (color-X + color-Y + color-Z) - * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0 - * - * This is 9 simultaneous equations in the 9 variables "color-C" and can be - * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix - * determinants, however this is not as bad as it seems because only 28 of - * the total of 90 terms in the various matrices are non-zero. Nevertheless - * Cramer's rule is notoriously numerically unstable because the determinant - * calculation involves the difference of large, but similar, numbers. It is - * difficult to be sure that the calculation is stable for real world values - * and it is certain that it becomes unstable where the end points are close - * together. - * - * So this code uses the perhaps slightly less optimal but more - * understandable and totally obvious approach of calculating color-scale. - * - * This algorithm depends on the precision in white-scale and that is - * (1/white-y), so we can immediately see that as white-y approaches 0 the - * accuracy inherent in the cHRM chunk drops off substantially. - * - * libpng arithmetic: a simple inversion of the above equations - * ------------------------------------------------------------ - * - * white_scale = 1/white-y - * white-X = white-x * white-scale - * white-Y = 1.0 - * white-Z = (1 - white-x - white-y) * white_scale - * - * white-C = red-C + green-C + blue-C - * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale - * - * This gives us three equations in (red-scale,green-scale,blue-scale) where - * all the coefficients are now known: - * - * red-x*red-scale + green-x*green-scale + blue-x*blue-scale - * = white-x/white-y - * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1 - * red-z*red-scale + green-z*green-scale + blue-z*blue-scale - * = (1 - white-x - white-y)/white-y - * - * In the last equation color-z is (1 - color-x - color-y) so we can add all - * three equations together to get an alternative third: - * - * red-scale + green-scale + blue-scale = 1/white-y = white-scale - * - * So now we have a Cramer's rule solution where the determinants are just - * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve - * multiplication of three coefficients so we can't guarantee to avoid - * overflow in the libpng fixed point representation. Using Cramer's rule in - * floating point is probably a good choice here, but it's not an option for - * fixed point. Instead proceed to simplify the first two equations by - * eliminating what is likely to be the largest value, blue-scale: - * - * blue-scale = white-scale - red-scale - green-scale - * - * Hence: - * - * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale = - * (white-x - blue-x)*white-scale - * - * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale = - * 1 - blue-y*white-scale - * - * And now we can trivially solve for (red-scale,green-scale): - * - * green-scale = - * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale - * ----------------------------------------------------------- - * green-x - blue-x - * - * red-scale = - * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale - * --------------------------------------------------------- - * red-y - blue-y - * - * Hence: - * - * red-scale = - * ( (green-x - blue-x) * (white-y - blue-y) - - * (green-y - blue-y) * (white-x - blue-x) ) / white-y - * ------------------------------------------------------------------------- - * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) - * - * green-scale = - * ( (red-y - blue-y) * (white-x - blue-x) - - * (red-x - blue-x) * (white-y - blue-y) ) / white-y - * ------------------------------------------------------------------------- - * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x) - * - * Accuracy: - * The input values have 5 decimal digits of accuracy. The values are all in - * the range 0 < value < 1, so simple products are in the same range but may - * need up to 10 decimal digits to preserve the original precision and avoid - * underflow. Because we are using a 32-bit signed representation we cannot - * match this; the best is a little over 9 decimal digits, less than 10. - * - * The approach used here is to preserve the maximum precision within the - * signed representation. Because the red-scale calculation above uses the - * difference between two products of values that must be in the range -1..+1 - * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The - * factor is irrelevant in the calculation because it is applied to both - * numerator and denominator. - * - * Note that the values of the differences of the products of the - * chromaticities in the above equations tend to be small, for example for - * the sRGB chromaticities they are: - * - * red numerator: -0.04751 - * green numerator: -0.08788 - * denominator: -0.2241 (without white-y multiplication) - * - * The resultant Y coefficients from the chromaticities of some widely used - * color space definitions are (to 15 decimal places): - * - * sRGB - * 0.212639005871510 0.715168678767756 0.072192315360734 - * Kodak ProPhoto - * 0.288071128229293 0.711843217810102 0.000085653960605 - * Adobe RGB - * 0.297344975250536 0.627363566255466 0.075291458493998 - * Adobe Wide Gamut RGB - * 0.258728243040113 0.724682314948566 0.016589442011321 - */ - /* By the argument, above overflow should be impossible here. The return - * value of 2 indicates an internal error to the caller. - */ - if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0) - return 2; - if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0) - return 2; - denominator = left - right; - - /* Now find the red numerator. */ - if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0) - return 2; - if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0) - return 2; - - /* Overflow is possible here and it indicates an extreme set of PNG cHRM - * chunk values. This calculation actually returns the reciprocal of the - * scale value because this allows us to delay the multiplication of white-y - * into the denominator, which tends to produce a small number. - */ - if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 || - red_inverse <= xy->whitey /* r+g+b scales = white scale */) - return 1; - - /* Similarly for green_inverse: */ - if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0) - return 2; - if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0) - return 2; - if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 || - green_inverse <= xy->whitey) - return 1; - - /* And the blue scale, the checks above guarantee this can't overflow but it - * can still produce 0 for extreme cHRM values. - */ - blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) - - png_reciprocal(green_inverse); - if (blue_scale <= 0) - return 1; - - - /* And fill in the png_XYZ: */ - if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0) - return 1; - if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0) - return 1; - if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1, - red_inverse) == 0) - return 1; - - if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0) - return 1; - if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0) - return 1; - if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1, - green_inverse) == 0) - return 1; - - if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0) - return 1; - if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0) - return 1; - if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale, - PNG_FP_1) == 0) - return 1; - - return 0; /*success*/ -} - -static int -png_XYZ_normalize(png_XYZ *XYZ) -{ - png_int_32 Y; - - if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 || - XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 || - XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0) - return 1; - - /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1. - * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore - * relying on addition of two positive values producing a negative one is not - * safe. - */ - Y = XYZ->red_Y; - if (0x7fffffff - Y < XYZ->green_X) - return 1; - Y += XYZ->green_Y; - if (0x7fffffff - Y < XYZ->blue_X) - return 1; - Y += XYZ->blue_Y; - - if (Y != PNG_FP_1) - { - if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0) - return 1; - - if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0) - return 1; - - if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0) - return 1; - if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0) - return 1; - } - - return 0; -} - -static int -png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta) -{ - /* Allow an error of +/-0.01 (absolute value) on each chromaticity */ - if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) || - PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) || - PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) || - PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) || - PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) || - PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) || - PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) || - PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta)) - return 0; - return 1; -} - -/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM - * chunk chromaticities. Earlier checks used to simply look for the overflow - * condition (where the determinant of the matrix to solve for XYZ ends up zero - * because the chromaticity values are not all distinct.) Despite this it is - * theoretically possible to produce chromaticities that are apparently valid - * but that rapidly degrade to invalid, potentially crashing, sets because of - * arithmetic inaccuracies when calculations are performed on them. The new - * check is to round-trip xy -> XYZ -> xy and then check that the result is - * within a small percentage of the original. - */ -static int -png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy) -{ - int result; - png_xy xy_test; - - /* As a side-effect this routine also returns the XYZ endpoints. */ - result = png_XYZ_from_xy(XYZ, xy); - if (result != 0) - return result; - - result = png_xy_from_XYZ(&xy_test, XYZ); - if (result != 0) - return result; - - if (png_colorspace_endpoints_match(xy, &xy_test, - 5/*actually, the math is pretty accurate*/) != 0) - return 0; - - /* Too much slip */ - return 1; -} - -/* This is the check going the other way. The XYZ is modified to normalize it - * (another side-effect) and the xy chromaticities are returned. - */ -static int -png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ) -{ - int result; - png_XYZ XYZtemp; - - result = png_XYZ_normalize(XYZ); - if (result != 0) - return result; - - result = png_xy_from_XYZ(xy, XYZ); - if (result != 0) - return result; - - XYZtemp = *XYZ; - return png_colorspace_check_xy(&XYZtemp, xy); -} - -/* Used to check for an endpoint match against sRGB */ -static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */ -{ - /* color x y */ - /* red */ 64000, 33000, - /* green */ 30000, 60000, - /* blue */ 15000, 6000, - /* white */ 31270, 32900 -}; - -static int -png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ, - int preferred) -{ - if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return 0; - - /* The consistency check is performed on the chromaticities; this factors out - * variations because of the normalization (or not) of the end point Y - * values. - */ - if (preferred < 2 && - (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - /* The end points must be reasonably close to any we already have. The - * following allows an error of up to +/-.001 - */ - if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy, - 100) == 0) - { - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_benign_error(png_ptr, "inconsistent chromaticities"); - return 0; /* failed */ - } - - /* Only overwrite with preferred values */ - if (preferred == 0) - return 1; /* ok, but no change */ - } - - colorspace->end_points_xy = *xy; - colorspace->end_points_XYZ = *XYZ; - colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS; - - /* The end points are normally quoted to two decimal digits, so allow +/-0.01 - * on this test. - */ - if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0) - colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB; - - else - colorspace->flags &= PNG_COLORSPACE_CANCEL( - PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); - - return 2; /* ok and changed */ -} - -int /* PRIVATE */ -png_colorspace_set_chromaticities(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_xy *xy, int preferred) -{ - /* We must check the end points to ensure they are reasonable - in the past - * color management systems have crashed as a result of getting bogus - * colorant values, while this isn't the fault of libpng it is the - * responsibility of libpng because PNG carries the bomb and libpng is in a - * position to protect against it. - */ - png_XYZ XYZ; - - switch (png_colorspace_check_xy(&XYZ, xy)) - { - case 0: /* success */ - return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ, - preferred); - - case 1: - /* We can't invert the chromaticities so we can't produce value XYZ - * values. Likely as not a color management system will fail too. - */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_benign_error(png_ptr, "invalid chromaticities"); - break; - - default: - /* libpng is broken; this should be a warning but if it happens we - * want error reports so for the moment it is an error. - */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_error(png_ptr, "internal error checking chromaticities"); - } - - return 0; /* failed */ -} - -int /* PRIVATE */ -png_colorspace_set_endpoints(png_const_structrp png_ptr, - png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred) -{ - png_XYZ XYZ = *XYZ_in; - png_xy xy; - - switch (png_colorspace_check_XYZ(&xy, &XYZ)) - { - case 0: - return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ, - preferred); - - case 1: - /* End points are invalid. */ - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_benign_error(png_ptr, "invalid end points"); - break; - - default: - colorspace->flags |= PNG_COLORSPACE_INVALID; - png_error(png_ptr, "internal error checking chromaticities"); - } - - return 0; /* failed */ -} - -#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED) -/* Error message generation */ -static char -png_icc_tag_char(png_uint_32 byte) -{ - byte &= 0xff; - if (byte >= 32 && byte <= 126) - return (char)byte; - else - return '?'; -} - -static void -png_icc_tag_name(char *name, png_uint_32 tag) -{ - name[0] = '\''; - name[1] = png_icc_tag_char(tag >> 24); - name[2] = png_icc_tag_char(tag >> 16); - name[3] = png_icc_tag_char(tag >> 8); - name[4] = png_icc_tag_char(tag ); - name[5] = '\''; -} - -static int -is_ICC_signature_char(png_alloc_size_t it) -{ - return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) || - (it >= 97 && it <= 122); -} - -static int -is_ICC_signature(png_alloc_size_t it) -{ - return is_ICC_signature_char(it >> 24) /* checks all the top bits */ && - is_ICC_signature_char((it >> 16) & 0xff) && - is_ICC_signature_char((it >> 8) & 0xff) && - is_ICC_signature_char(it & 0xff); -} - -static int -png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_alloc_size_t value, png_const_charp reason) -{ - size_t pos; - char message[196]; /* see below for calculation */ - - if (colorspace != NULL) - colorspace->flags |= PNG_COLORSPACE_INVALID; - - pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */ - pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */ - pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */ - if (is_ICC_signature(value) != 0) - { - /* So 'value' is at most 4 bytes and the following cast is safe */ - png_icc_tag_name(message+pos, (png_uint_32)value); - pos += 6; /* total +8; less than the else clause */ - message[pos++] = ':'; - message[pos++] = ' '; - } -# ifdef PNG_WARNINGS_SUPPORTED - else - { - char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/ - - pos = png_safecat(message, (sizeof message), pos, - png_format_number(number, number+(sizeof number), - PNG_NUMBER_FORMAT_x, value)); - pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/ - } -# endif - /* The 'reason' is an arbitrary message, allow +79 maximum 195 */ - pos = png_safecat(message, (sizeof message), pos, reason); - PNG_UNUSED(pos) - - /* This is recoverable, but make it unconditionally an app_error on write to - * avoid writing invalid ICC profiles into PNG files (i.e., we handle them - * on read, with a warning, but on write unless the app turns off - * application errors the PNG won't be written.) - */ - png_chunk_report(png_ptr, message, - (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR); - - return 0; -} -#endif /* sRGB || iCCP */ - -#ifdef PNG_sRGB_SUPPORTED -int /* PRIVATE */ -png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace, - int intent) -{ - /* sRGB sets known gamma, end points and (from the chunk) intent. */ - /* IMPORTANT: these are not necessarily the values found in an ICC profile - * because ICC profiles store values adapted to a D50 environment; it is - * expected that the ICC profile mediaWhitePointTag will be D50; see the - * checks and code elsewhere to understand this better. - * - * These XYZ values, which are accurate to 5dp, produce rgb to gray - * coefficients of (6968,23435,2366), which are reduced (because they add up - * to 32769 not 32768) to (6968,23434,2366). These are the values that - * libpng has traditionally used (and are the best values given the 15bit - * algorithm used by the rgb to gray code.) - */ - static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */ - { - /* color X Y Z */ - /* red */ 41239, 21264, 1933, - /* green */ 35758, 71517, 11919, - /* blue */ 18048, 7219, 95053 - }; - - /* Do nothing if the colorspace is already invalidated. */ - if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return 0; - - /* Check the intent, then check for existing settings. It is valid for the - * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must - * be consistent with the correct values. If, however, this function is - * called below because an iCCP chunk matches sRGB then it is quite - * conceivable that an older app recorded incorrect gAMA and cHRM because of - * an incorrect calculation based on the values in the profile - this does - * *not* invalidate the profile (though it still produces an error, which can - * be ignored.) - */ - if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST) - return png_icc_profile_error(png_ptr, colorspace, "sRGB", - (png_alloc_size_t)intent, "invalid sRGB rendering intent"); - - if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 && - colorspace->rendering_intent != intent) - return png_icc_profile_error(png_ptr, colorspace, "sRGB", - (png_alloc_size_t)intent, "inconsistent rendering intents"); - - if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0) - { - png_benign_error(png_ptr, "duplicate sRGB information ignored"); - return 0; - } - - /* If the standard sRGB cHRM chunk does not match the one from the PNG file - * warn but overwrite the value with the correct one. - */ - if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 && - !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy, - 100)) - png_chunk_report(png_ptr, "cHRM chunk does not match sRGB", - PNG_CHUNK_ERROR); - - /* This check is just done for the error reporting - the routine always - * returns true when the 'from' argument corresponds to sRGB (2). - */ - (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE, - 2/*from sRGB*/); - - /* intent: bugs in GCC force 'int' to be used as the parameter type. */ - colorspace->rendering_intent = (png_uint_16)intent; - colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT; - - /* endpoints */ - colorspace->end_points_xy = sRGB_xy; - colorspace->end_points_XYZ = sRGB_XYZ; - colorspace->flags |= - (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB); - - /* gamma */ - colorspace->gamma = PNG_GAMMA_sRGB_INVERSE; - colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA; - - /* Finally record that we have an sRGB profile */ - colorspace->flags |= - (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB); - - return 1; /* set */ -} -#endif /* sRGB */ - -#ifdef PNG_iCCP_SUPPORTED -/* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value - * is XYZ(0.9642,1.0,0.8249), which scales to: - * - * (63189.8112, 65536, 54060.6464) - */ -static const png_byte D50_nCIEXYZ[12] = - { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d }; - -static int /* bool */ -icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length) -{ - if (profile_length < 132) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "too short"); - return 1; -} - -#ifdef PNG_READ_iCCP_SUPPORTED -int /* PRIVATE */ -png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length) -{ - if (!icc_check_length(png_ptr, colorspace, name, profile_length)) - return 0; - - /* This needs to be here because the 'normal' check is in - * png_decompress_chunk, yet this happens after the attempt to - * png_malloc_base the required data. We only need this on read; on write - * the caller supplies the profile buffer so libpng doesn't allocate it. See - * the call to icc_check_length below (the write case). - */ -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - else if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < profile_length) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "exceeds application limits"); -# elif PNG_USER_CHUNK_MALLOC_MAX > 0 - else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "exceeds libpng limits"); -# else /* !SET_USER_LIMITS */ - /* This will get compiled out on all 32-bit and better systems. */ - else if (PNG_SIZE_MAX < profile_length) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "exceeds system limits"); -# endif /* !SET_USER_LIMITS */ - - return 1; -} -#endif /* READ_iCCP */ - -int /* PRIVATE */ -png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, - png_const_bytep profile/* first 132 bytes only */, int color_type) -{ - png_uint_32 temp; - - /* Length check; this cannot be ignored in this code because profile_length - * is used later to check the tag table, so even if the profile seems over - * long profile_length from the caller must be correct. The caller can fix - * this up on read or write by just passing in the profile header length. - */ - temp = png_get_uint_32(profile); - if (temp != profile_length) - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "length does not match profile"); - - temp = (png_uint_32) (*(profile+8)); - if (temp > 3 && (profile_length & 3)) - return png_icc_profile_error(png_ptr, colorspace, name, profile_length, - "invalid length"); - - temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */ - if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */ - profile_length < 132+12*temp) /* truncated tag table */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "tag count too large"); - - /* The 'intent' must be valid or we can't store it, ICC limits the intent to - * 16 bits. - */ - temp = png_get_uint_32(profile+64); - if (temp >= 0xffff) /* The ICC limit */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid rendering intent"); - - /* This is just a warning because the profile may be valid in future - * versions. - */ - if (temp >= PNG_sRGB_INTENT_LAST) - (void)png_icc_profile_error(png_ptr, NULL, name, temp, - "intent outside defined range"); - - /* At this point the tag table can't be checked because it hasn't necessarily - * been loaded; however, various header fields can be checked. These checks - * are for values permitted by the PNG spec in an ICC profile; the PNG spec - * restricts the profiles that can be passed in an iCCP chunk (they must be - * appropriate to processing PNG data!) - */ - - /* Data checks (could be skipped). These checks must be independent of the - * version number; however, the version number doesn't accommodate changes in - * the header fields (just the known tags and the interpretation of the - * data.) - */ - temp = png_get_uint_32(profile+36); /* signature 'ascp' */ - if (temp != 0x61637370) - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid signature"); - - /* Currently the PCS illuminant/adopted white point (the computational - * white point) are required to be D50, - * however the profile contains a record of the illuminant so perhaps ICC - * expects to be able to change this in the future (despite the rationale in - * the introduction for using a fixed PCS adopted white.) Consequently the - * following is just a warning. - */ - if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0) - (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/, - "PCS illuminant is not D50"); - - /* The PNG spec requires this: - * "If the iCCP chunk is present, the image samples conform to the colour - * space represented by the embedded ICC profile as defined by the - * International Color Consortium [ICC]. The colour space of the ICC profile - * shall be an RGB colour space for colour images (PNG colour types 2, 3, and - * 6), or a greyscale colour space for greyscale images (PNG colour types 0 - * and 4)." - * - * This checking code ensures the embedded profile (on either read or write) - * conforms to the specification requirements. Notice that an ICC 'gray' - * color-space profile contains the information to transform the monochrome - * data to XYZ or L*a*b (according to which PCS the profile uses) and this - * should be used in preference to the standard libpng K channel replication - * into R, G and B channels. - * - * Previously it was suggested that an RGB profile on grayscale data could be - * handled. However it it is clear that using an RGB profile in this context - * must be an error - there is no specification of what it means. Thus it is - * almost certainly more correct to ignore the profile. - */ - temp = png_get_uint_32(profile+16); /* data colour space field */ - switch (temp) - { - case 0x52474220: /* 'RGB ' */ - if ((color_type & PNG_COLOR_MASK_COLOR) == 0) - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "RGB color space not permitted on grayscale PNG"); - break; - - case 0x47524159: /* 'GRAY' */ - if ((color_type & PNG_COLOR_MASK_COLOR) != 0) - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "Gray color space not permitted on RGB PNG"); - break; - - default: - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid ICC profile color space"); - } - - /* It is up to the application to check that the profile class matches the - * application requirements; the spec provides no guidance, but it's pretty - * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer - * ('prtr') or 'spac' (for generic color spaces). Issue a warning in these - * cases. Issue an error for device link or abstract profiles - these don't - * contain the records necessary to transform the color-space to anything - * other than the target device (and not even that for an abstract profile). - * Profiles of these classes may not be embedded in images. - */ - temp = png_get_uint_32(profile+12); /* profile/device class */ - switch (temp) - { - case 0x73636e72: /* 'scnr' */ - case 0x6d6e7472: /* 'mntr' */ - case 0x70727472: /* 'prtr' */ - case 0x73706163: /* 'spac' */ - /* All supported */ - break; - - case 0x61627374: /* 'abst' */ - /* May not be embedded in an image */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "invalid embedded Abstract ICC profile"); - - case 0x6c696e6b: /* 'link' */ - /* DeviceLink profiles cannot be interpreted in a non-device specific - * fashion, if an app uses the AToB0Tag in the profile the results are - * undefined unless the result is sent to the intended device, - * therefore a DeviceLink profile should not be found embedded in a - * PNG. - */ - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "unexpected DeviceLink ICC profile class"); - - case 0x6e6d636c: /* 'nmcl' */ - /* A NamedColor profile is also device specific, however it doesn't - * contain an AToB0 tag that is open to misinterpretation. Almost - * certainly it will fail the tests below. - */ - (void)png_icc_profile_error(png_ptr, NULL, name, temp, - "unexpected NamedColor ICC profile class"); - break; - - default: - /* To allow for future enhancements to the profile accept unrecognized - * profile classes with a warning, these then hit the test below on the - * tag content to ensure they are backward compatible with one of the - * understood profiles. - */ - (void)png_icc_profile_error(png_ptr, NULL, name, temp, - "unrecognized ICC profile class"); - break; - } - - /* For any profile other than a device link one the PCS must be encoded - * either in XYZ or Lab. - */ - temp = png_get_uint_32(profile+20); - switch (temp) - { - case 0x58595a20: /* 'XYZ ' */ - case 0x4c616220: /* 'Lab ' */ - break; - - default: - return png_icc_profile_error(png_ptr, colorspace, name, temp, - "unexpected ICC PCS encoding"); - } - - return 1; -} - -int /* PRIVATE */ -png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, - png_const_bytep profile /* header plus whole tag table */) -{ - png_uint_32 tag_count = png_get_uint_32(profile+128); - png_uint_32 itag; - png_const_bytep tag = profile+132; /* The first tag */ - - /* First scan all the tags in the table and add bits to the icc_info value - * (temporarily in 'tags'). - */ - for (itag=0; itag < tag_count; ++itag, tag += 12) - { - png_uint_32 tag_id = png_get_uint_32(tag+0); - png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */ - png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */ - - /* The ICC specification does not exclude zero length tags, therefore the - * start might actually be anywhere if there is no data, but this would be - * a clear abuse of the intent of the standard so the start is checked for - * being in range. All defined tag types have an 8 byte header - a 4 byte - * type signature then 0. - */ - - /* This is a hard error; potentially it can cause read outside the - * profile. - */ - if (tag_start > profile_length || tag_length > profile_length - tag_start) - return png_icc_profile_error(png_ptr, colorspace, name, tag_id, - "ICC profile tag outside profile"); - - if ((tag_start & 3) != 0) - { - /* CNHP730S.icc shipped with Microsoft Windows 64 violates this; it is - * only a warning here because libpng does not care about the - * alignment. - */ - (void)png_icc_profile_error(png_ptr, NULL, name, tag_id, - "ICC profile tag start not a multiple of 4"); - } - } - - return 1; /* success, maybe with warnings */ -} - -#ifdef PNG_sRGB_SUPPORTED -#if PNG_sRGB_PROFILE_CHECKS >= 0 -/* Information about the known ICC sRGB profiles */ -static const struct -{ - png_uint_32 adler, crc, length; - png_uint_32 md5[4]; - png_byte have_md5; - png_byte is_broken; - png_uint_16 intent; - -# define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0) -# define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\ - { adler, crc, length, md5, broke, intent }, - -} png_sRGB_checks[] = -{ - /* This data comes from contrib/tools/checksum-icc run on downloads of - * all four ICC sRGB profiles from www.color.org. - */ - /* adler32, crc32, MD5[4], intent, date, length, file-name */ - PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9, - PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0, - "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc") - - /* ICC sRGB v2 perceptual no black-compensation: */ - PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21, - PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0, - "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc") - - PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae, - PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0, - "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc") - - /* ICC sRGB v4 perceptual */ - PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812, - PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0, - "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc") - - /* The following profiles have no known MD5 checksum. If there is a match - * on the (empty) MD5 the other fields are used to attempt a match and - * a warning is produced. The first two of these profiles have a 'cprt' tag - * which suggests that they were also made by Hewlett Packard. - */ - PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0, - "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc") - - /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not - * match the D50 PCS illuminant in the header (it is in fact the D65 values, - * so the white point is recorded as the un-adapted value.) The profiles - * below only differ in one byte - the intent - and are basically the same as - * the previous profile except for the mediaWhitePointTag error and a missing - * chromaticAdaptationTag. - */ - PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/, - "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual") - - PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d, - PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/, - "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative") -}; - -static int -png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr, - png_const_bytep profile, uLong adler) -{ - /* The quick check is to verify just the MD5 signature and trust the - * rest of the data. Because the profile has already been verified for - * correctness this is safe. png_colorspace_set_sRGB will check the 'intent' - * field too, so if the profile has been edited with an intent not defined - * by sRGB (but maybe defined by a later ICC specification) the read of - * the profile will fail at that point. - */ - - png_uint_32 length = 0; - png_uint_32 intent = 0x10000; /* invalid */ -#if PNG_sRGB_PROFILE_CHECKS > 1 - uLong crc = 0; /* the value for 0 length data */ -#endif - unsigned int i; - -#ifdef PNG_SET_OPTION_SUPPORTED - /* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to "on" */ - if (((png_ptr->options >> PNG_SKIP_sRGB_CHECK_PROFILE) & 3) == - PNG_OPTION_ON) - return 0; -#endif - - for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i) - { - if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] && - png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] && - png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] && - png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3]) - { - /* This may be one of the old HP profiles without an MD5, in that - * case we can only use the length and Adler32 (note that these - * are not used by default if there is an MD5!) - */ -# if PNG_sRGB_PROFILE_CHECKS == 0 - if (png_sRGB_checks[i].have_md5 != 0) - return 1+png_sRGB_checks[i].is_broken; -# endif - - /* Profile is unsigned or more checks have been configured in. */ - if (length == 0) - { - length = png_get_uint_32(profile); - intent = png_get_uint_32(profile+64); - } - - /* Length *and* intent must match */ - if (length == (png_uint_32) png_sRGB_checks[i].length && - intent == (png_uint_32) png_sRGB_checks[i].intent) - { - /* Now calculate the adler32 if not done already. */ - if (adler == 0) - { - adler = adler32(0, NULL, 0); - adler = adler32(adler, profile, length); - } - - if (adler == png_sRGB_checks[i].adler) - { - /* These basic checks suggest that the data has not been - * modified, but if the check level is more than 1 perform - * our own crc32 checksum on the data. - */ -# if PNG_sRGB_PROFILE_CHECKS > 1 - if (crc == 0) - { - crc = crc32(0, NULL, 0); - crc = crc32(crc, profile, length); - } - - /* So this check must pass for the 'return' below to happen. - */ - if (crc == png_sRGB_checks[i].crc) -# endif - { - if (png_sRGB_checks[i].is_broken != 0) - { - /* These profiles are known to have bad data that may cause - * problems if they are used, therefore attempt to - * discourage their use, skip the 'have_md5' warning below, - * which is made irrelevant by this error. - */ - png_chunk_report(png_ptr, "known incorrect sRGB profile", - PNG_CHUNK_ERROR); - } - - /* Warn that this being done; this isn't even an error since - * the profile is perfectly valid, but it would be nice if - * people used the up-to-date ones. - */ - else if (png_sRGB_checks[i].have_md5 == 0) - { - png_chunk_report(png_ptr, - "out-of-date sRGB profile with no signature", - PNG_CHUNK_WARNING); - } - - return 1+png_sRGB_checks[i].is_broken; - } - } - -# if PNG_sRGB_PROFILE_CHECKS > 0 - /* The signature matched, but the profile had been changed in some - * way. This probably indicates a data error or uninformed hacking. - * Fall through to "no match". - */ - png_chunk_report(png_ptr, - "Not recognizing known sRGB profile that has been edited", - PNG_CHUNK_WARNING); - break; -# endif - } - } - } - - return 0; /* no match */ -} - -void /* PRIVATE */ -png_icc_set_sRGB(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_bytep profile, uLong adler) -{ - /* Is this profile one of the known ICC sRGB profiles? If it is, just set - * the sRGB information. - */ - if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0) - (void)png_colorspace_set_sRGB(png_ptr, colorspace, - (int)/*already checked*/png_get_uint_32(profile+64)); -} -#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */ -#endif /* sRGB */ - -int /* PRIVATE */ -png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_charp name, png_uint_32 profile_length, png_const_bytep profile, - int color_type) -{ - if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0) - return 0; - - if (icc_check_length(png_ptr, colorspace, name, profile_length) != 0 && - png_icc_check_header(png_ptr, colorspace, name, profile_length, profile, - color_type) != 0 && - png_icc_check_tag_table(png_ptr, colorspace, name, profile_length, - profile) != 0) - { -# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0 - /* If no sRGB support, don't try storing sRGB information */ - png_icc_set_sRGB(png_ptr, colorspace, profile, 0); -# endif - return 1; - } - - /* Failure case */ - return 0; -} -#endif /* iCCP */ - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -void /* PRIVATE */ -png_colorspace_set_rgb_coefficients(png_structrp png_ptr) -{ - /* Set the rgb_to_gray coefficients from the colorspace. */ - if (png_ptr->rgb_to_gray_coefficients_set == 0 && - (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - /* png_set_background has not been called, get the coefficients from the Y - * values of the colorspace colorants. - */ - png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y; - png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y; - png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y; - png_fixed_point total = r+g+b; - - if (total > 0 && - r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 && - g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 && - b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 && - r+g+b <= 32769) - { - /* We allow 0 coefficients here. r+g+b may be 32769 if two or - * all of the coefficients were rounded up. Handle this by - * reducing the *largest* coefficient by 1; this matches the - * approach used for the default coefficients in pngrtran.c - */ - int add = 0; - - if (r+g+b > 32768) - add = -1; - else if (r+g+b < 32768) - add = 1; - - if (add != 0) - { - if (g >= r && g >= b) - g += add; - else if (r >= g && r >= b) - r += add; - else - b += add; - } - - /* Check for an internal error. */ - if (r+g+b != 32768) - png_error(png_ptr, - "internal error handling cHRM coefficients"); - - else - { - png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r; - png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g; - } - } - - /* This is a png_error at present even though it could be ignored - - * it should never happen, but it is important that if it does, the - * bug is fixed. - */ - else - png_error(png_ptr, "internal error handling cHRM->XYZ"); - } -} -#endif /* READ_RGB_TO_GRAY */ - -#endif /* COLORSPACE */ - -#ifdef __GNUC__ -/* This exists solely to work round a warning from GNU C. */ -static int /* PRIVATE */ -png_gt(size_t a, size_t b) -{ - return a > b; -} -#else -# define png_gt(a,b) ((a) > (b)) -#endif - -void /* PRIVATE */ -png_check_IHDR(png_const_structrp png_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type) -{ - int error = 0; - - /* Check for width and height valid values */ - if (width == 0) - { - png_warning(png_ptr, "Image width is zero in IHDR"); - error = 1; - } - - if (width > PNG_UINT_31_MAX) - { - png_warning(png_ptr, "Invalid image width in IHDR"); - error = 1; - } - - if (png_gt(((width + 7) & (~7U)), - ((PNG_SIZE_MAX - - 48 /* big_row_buf hack */ - - 1) /* filter byte */ - / 8) /* 8-byte RGBA pixels */ - - 1)) /* extra max_pixel_depth pad */ - { - /* The size of the row must be within the limits of this architecture. - * Because the read code can perform arbitrary transformations the - * maximum size is checked here. Because the code in png_read_start_row - * adds extra space "for safety's sake" in several places a conservative - * limit is used here. - * - * NOTE: it would be far better to check the size that is actually used, - * but the effect in the real world is minor and the changes are more - * extensive, therefore much more dangerous and much more difficult to - * write in a way that avoids compiler warnings. - */ - png_warning(png_ptr, "Image width is too large for this architecture"); - error = 1; - } - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (width > png_ptr->user_width_max) -#else - if (width > PNG_USER_WIDTH_MAX) -#endif - { - png_warning(png_ptr, "Image width exceeds user limit in IHDR"); - error = 1; - } - - if (height == 0) - { - png_warning(png_ptr, "Image height is zero in IHDR"); - error = 1; - } - - if (height > PNG_UINT_31_MAX) - { - png_warning(png_ptr, "Invalid image height in IHDR"); - error = 1; - } - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (height > png_ptr->user_height_max) -#else - if (height > PNG_USER_HEIGHT_MAX) -#endif - { - png_warning(png_ptr, "Image height exceeds user limit in IHDR"); - error = 1; - } - - /* Check other values */ - if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && - bit_depth != 8 && bit_depth != 16) - { - png_warning(png_ptr, "Invalid bit depth in IHDR"); - error = 1; - } - - if (color_type < 0 || color_type == 1 || - color_type == 5 || color_type > 6) - { - png_warning(png_ptr, "Invalid color type in IHDR"); - error = 1; - } - - if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || - ((color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA || - color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8)) - { - png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR"); - error = 1; - } - - if (interlace_type >= PNG_INTERLACE_LAST) - { - png_warning(png_ptr, "Unknown interlace method in IHDR"); - error = 1; - } - - if (compression_type != PNG_COMPRESSION_TYPE_BASE) - { - png_warning(png_ptr, "Unknown compression method in IHDR"); - error = 1; - } - -#ifdef PNG_MNG_FEATURES_SUPPORTED - /* Accept filter_method 64 (intrapixel differencing) only if - * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and - * 2. Libpng did not read a PNG signature (this filter_method is only - * used in PNG datastreams that are embedded in MNG datastreams) and - * 3. The application called png_permit_mng_features with a mask that - * included PNG_FLAG_MNG_FILTER_64 and - * 4. The filter_method is 64 and - * 5. The color_type is RGB or RGBA - */ - if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && - png_ptr->mng_features_permitted != 0) - png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); - - if (filter_type != PNG_FILTER_TYPE_BASE) - { - if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && - ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && - (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_RGB_ALPHA))) - { - png_warning(png_ptr, "Unknown filter method in IHDR"); - error = 1; - } - - if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0) - { - png_warning(png_ptr, "Invalid filter method in IHDR"); - error = 1; - } - } - -#else - if (filter_type != PNG_FILTER_TYPE_BASE) - { - png_warning(png_ptr, "Unknown filter method in IHDR"); - error = 1; - } -#endif - - if (error == 1) - png_error(png_ptr, "Invalid IHDR data"); -} - -#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) -/* ASCII to fp functions */ -/* Check an ASCII formatted floating point value, see the more detailed - * comments in pngpriv.h - */ -/* The following is used internally to preserve the sticky flags */ -#define png_fp_add(state, flags) ((state) |= (flags)) -#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY)) - -int /* PRIVATE */ -png_check_fp_number(png_const_charp string, size_t size, int *statep, - png_size_tp whereami) -{ - int state = *statep; - size_t i = *whereami; - - while (i < size) - { - int type; - /* First find the type of the next character */ - switch (string[i]) - { - case 43: type = PNG_FP_SAW_SIGN; break; - case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break; - case 46: type = PNG_FP_SAW_DOT; break; - case 48: type = PNG_FP_SAW_DIGIT; break; - case 49: case 50: case 51: case 52: - case 53: case 54: case 55: case 56: - case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break; - case 69: - case 101: type = PNG_FP_SAW_E; break; - default: goto PNG_FP_End; - } - - /* Now deal with this type according to the current - * state, the type is arranged to not overlap the - * bits of the PNG_FP_STATE. - */ - switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY)) - { - case PNG_FP_INTEGER + PNG_FP_SAW_SIGN: - if ((state & PNG_FP_SAW_ANY) != 0) - goto PNG_FP_End; /* not a part of the number */ - - png_fp_add(state, type); - break; - - case PNG_FP_INTEGER + PNG_FP_SAW_DOT: - /* Ok as trailer, ok as lead of fraction. */ - if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */ - goto PNG_FP_End; - - else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */ - png_fp_add(state, type); - - else - png_fp_set(state, PNG_FP_FRACTION | type); - - break; - - case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT: - if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */ - png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); - - png_fp_add(state, type | PNG_FP_WAS_VALID); - - break; - - case PNG_FP_INTEGER + PNG_FP_SAW_E: - if ((state & PNG_FP_SAW_DIGIT) == 0) - goto PNG_FP_End; - - png_fp_set(state, PNG_FP_EXPONENT); - - break; - - /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN: - goto PNG_FP_End; ** no sign in fraction */ - - /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT: - goto PNG_FP_End; ** Because SAW_DOT is always set */ - - case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT: - png_fp_add(state, type | PNG_FP_WAS_VALID); - break; - - case PNG_FP_FRACTION + PNG_FP_SAW_E: - /* This is correct because the trailing '.' on an - * integer is handled above - so we can only get here - * with the sequence ".E" (with no preceding digits). - */ - if ((state & PNG_FP_SAW_DIGIT) == 0) - goto PNG_FP_End; - - png_fp_set(state, PNG_FP_EXPONENT); - - break; - - case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN: - if ((state & PNG_FP_SAW_ANY) != 0) - goto PNG_FP_End; /* not a part of the number */ - - png_fp_add(state, PNG_FP_SAW_SIGN); - - break; - - /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT: - goto PNG_FP_End; */ - - case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT: - png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID); - - break; - - /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E: - goto PNG_FP_End; */ - - default: goto PNG_FP_End; /* I.e. break 2 */ - } - - /* The character seems ok, continue. */ - ++i; - } - -PNG_FP_End: - /* Here at the end, update the state and return the correct - * return code. - */ - *statep = state; - *whereami = i; - - return (state & PNG_FP_SAW_DIGIT) != 0; -} - - -/* The same but for a complete string. */ -int -png_check_fp_string(png_const_charp string, size_t size) -{ - int state=0; - size_t char_index=0; - - if (png_check_fp_number(string, size, &state, &char_index) != 0 && - (char_index == size || string[char_index] == 0)) - return state /* must be non-zero - see above */; - - return 0; /* i.e. fail */ -} -#endif /* pCAL || sCAL */ - -#ifdef PNG_sCAL_SUPPORTED -# ifdef PNG_FLOATING_POINT_SUPPORTED -/* Utility used below - a simple accurate power of ten from an integral - * exponent. - */ -static double -png_pow10(int power) -{ - int recip = 0; - double d = 1; - - /* Handle negative exponent with a reciprocal at the end because - * 10 is exact whereas .1 is inexact in base 2 - */ - if (power < 0) - { - if (power < DBL_MIN_10_EXP) return 0; - recip = 1; power = -power; - } - - if (power > 0) - { - /* Decompose power bitwise. */ - double mult = 10; - do - { - if (power & 1) d *= mult; - mult *= mult; - power >>= 1; - } - while (power > 0); - - if (recip != 0) d = 1/d; - } - /* else power is 0 and d is 1 */ - - return d; -} - -/* Function to format a floating point value in ASCII with a given - * precision. - */ -#if GCC_STRICT_OVERFLOW -#pragma GCC diagnostic push -/* The problem arises below with exp_b10, which can never overflow because it - * comes, originally, from frexp and is therefore limited to a range which is - * typically +/-710 (log2(DBL_MAX)/log2(DBL_MIN)). - */ -#pragma GCC diagnostic warning "-Wstrict-overflow=2" -#endif /* GCC_STRICT_OVERFLOW */ -void /* PRIVATE */ -png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size, - double fp, unsigned int precision) -{ - /* We use standard functions from math.h, but not printf because - * that would require stdio. The caller must supply a buffer of - * sufficient size or we will png_error. The tests on size and - * the space in ascii[] consumed are indicated below. - */ - if (precision < 1) - precision = DBL_DIG; - - /* Enforce the limit of the implementation precision too. */ - if (precision > DBL_DIG+1) - precision = DBL_DIG+1; - - /* Basic sanity checks */ - if (size >= precision+5) /* See the requirements below. */ - { - if (fp < 0) - { - fp = -fp; - *ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */ - --size; - } - - if (fp >= DBL_MIN && fp <= DBL_MAX) - { - int exp_b10; /* A base 10 exponent */ - double base; /* 10^exp_b10 */ - - /* First extract a base 10 exponent of the number, - * the calculation below rounds down when converting - * from base 2 to base 10 (multiply by log10(2) - - * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to - * be increased. Note that the arithmetic shift - * performs a floor() unlike C arithmetic - using a - * C multiply would break the following for negative - * exponents. - */ - (void)frexp(fp, &exp_b10); /* exponent to base 2 */ - - exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */ - - /* Avoid underflow here. */ - base = png_pow10(exp_b10); /* May underflow */ - - while (base < DBL_MIN || base < fp) - { - /* And this may overflow. */ - double test = png_pow10(exp_b10+1); - - if (test <= DBL_MAX) - { - ++exp_b10; base = test; - } - - else - break; - } - - /* Normalize fp and correct exp_b10, after this fp is in the - * range [.1,1) and exp_b10 is both the exponent and the digit - * *before* which the decimal point should be inserted - * (starting with 0 for the first digit). Note that this - * works even if 10^exp_b10 is out of range because of the - * test on DBL_MAX above. - */ - fp /= base; - while (fp >= 1) - { - fp /= 10; ++exp_b10; - } - - /* Because of the code above fp may, at this point, be - * less than .1, this is ok because the code below can - * handle the leading zeros this generates, so no attempt - * is made to correct that here. - */ - - { - unsigned int czero, clead, cdigits; - char exponent[10]; - - /* Allow up to two leading zeros - this will not lengthen - * the number compared to using E-n. - */ - if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */ - { - czero = 0U-exp_b10; /* PLUS 2 digits: TOTAL 3 */ - exp_b10 = 0; /* Dot added below before first output. */ - } - else - czero = 0; /* No zeros to add */ - - /* Generate the digit list, stripping trailing zeros and - * inserting a '.' before a digit if the exponent is 0. - */ - clead = czero; /* Count of leading zeros */ - cdigits = 0; /* Count of digits in list. */ - - do - { - double d; - - fp *= 10; - /* Use modf here, not floor and subtract, so that - * the separation is done in one step. At the end - * of the loop don't break the number into parts so - * that the final digit is rounded. - */ - if (cdigits+czero+1 < precision+clead) - fp = modf(fp, &d); - - else - { - d = floor(fp + .5); - - if (d > 9) - { - /* Rounding up to 10, handle that here. */ - if (czero > 0) - { - --czero; d = 1; - if (cdigits == 0) --clead; - } - else - { - while (cdigits > 0 && d > 9) - { - int ch = *--ascii; - - if (exp_b10 != (-1)) - ++exp_b10; - - else if (ch == 46) - { - ch = *--ascii; ++size; - /* Advance exp_b10 to '1', so that the - * decimal point happens after the - * previous digit. - */ - exp_b10 = 1; - } - - --cdigits; - d = ch - 47; /* I.e. 1+(ch-48) */ - } - - /* Did we reach the beginning? If so adjust the - * exponent but take into account the leading - * decimal point. - */ - if (d > 9) /* cdigits == 0 */ - { - if (exp_b10 == (-1)) - { - /* Leading decimal point (plus zeros?), if - * we lose the decimal point here it must - * be reentered below. - */ - int ch = *--ascii; - - if (ch == 46) - { - ++size; exp_b10 = 1; - } - - /* Else lost a leading zero, so 'exp_b10' is - * still ok at (-1) - */ - } - else - ++exp_b10; - - /* In all cases we output a '1' */ - d = 1; - } - } - } - fp = 0; /* Guarantees termination below. */ - } - - if (d == 0) - { - ++czero; - if (cdigits == 0) ++clead; - } - else - { - /* Included embedded zeros in the digit count. */ - cdigits += czero - clead; - clead = 0; - - while (czero > 0) - { - /* exp_b10 == (-1) means we just output the decimal - * place - after the DP don't adjust 'exp_b10' any - * more! - */ - if (exp_b10 != (-1)) - { - if (exp_b10 == 0) - { - *ascii++ = 46; --size; - } - /* PLUS 1: TOTAL 4 */ - --exp_b10; - } - *ascii++ = 48; --czero; - } - - if (exp_b10 != (-1)) - { - if (exp_b10 == 0) - { - *ascii++ = 46; --size; /* counted above */ - } - - --exp_b10; - } - *ascii++ = (char)(48 + (int)d); ++cdigits; - } - } - while (cdigits+czero < precision+clead && fp > DBL_MIN); - - /* The total output count (max) is now 4+precision */ - - /* Check for an exponent, if we don't need one we are - * done and just need to terminate the string. At this - * point, exp_b10==(-1) is effectively a flag: it got - * to '-1' because of the decrement, after outputting - * the decimal point above. (The exponent required is - * *not* -1.) - */ - if (exp_b10 >= (-1) && exp_b10 <= 2) - { - /* The following only happens if we didn't output the - * leading zeros above for negative exponent, so this - * doesn't add to the digit requirement. Note that the - * two zeros here can only be output if the two leading - * zeros were *not* output, so this doesn't increase - * the output count. - */ - while (exp_b10-- > 0) *ascii++ = 48; - - *ascii = 0; - - /* Total buffer requirement (including the '\0') is - * 5+precision - see check at the start. - */ - return; - } - - /* Here if an exponent is required, adjust size for - * the digits we output but did not count. The total - * digit output here so far is at most 1+precision - no - * decimal point and no leading or trailing zeros have - * been output. - */ - size -= cdigits; - - *ascii++ = 69; --size; /* 'E': PLUS 1 TOTAL 2+precision */ - - /* The following use of an unsigned temporary avoids ambiguities in - * the signed arithmetic on exp_b10 and permits GCC at least to do - * better optimization. - */ - { - unsigned int uexp_b10; - - if (exp_b10 < 0) - { - *ascii++ = 45; --size; /* '-': PLUS 1 TOTAL 3+precision */ - uexp_b10 = 0U-exp_b10; - } - - else - uexp_b10 = 0U+exp_b10; - - cdigits = 0; - - while (uexp_b10 > 0) - { - exponent[cdigits++] = (char)(48 + uexp_b10 % 10); - uexp_b10 /= 10; - } - } - - /* Need another size check here for the exponent digits, so - * this need not be considered above. - */ - if (size > cdigits) - { - while (cdigits > 0) *ascii++ = exponent[--cdigits]; - - *ascii = 0; - - return; - } - } - } - else if (!(fp >= DBL_MIN)) - { - *ascii++ = 48; /* '0' */ - *ascii = 0; - return; - } - else - { - *ascii++ = 105; /* 'i' */ - *ascii++ = 110; /* 'n' */ - *ascii++ = 102; /* 'f' */ - *ascii = 0; - return; - } - } - - /* Here on buffer too small. */ - png_error(png_ptr, "ASCII conversion buffer too small"); -} -#if GCC_STRICT_OVERFLOW -#pragma GCC diagnostic pop -#endif /* GCC_STRICT_OVERFLOW */ - -# endif /* FLOATING_POINT */ - -# ifdef PNG_FIXED_POINT_SUPPORTED -/* Function to format a fixed point value in ASCII. - */ -void /* PRIVATE */ -png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii, - size_t size, png_fixed_point fp) -{ - /* Require space for 10 decimal digits, a decimal point, a minus sign and a - * trailing \0, 13 characters: - */ - if (size > 12) - { - png_uint_32 num; - - /* Avoid overflow here on the minimum integer. */ - if (fp < 0) - { - *ascii++ = 45; num = (png_uint_32)(-fp); - } - else - num = (png_uint_32)fp; - - if (num <= 0x80000000) /* else overflowed */ - { - unsigned int ndigits = 0, first = 16 /* flag value */; - char digits[10]; - - while (num) - { - /* Split the low digit off num: */ - unsigned int tmp = num/10; - num -= tmp*10; - digits[ndigits++] = (char)(48 + num); - /* Record the first non-zero digit, note that this is a number - * starting at 1, it's not actually the array index. - */ - if (first == 16 && num > 0) - first = ndigits; - num = tmp; - } - - if (ndigits > 0) - { - while (ndigits > 5) *ascii++ = digits[--ndigits]; - /* The remaining digits are fractional digits, ndigits is '5' or - * smaller at this point. It is certainly not zero. Check for a - * non-zero fractional digit: - */ - if (first <= 5) - { - unsigned int i; - *ascii++ = 46; /* decimal point */ - /* ndigits may be <5 for small numbers, output leading zeros - * then ndigits digits to first: - */ - i = 5; - while (ndigits < i) - { - *ascii++ = 48; --i; - } - while (ndigits >= first) *ascii++ = digits[--ndigits]; - /* Don't output the trailing zeros! */ - } - } - else - *ascii++ = 48; - - /* And null terminate the string: */ - *ascii = 0; - return; - } - } - - /* Here on buffer too small. */ - png_error(png_ptr, "ASCII conversion buffer too small"); -} -# endif /* FIXED_POINT */ -#endif /* SCAL */ - -#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ - !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ - (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ - defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ - (defined(PNG_sCAL_SUPPORTED) && \ - defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) -png_fixed_point -png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text) -{ - double r = floor(100000 * fp + .5); - - if (r > 2147483647. || r < -2147483648.) - png_fixed_error(png_ptr, text); - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(text) -# endif - - return (png_fixed_point)r; -} -#endif - -#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\ - defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) -/* muldiv functions */ -/* This API takes signed arguments and rounds the result to the nearest - * integer (or, for a fixed point number - the standard argument - to - * the nearest .00001). Overflow and divide by zero are signalled in - * the result, a boolean - true on success, false on overflow. - */ -#if GCC_STRICT_OVERFLOW /* from above */ -/* It is not obvious which comparison below gets optimized in such a way that - * signed overflow would change the result; looking through the code does not - * reveal any tests which have the form GCC complains about, so presumably the - * optimizer is moving an add or subtract into the 'if' somewhere. - */ -#pragma GCC diagnostic push -#pragma GCC diagnostic warning "-Wstrict-overflow=2" -#endif /* GCC_STRICT_OVERFLOW */ -int -png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, - png_int_32 divisor) -{ - /* Return a * times / divisor, rounded. */ - if (divisor != 0) - { - if (a == 0 || times == 0) - { - *res = 0; - return 1; - } - else - { -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = a; - r *= times; - r /= divisor; - r = floor(r+.5); - - /* A png_fixed_point is a 32-bit integer. */ - if (r <= 2147483647. && r >= -2147483648.) - { - *res = (png_fixed_point)r; - return 1; - } -#else - int negative = 0; - png_uint_32 A, T, D; - png_uint_32 s16, s32, s00; - - if (a < 0) - negative = 1, A = -a; - else - A = a; - - if (times < 0) - negative = !negative, T = -times; - else - T = times; - - if (divisor < 0) - negative = !negative, D = -divisor; - else - D = divisor; - - /* Following can't overflow because the arguments only - * have 31 bits each, however the result may be 32 bits. - */ - s16 = (A >> 16) * (T & 0xffff) + - (A & 0xffff) * (T >> 16); - /* Can't overflow because the a*times bit is only 30 - * bits at most. - */ - s32 = (A >> 16) * (T >> 16) + (s16 >> 16); - s00 = (A & 0xffff) * (T & 0xffff); - - s16 = (s16 & 0xffff) << 16; - s00 += s16; - - if (s00 < s16) - ++s32; /* carry */ - - if (s32 < D) /* else overflow */ - { - /* s32.s00 is now the 64-bit product, do a standard - * division, we know that s32 < D, so the maximum - * required shift is 31. - */ - int bitshift = 32; - png_fixed_point result = 0; /* NOTE: signed */ - - while (--bitshift >= 0) - { - png_uint_32 d32, d00; - - if (bitshift > 0) - d32 = D >> (32-bitshift), d00 = D << bitshift; - - else - d32 = 0, d00 = D; - - if (s32 > d32) - { - if (s00 < d00) --s32; /* carry */ - s32 -= d32, s00 -= d00, result += 1<= d00) - s32 = 0, s00 -= d00, result += 1<= (D >> 1)) - ++result; - - if (negative != 0) - result = -result; - - /* Check for overflow. */ - if ((negative != 0 && result <= 0) || - (negative == 0 && result >= 0)) - { - *res = result; - return 1; - } - } -#endif - } - } - - return 0; -} -#if GCC_STRICT_OVERFLOW -#pragma GCC diagnostic pop -#endif /* GCC_STRICT_OVERFLOW */ -#endif /* READ_GAMMA || INCH_CONVERSIONS */ - -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) -/* The following is for when the caller doesn't much care about the - * result. - */ -png_fixed_point -png_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times, - png_int_32 divisor) -{ - png_fixed_point result; - - if (png_muldiv(&result, a, times, divisor) != 0) - return result; - - png_warning(png_ptr, "fixed point overflow ignored"); - return 0; -} -#endif - -#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */ -/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ -png_fixed_point -png_reciprocal(png_fixed_point a) -{ -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = floor(1E10/a+.5); - - if (r <= 2147483647. && r >= -2147483648.) - return (png_fixed_point)r; -#else - png_fixed_point res; - - if (png_muldiv(&res, 100000, 100000, a) != 0) - return res; -#endif - - return 0; /* error/overflow */ -} - -/* This is the shared test on whether a gamma value is 'significant' - whether - * it is worth doing gamma correction. - */ -int /* PRIVATE */ -png_gamma_significant(png_fixed_point gamma_val) -{ - return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || - gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; -} -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED -#ifdef PNG_16BIT_SUPPORTED -/* A local convenience routine. */ -static png_fixed_point -png_product2(png_fixed_point a, png_fixed_point b) -{ - /* The required result is 1/a * 1/b; the following preserves accuracy. */ -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - double r = a * 1E-5; - r *= b; - r = floor(r+.5); - - if (r <= 2147483647. && r >= -2147483648.) - return (png_fixed_point)r; -#else - png_fixed_point res; - - if (png_muldiv(&res, a, b, 100000) != 0) - return res; -#endif - - return 0; /* overflow */ -} -#endif /* 16BIT */ - -/* The inverse of the above. */ -png_fixed_point -png_reciprocal2(png_fixed_point a, png_fixed_point b) -{ - /* The required result is 1/a * 1/b; the following preserves accuracy. */ -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - if (a != 0 && b != 0) - { - double r = 1E15/a; - r /= b; - r = floor(r+.5); - - if (r <= 2147483647. && r >= -2147483648.) - return (png_fixed_point)r; - } -#else - /* This may overflow because the range of png_fixed_point isn't symmetric, - * but this API is only used for the product of file and screen gamma so it - * doesn't matter that the smallest number it can produce is 1/21474, not - * 1/100000 - */ - png_fixed_point res = png_product2(a, b); - - if (res != 0) - return png_reciprocal(res); -#endif - - return 0; /* overflow */ -} -#endif /* READ_GAMMA */ - -#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */ -#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED -/* Fixed point gamma. - * - * The code to calculate the tables used below can be found in the shell script - * contrib/tools/intgamma.sh - * - * To calculate gamma this code implements fast log() and exp() calls using only - * fixed point arithmetic. This code has sufficient precision for either 8-bit - * or 16-bit sample values. - * - * The tables used here were calculated using simple 'bc' programs, but C double - * precision floating point arithmetic would work fine. - * - * 8-bit log table - * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to - * 255, so it's the base 2 logarithm of a normalized 8-bit floating point - * mantissa. The numbers are 32-bit fractions. - */ -static const png_uint_32 -png_8bit_l2[128] = -{ - 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U, - 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U, - 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U, - 3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U, - 3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U, - 2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U, - 2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U, - 2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U, - 2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U, - 2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U, - 1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U, - 1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U, - 1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U, - 1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U, - 1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U, - 971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U, - 803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U, - 639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U, - 479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U, - 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U, - 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U, - 24347096U, 0U - -#if 0 - /* The following are the values for 16-bit tables - these work fine for the - * 8-bit conversions but produce very slightly larger errors in the 16-bit - * log (about 1.2 as opposed to 0.7 absolute error in the final value). To - * use these all the shifts below must be adjusted appropriately. - */ - 65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054, - 57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803, - 50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068, - 43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782, - 37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887, - 31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339, - 25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098, - 20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132, - 15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415, - 10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523, - 6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495, - 1119, 744, 372 -#endif -}; - -static png_int_32 -png_log8bit(unsigned int x) -{ - unsigned int lg2 = 0; - /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log, - * because the log is actually negate that means adding 1. The final - * returned value thus has the range 0 (for 255 input) to 7.994 (for 1 - * input), return -1 for the overflow (log 0) case, - so the result is - * always at most 19 bits. - */ - if ((x &= 0xff) == 0) - return -1; - - if ((x & 0xf0) == 0) - lg2 = 4, x <<= 4; - - if ((x & 0xc0) == 0) - lg2 += 2, x <<= 2; - - if ((x & 0x80) == 0) - lg2 += 1, x <<= 1; - - /* result is at most 19 bits, so this cast is safe: */ - return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16)); -} - -/* The above gives exact (to 16 binary places) log2 values for 8-bit images, - * for 16-bit images we use the most significant 8 bits of the 16-bit value to - * get an approximation then multiply the approximation by a correction factor - * determined by the remaining up to 8 bits. This requires an additional step - * in the 16-bit case. - * - * We want log2(value/65535), we have log2(v'/255), where: - * - * value = v' * 256 + v'' - * = v' * f - * - * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128 - * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less - * than 258. The final factor also needs to correct for the fact that our 8-bit - * value is scaled by 255, whereas the 16-bit values must be scaled by 65535. - * - * This gives a final formula using a calculated value 'x' which is value/v' and - * scaling by 65536 to match the above table: - * - * log2(x/257) * 65536 - * - * Since these numbers are so close to '1' we can use simple linear - * interpolation between the two end values 256/257 (result -368.61) and 258/257 - * (result 367.179). The values used below are scaled by a further 64 to give - * 16-bit precision in the interpolation: - * - * Start (256): -23591 - * Zero (257): 0 - * End (258): 23499 - */ -#ifdef PNG_16BIT_SUPPORTED -static png_int_32 -png_log16bit(png_uint_32 x) -{ - unsigned int lg2 = 0; - - /* As above, but now the input has 16 bits. */ - if ((x &= 0xffff) == 0) - return -1; - - if ((x & 0xff00) == 0) - lg2 = 8, x <<= 8; - - if ((x & 0xf000) == 0) - lg2 += 4, x <<= 4; - - if ((x & 0xc000) == 0) - lg2 += 2, x <<= 2; - - if ((x & 0x8000) == 0) - lg2 += 1, x <<= 1; - - /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional - * value. - */ - lg2 <<= 28; - lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4; - - /* Now we need to interpolate the factor, this requires a division by the top - * 8 bits. Do this with maximum precision. - */ - x = ((x << 16) + (x >> 9)) / (x >> 8); - - /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24, - * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly - * 16 bits to interpolate to get the low bits of the result. Round the - * answer. Note that the end point values are scaled by 64 to retain overall - * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust - * the overall scaling by 6-12. Round at every step. - */ - x -= 1U << 24; - - if (x <= 65536U) /* <= '257' */ - lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12); - - else - lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12); - - /* Safe, because the result can't have more than 20 bits: */ - return (png_int_32)((lg2 + 2048) >> 12); -} -#endif /* 16BIT */ - -/* The 'exp()' case must invert the above, taking a 20-bit fixed point - * logarithmic value and returning a 16 or 8-bit number as appropriate. In - * each case only the low 16 bits are relevant - the fraction - since the - * integer bits (the top 4) simply determine a shift. - * - * The worst case is the 16-bit distinction between 65535 and 65534. This - * requires perhaps spurious accuracy in the decoding of the logarithm to - * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance - * of getting this accuracy in practice. - * - * To deal with this the following exp() function works out the exponent of the - * fractional part of the logarithm by using an accurate 32-bit value from the - * top four fractional bits then multiplying in the remaining bits. - */ -static const png_uint_32 -png_32bit_exp[16] = -{ - /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */ - 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U, - 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U, - 2553802834U, 2445529972U, 2341847524U, 2242560872U -}; - -/* Adjustment table; provided to explain the numbers in the code below. */ -#if 0 -for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} - 11 44937.64284865548751208448 - 10 45180.98734845585101160448 - 9 45303.31936980687359311872 - 8 45364.65110595323018870784 - 7 45395.35850361789624614912 - 6 45410.72259715102037508096 - 5 45418.40724413220722311168 - 4 45422.25021786898173001728 - 3 45424.17186732298419044352 - 2 45425.13273269940811464704 - 1 45425.61317555035558641664 - 0 45425.85339951654943850496 -#endif - -static png_uint_32 -png_exp(png_fixed_point x) -{ - if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */ - { - /* Obtain a 4-bit approximation */ - png_uint_32 e = png_32bit_exp[(x >> 12) & 0x0f]; - - /* Incorporate the low 12 bits - these decrease the returned value by - * multiplying by a number less than 1 if the bit is set. The multiplier - * is determined by the above table and the shift. Notice that the values - * converge on 45426 and this is used to allow linear interpolation of the - * low bits. - */ - if (x & 0x800) - e -= (((e >> 16) * 44938U) + 16U) >> 5; - - if (x & 0x400) - e -= (((e >> 16) * 45181U) + 32U) >> 6; - - if (x & 0x200) - e -= (((e >> 16) * 45303U) + 64U) >> 7; - - if (x & 0x100) - e -= (((e >> 16) * 45365U) + 128U) >> 8; - - if (x & 0x080) - e -= (((e >> 16) * 45395U) + 256U) >> 9; - - if (x & 0x040) - e -= (((e >> 16) * 45410U) + 512U) >> 10; - - /* And handle the low 6 bits in a single block. */ - e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9; - - /* Handle the upper bits of x. */ - e >>= x >> 16; - return e; - } - - /* Check for overflow */ - if (x <= 0) - return png_32bit_exp[0]; - - /* Else underflow */ - return 0; -} - -static png_byte -png_exp8bit(png_fixed_point lg2) -{ - /* Get a 32-bit value: */ - png_uint_32 x = png_exp(lg2); - - /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that the - * second, rounding, step can't overflow because of the first, subtraction, - * step. - */ - x -= x >> 8; - return (png_byte)(((x + 0x7fffffU) >> 24) & 0xff); -} - -#ifdef PNG_16BIT_SUPPORTED -static png_uint_16 -png_exp16bit(png_fixed_point lg2) -{ - /* Get a 32-bit value: */ - png_uint_32 x = png_exp(lg2); - - /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */ - x -= x >> 16; - return (png_uint_16)((x + 32767U) >> 16); -} -#endif /* 16BIT */ -#endif /* FLOATING_ARITHMETIC */ - -png_byte -png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val) -{ - if (value > 0 && value < 255) - { -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly - * convert this to a floating point value. This includes values that - * would overflow if 'value' were to be converted to 'int'. - * - * Apparently GCC, however, does an intermediate conversion to (int) - * on some (ARM) but not all (x86) platforms, possibly because of - * hardware FP limitations. (E.g. if the hardware conversion always - * assumes the integer register contains a signed value.) This results - * in ANSI-C undefined behavior for large values. - * - * Other implementations on the same machine might actually be ANSI-C90 - * conformant and therefore compile spurious extra code for the large - * values. - * - * We can be reasonably sure that an unsigned to float conversion - * won't be faster than an int to float one. Therefore this code - * assumes responsibility for the undefined behavior, which it knows - * can't happen because of the check above. - * - * Note the argument to this routine is an (unsigned int) because, on - * 16-bit platforms, it is assigned a value which might be out of - * range for an (int); that would result in undefined behavior in the - * caller if the *argument* ('value') were to be declared (int). - */ - double r = floor(255*pow((int)/*SAFE*/value/255.,gamma_val*.00001)+.5); - return (png_byte)r; -# else - png_int_32 lg2 = png_log8bit(value); - png_fixed_point res; - - if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0) - return png_exp8bit(res); - - /* Overflow. */ - value = 0; -# endif - } - - return (png_byte)(value & 0xff); -} - -#ifdef PNG_16BIT_SUPPORTED -png_uint_16 -png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val) -{ - if (value > 0 && value < 65535) - { -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* The same (unsigned int)->(double) constraints apply here as above, - * however in this case the (unsigned int) to (int) conversion can - * overflow on an ANSI-C90 compliant system so the cast needs to ensure - * that this is not possible. - */ - double r = floor(65535*pow((png_int_32)value/65535., - gamma_val*.00001)+.5); - return (png_uint_16)r; -# else - png_int_32 lg2 = png_log16bit(value); - png_fixed_point res; - - if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0) - return png_exp16bit(res); - - /* Overflow. */ - value = 0; -# endif - } - - return (png_uint_16)value; -} -#endif /* 16BIT */ - -/* This does the right thing based on the bit_depth field of the - * png_struct, interpreting values as 8-bit or 16-bit. While the result - * is nominally a 16-bit value if bit depth is 8 then the result is - * 8-bit (as are the arguments.) - */ -png_uint_16 /* PRIVATE */ -png_gamma_correct(png_structrp png_ptr, unsigned int value, - png_fixed_point gamma_val) -{ - if (png_ptr->bit_depth == 8) - return png_gamma_8bit_correct(value, gamma_val); - -#ifdef PNG_16BIT_SUPPORTED - else - return png_gamma_16bit_correct(value, gamma_val); -#else - /* should not reach this */ - return 0; -#endif /* 16BIT */ -} - -#ifdef PNG_16BIT_SUPPORTED -/* Internal function to build a single 16-bit table - the table consists of - * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount - * to shift the input values right (or 16-number_of_signifiant_bits). - * - * The caller is responsible for ensuring that the table gets cleaned up on - * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument - * should be somewhere that will be cleaned. - */ -static void -png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable, - unsigned int shift, png_fixed_point gamma_val) -{ - /* Various values derived from 'shift': */ - unsigned int num = 1U << (8U - shift); -#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* CSE the division and work round wacky GCC warnings (see the comments - * in png_gamma_8bit_correct for where these come from.) - */ - double fmax = 1.0 / (((png_int_32)1 << (16U - shift)) - 1); -#endif - unsigned int max = (1U << (16U - shift)) - 1U; - unsigned int max_by_2 = 1U << (15U - shift); - unsigned int i; - - png_uint_16pp table = *ptable = - (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); - - for (i = 0; i < num; i++) - { - png_uint_16p sub_table = table[i] = - (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16))); - - /* The 'threshold' test is repeated here because it can arise for one of - * the 16-bit tables even if the others don't hit it. - */ - if (png_gamma_significant(gamma_val) != 0) - { - /* The old code would overflow at the end and this would cause the - * 'pow' function to return a result >1, resulting in an - * arithmetic error. This code follows the spec exactly; ig is - * the recovered input sample, it always has 8-16 bits. - * - * We want input * 65535/max, rounded, the arithmetic fits in 32 - * bits (unsigned) so long as max <= 32767. - */ - unsigned int j; - for (j = 0; j < 256; j++) - { - png_uint_32 ig = (j << (8-shift)) + i; -# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED - /* Inline the 'max' scaling operation: */ - /* See png_gamma_8bit_correct for why the cast to (int) is - * required here. - */ - double d = floor(65535.*pow(ig*fmax, gamma_val*.00001)+.5); - sub_table[j] = (png_uint_16)d; -# else - if (shift != 0) - ig = (ig * 65535U + max_by_2)/max; - - sub_table[j] = png_gamma_16bit_correct(ig, gamma_val); -# endif - } - } - else - { - /* We must still build a table, but do it the fast way. */ - unsigned int j; - - for (j = 0; j < 256; j++) - { - png_uint_32 ig = (j << (8-shift)) + i; - - if (shift != 0) - ig = (ig * 65535U + max_by_2)/max; - - sub_table[j] = (png_uint_16)ig; - } - } - } -} - -/* NOTE: this function expects the *inverse* of the overall gamma transformation - * required. - */ -static void -png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable, - unsigned int shift, png_fixed_point gamma_val) -{ - unsigned int num = 1U << (8U - shift); - unsigned int max = (1U << (16U - shift))-1U; - unsigned int i; - png_uint_32 last; - - png_uint_16pp table = *ptable = - (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p))); - - /* 'num' is the number of tables and also the number of low bits of low - * bits of the input 16-bit value used to select a table. Each table is - * itself indexed by the high 8 bits of the value. - */ - for (i = 0; i < num; i++) - table[i] = (png_uint_16p)png_malloc(png_ptr, - 256 * (sizeof (png_uint_16))); - - /* 'gamma_val' is set to the reciprocal of the value calculated above, so - * pow(out,g) is an *input* value. 'last' is the last input value set. - * - * In the loop 'i' is used to find output values. Since the output is - * 8-bit there are only 256 possible values. The tables are set up to - * select the closest possible output value for each input by finding - * the input value at the boundary between each pair of output values - * and filling the table up to that boundary with the lower output - * value. - * - * The boundary values are 0.5,1.5..253.5,254.5. Since these are 9-bit - * values the code below uses a 16-bit value in i; the values start at - * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last - * entries are filled with 255). Start i at 128 and fill all 'last' - * table entries <= 'max' - */ - last = 0; - for (i = 0; i < 255; ++i) /* 8-bit output value */ - { - /* Find the corresponding maximum input value */ - png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */ - - /* Find the boundary value in 16 bits: */ - png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val); - - /* Adjust (round) to (16-shift) bits: */ - bound = (bound * max + 32768U)/65535U + 1U; - - while (last < bound) - { - table[last & (0xffU >> shift)][last >> (8U - shift)] = out; - last++; - } - } - - /* And fill in the final entries. */ - while (last < (num << 8)) - { - table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U; - last++; - } -} -#endif /* 16BIT */ - -/* Build a single 8-bit table: same as the 16-bit case but much simpler (and - * typically much faster). Note that libpng currently does no sBIT processing - * (apparently contrary to the spec) so a 256-entry table is always generated. - */ -static void -png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable, - png_fixed_point gamma_val) -{ - unsigned int i; - png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); - - if (png_gamma_significant(gamma_val) != 0) - for (i=0; i<256; i++) - table[i] = png_gamma_8bit_correct(i, gamma_val); - - else - for (i=0; i<256; ++i) - table[i] = (png_byte)(i & 0xff); -} - -/* Used from png_read_destroy and below to release the memory used by the gamma - * tables. - */ -void /* PRIVATE */ -png_destroy_gamma_table(png_structrp png_ptr) -{ - png_free(png_ptr, png_ptr->gamma_table); - png_ptr->gamma_table = NULL; - -#ifdef PNG_16BIT_SUPPORTED - if (png_ptr->gamma_16_table != NULL) - { - int i; - int istop = (1 << (8 - png_ptr->gamma_shift)); - for (i = 0; i < istop; i++) - { - png_free(png_ptr, png_ptr->gamma_16_table[i]); - } - png_free(png_ptr, png_ptr->gamma_16_table); - png_ptr->gamma_16_table = NULL; - } -#endif /* 16BIT */ - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - png_free(png_ptr, png_ptr->gamma_from_1); - png_ptr->gamma_from_1 = NULL; - png_free(png_ptr, png_ptr->gamma_to_1); - png_ptr->gamma_to_1 = NULL; - -#ifdef PNG_16BIT_SUPPORTED - if (png_ptr->gamma_16_from_1 != NULL) - { - int i; - int istop = (1 << (8 - png_ptr->gamma_shift)); - for (i = 0; i < istop; i++) - { - png_free(png_ptr, png_ptr->gamma_16_from_1[i]); - } - png_free(png_ptr, png_ptr->gamma_16_from_1); - png_ptr->gamma_16_from_1 = NULL; - } - if (png_ptr->gamma_16_to_1 != NULL) - { - int i; - int istop = (1 << (8 - png_ptr->gamma_shift)); - for (i = 0; i < istop; i++) - { - png_free(png_ptr, png_ptr->gamma_16_to_1[i]); - } - png_free(png_ptr, png_ptr->gamma_16_to_1); - png_ptr->gamma_16_to_1 = NULL; - } -#endif /* 16BIT */ -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ -} - -/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit - * tables, we don't make a full table if we are reducing to 8-bit in - * the future. Note also how the gamma_16 tables are segmented so that - * we don't need to allocate > 64K chunks for a full 16-bit table. - */ -void /* PRIVATE */ -png_build_gamma_table(png_structrp png_ptr, int bit_depth) -{ - png_debug(1, "in png_build_gamma_table"); - - /* Remove any existing table; this copes with multiple calls to - * png_read_update_info. The warning is because building the gamma tables - * multiple times is a performance hit - it's harmless but the ability to - * call png_read_update_info() multiple times is new in 1.5.6 so it seems - * sensible to warn if the app introduces such a hit. - */ - if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL) - { - png_warning(png_ptr, "gamma table being rebuilt"); - png_destroy_gamma_table(png_ptr); - } - - if (bit_depth <= 8) - { - png_build_8bit_table(png_ptr, &png_ptr->gamma_table, - png_ptr->screen_gamma > 0 ? - png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) - { - png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, - png_reciprocal(png_ptr->colorspace.gamma)); - - png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, - png_ptr->screen_gamma > 0 ? - png_reciprocal(png_ptr->screen_gamma) : - png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); - } -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ - } -#ifdef PNG_16BIT_SUPPORTED - else - { - png_byte shift, sig_bit; - - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - sig_bit = png_ptr->sig_bit.red; - - if (png_ptr->sig_bit.green > sig_bit) - sig_bit = png_ptr->sig_bit.green; - - if (png_ptr->sig_bit.blue > sig_bit) - sig_bit = png_ptr->sig_bit.blue; - } - else - sig_bit = png_ptr->sig_bit.gray; - - /* 16-bit gamma code uses this equation: - * - * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8] - * - * Where 'iv' is the input color value and 'ov' is the output value - - * pow(iv, gamma). - * - * Thus the gamma table consists of up to 256 256-entry tables. The table - * is selected by the (8-gamma_shift) most significant of the low 8 bits - * of the color value then indexed by the upper 8 bits: - * - * table[low bits][high 8 bits] - * - * So the table 'n' corresponds to all those 'iv' of: - * - * ..<(n+1 << gamma_shift)-1> - * - */ - if (sig_bit > 0 && sig_bit < 16U) - /* shift == insignificant bits */ - shift = (png_byte)((16U - sig_bit) & 0xff); - - else - shift = 0; /* keep all 16 bits */ - - if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) - { - /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively - * the significant bits in the *input* when the output will - * eventually be 8 bits. By default it is 11. - */ - if (shift < (16U - PNG_MAX_GAMMA_8)) - shift = (16U - PNG_MAX_GAMMA_8); - } - - if (shift > 8U) - shift = 8U; /* Guarantees at least one table! */ - - png_ptr->gamma_shift = shift; - - /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now - * PNG_COMPOSE). This effectively smashed the background calculation for - * 16-bit output because the 8-bit table assumes the result will be - * reduced to 8 bits. - */ - if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0) - png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, - png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); - - else - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, - png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma) : PNG_FP_1); - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0) - { - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, - png_reciprocal(png_ptr->colorspace.gamma)); - - /* Notice that the '16 from 1' table should be full precision, however - * the lookup on this table still uses gamma_shift, so it can't be. - * TODO: fix this. - */ - png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, - png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : - png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */); - } -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ - } -#endif /* 16BIT */ -} -#endif /* READ_GAMMA */ - -/* HARDWARE OR SOFTWARE OPTION SUPPORT */ -#ifdef PNG_SET_OPTION_SUPPORTED -int PNGAPI -png_set_option(png_structrp png_ptr, int option, int onoff) -{ - if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT && - (option & 1) == 0) - { - png_uint_32 mask = 3U << option; - png_uint_32 setting = (2U + (onoff != 0)) << option; - png_uint_32 current = png_ptr->options; - - png_ptr->options = (png_uint_32)((current & ~mask) | setting); - - return (int)(current & mask) >> option; - } - - return PNG_OPTION_INVALID; -} -#endif - -/* sRGB support */ -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -/* sRGB conversion tables; these are machine generated with the code in - * contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the - * specification (see the article at https://en.wikipedia.org/wiki/SRGB) - * is used, not the gamma=1/2.2 approximation use elsewhere in libpng. - * The sRGB to linear table is exact (to the nearest 16-bit linear fraction). - * The inverse (linear to sRGB) table has accuracies as follows: - * - * For all possible (255*65535+1) input values: - * - * error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact - * - * For the input values corresponding to the 65536 16-bit values: - * - * error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact - * - * In all cases the inexact readings are only off by one. - */ - -#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -/* The convert-to-sRGB table is only currently required for read. */ -const png_uint_16 png_sRGB_table[256] = -{ - 0,20,40,60,80,99,119,139, - 159,179,199,219,241,264,288,313, - 340,367,396,427,458,491,526,562, - 599,637,677,718,761,805,851,898, - 947,997,1048,1101,1156,1212,1270,1330, - 1391,1453,1517,1583,1651,1720,1790,1863, - 1937,2013,2090,2170,2250,2333,2418,2504, - 2592,2681,2773,2866,2961,3058,3157,3258, - 3360,3464,3570,3678,3788,3900,4014,4129, - 4247,4366,4488,4611,4736,4864,4993,5124, - 5257,5392,5530,5669,5810,5953,6099,6246, - 6395,6547,6700,6856,7014,7174,7335,7500, - 7666,7834,8004,8177,8352,8528,8708,8889, - 9072,9258,9445,9635,9828,10022,10219,10417, - 10619,10822,11028,11235,11446,11658,11873,12090, - 12309,12530,12754,12980,13209,13440,13673,13909, - 14146,14387,14629,14874,15122,15371,15623,15878, - 16135,16394,16656,16920,17187,17456,17727,18001, - 18277,18556,18837,19121,19407,19696,19987,20281, - 20577,20876,21177,21481,21787,22096,22407,22721, - 23038,23357,23678,24002,24329,24658,24990,25325, - 25662,26001,26344,26688,27036,27386,27739,28094, - 28452,28813,29176,29542,29911,30282,30656,31033, - 31412,31794,32179,32567,32957,33350,33745,34143, - 34544,34948,35355,35764,36176,36591,37008,37429, - 37852,38278,38706,39138,39572,40009,40449,40891, - 41337,41785,42236,42690,43147,43606,44069,44534, - 45002,45473,45947,46423,46903,47385,47871,48359, - 48850,49344,49841,50341,50844,51349,51858,52369, - 52884,53401,53921,54445,54971,55500,56032,56567, - 57105,57646,58190,58737,59287,59840,60396,60955, - 61517,62082,62650,63221,63795,64372,64952,65535 -}; -#endif /* SIMPLIFIED_READ */ - -/* The base/delta tables are required for both read and write (but currently - * only the simplified versions.) - */ -const png_uint_16 png_sRGB_base[512] = -{ - 128,1782,3383,4644,5675,6564,7357,8074, - 8732,9346,9921,10463,10977,11466,11935,12384, - 12816,13233,13634,14024,14402,14769,15125,15473, - 15812,16142,16466,16781,17090,17393,17690,17981, - 18266,18546,18822,19093,19359,19621,19879,20133, - 20383,20630,20873,21113,21349,21583,21813,22041, - 22265,22487,22707,22923,23138,23350,23559,23767, - 23972,24175,24376,24575,24772,24967,25160,25352, - 25542,25730,25916,26101,26284,26465,26645,26823, - 27000,27176,27350,27523,27695,27865,28034,28201, - 28368,28533,28697,28860,29021,29182,29341,29500, - 29657,29813,29969,30123,30276,30429,30580,30730, - 30880,31028,31176,31323,31469,31614,31758,31902, - 32045,32186,32327,32468,32607,32746,32884,33021, - 33158,33294,33429,33564,33697,33831,33963,34095, - 34226,34357,34486,34616,34744,34873,35000,35127, - 35253,35379,35504,35629,35753,35876,35999,36122, - 36244,36365,36486,36606,36726,36845,36964,37083, - 37201,37318,37435,37551,37668,37783,37898,38013, - 38127,38241,38354,38467,38580,38692,38803,38915, - 39026,39136,39246,39356,39465,39574,39682,39790, - 39898,40005,40112,40219,40325,40431,40537,40642, - 40747,40851,40955,41059,41163,41266,41369,41471, - 41573,41675,41777,41878,41979,42079,42179,42279, - 42379,42478,42577,42676,42775,42873,42971,43068, - 43165,43262,43359,43456,43552,43648,43743,43839, - 43934,44028,44123,44217,44311,44405,44499,44592, - 44685,44778,44870,44962,45054,45146,45238,45329, - 45420,45511,45601,45692,45782,45872,45961,46051, - 46140,46229,46318,46406,46494,46583,46670,46758, - 46846,46933,47020,47107,47193,47280,47366,47452, - 47538,47623,47709,47794,47879,47964,48048,48133, - 48217,48301,48385,48468,48552,48635,48718,48801, - 48884,48966,49048,49131,49213,49294,49376,49458, - 49539,49620,49701,49782,49862,49943,50023,50103, - 50183,50263,50342,50422,50501,50580,50659,50738, - 50816,50895,50973,51051,51129,51207,51285,51362, - 51439,51517,51594,51671,51747,51824,51900,51977, - 52053,52129,52205,52280,52356,52432,52507,52582, - 52657,52732,52807,52881,52956,53030,53104,53178, - 53252,53326,53400,53473,53546,53620,53693,53766, - 53839,53911,53984,54056,54129,54201,54273,54345, - 54417,54489,54560,54632,54703,54774,54845,54916, - 54987,55058,55129,55199,55269,55340,55410,55480, - 55550,55620,55689,55759,55828,55898,55967,56036, - 56105,56174,56243,56311,56380,56448,56517,56585, - 56653,56721,56789,56857,56924,56992,57059,57127, - 57194,57261,57328,57395,57462,57529,57595,57662, - 57728,57795,57861,57927,57993,58059,58125,58191, - 58256,58322,58387,58453,58518,58583,58648,58713, - 58778,58843,58908,58972,59037,59101,59165,59230, - 59294,59358,59422,59486,59549,59613,59677,59740, - 59804,59867,59930,59993,60056,60119,60182,60245, - 60308,60370,60433,60495,60558,60620,60682,60744, - 60806,60868,60930,60992,61054,61115,61177,61238, - 61300,61361,61422,61483,61544,61605,61666,61727, - 61788,61848,61909,61969,62030,62090,62150,62211, - 62271,62331,62391,62450,62510,62570,62630,62689, - 62749,62808,62867,62927,62986,63045,63104,63163, - 63222,63281,63340,63398,63457,63515,63574,63632, - 63691,63749,63807,63865,63923,63981,64039,64097, - 64155,64212,64270,64328,64385,64443,64500,64557, - 64614,64672,64729,64786,64843,64900,64956,65013, - 65070,65126,65183,65239,65296,65352,65409,65465 -}; - -const png_byte png_sRGB_delta[512] = -{ - 207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54, - 52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36, - 35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28, - 28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24, - 23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21, - 21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19, - 19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17, - 17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16, - 16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15, - 15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14, - 14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13, - 13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11, - 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, - 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, - 11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, - 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, - 10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 -}; -#endif /* SIMPLIFIED READ/WRITE sRGB support */ - -/* SIMPLIFIED READ/WRITE SUPPORT */ -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -static int -png_image_free_function(png_voidp argument) -{ - png_imagep image = png_voidcast(png_imagep, argument); - png_controlp cp = image->opaque; - png_control c; - - /* Double check that we have a png_ptr - it should be impossible to get here - * without one. - */ - if (cp->png_ptr == NULL) - return 0; - - /* First free any data held in the control structure. */ -# ifdef PNG_STDIO_SUPPORTED - if (cp->owned_file != 0) - { - FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr); - cp->owned_file = 0; - - /* Ignore errors here. */ - if (fp != NULL) - { - cp->png_ptr->io_ptr = NULL; - (void)fclose(fp); - } - } -# endif - - /* Copy the control structure so that the original, allocated, version can be - * safely freed. Notice that a png_error here stops the remainder of the - * cleanup, but this is probably fine because that would indicate bad memory - * problems anyway. - */ - c = *cp; - image->opaque = &c; - png_free(c.png_ptr, cp); - - /* Then the structures, calling the correct API. */ - if (c.for_write != 0) - { -# ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED - png_destroy_write_struct(&c.png_ptr, &c.info_ptr); -# else - png_error(c.png_ptr, "simplified write not supported"); -# endif - } - else - { -# ifdef PNG_SIMPLIFIED_READ_SUPPORTED - png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL); -# else - png_error(c.png_ptr, "simplified read not supported"); -# endif - } - - /* Success. */ - return 1; -} - -void PNGAPI -png_image_free(png_imagep image) -{ - /* Safely call the real function, but only if doing so is safe at this point - * (if not inside an error handling context). Otherwise assume - * png_safe_execute will call this API after the return. - */ - if (image != NULL && image->opaque != NULL && - image->opaque->error_buf == NULL) - { - png_image_free_function(image); - image->opaque = NULL; - } -} - -int /* PRIVATE */ -png_image_error(png_imagep image, png_const_charp error_message) -{ - /* Utility to log an error. */ - png_safecat(image->message, (sizeof image->message), 0, error_message); - image->warning_or_error |= PNG_IMAGE_ERROR; - png_image_free(image); - return 0; -} - -#endif /* SIMPLIFIED READ/WRITE */ -#endif /* READ || WRITE */ diff --git a/extern/libpng/png.h b/extern/libpng/png.h deleted file mode 100644 index 139eb0dc0..000000000 --- a/extern/libpng/png.h +++ /dev/null @@ -1,3247 +0,0 @@ - -/* png.h - header file for PNG reference library - * - * libpng version 1.6.37 - April 14, 2019 - * - * Copyright (c) 2018-2019 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. (See LICENSE, below.) - * - * Authors and maintainers: - * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat - * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.6.35, July 2018: - * Glenn Randers-Pehrson - * libpng versions 1.6.36, December 2018, through 1.6.37, April 2019: - * Cosmin Truta - * See also "Contributing Authors", below. - */ - -/* - * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE - * ========================================= - * - * PNG Reference Library License version 2 - * --------------------------------------- - * - * * Copyright (c) 1995-2019 The PNG Reference Library Authors. - * * Copyright (c) 2018-2019 Cosmin Truta. - * * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. - * * Copyright (c) 1996-1997 Andreas Dilger. - * * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * The software is supplied "as is", without warranty of any kind, - * express or implied, including, without limitation, the warranties - * of merchantability, fitness for a particular purpose, title, and - * non-infringement. In no event shall the Copyright owners, or - * anyone distributing the software, be liable for any damages or - * other liability, whether in contract, tort or otherwise, arising - * from, out of, or in connection with the software, or the use or - * other dealings in the software, even if advised of the possibility - * of such damage. - * - * Permission is hereby granted to use, copy, modify, and distribute - * this software, or portions hereof, for any purpose, without fee, - * subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you - * use this software in a product, an acknowledgment in the product - * documentation would be appreciated, but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must - * not be misrepresented as being the original software. - * - * 3. This Copyright notice may not be removed or altered from any - * source or altered source distribution. - * - * - * PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35) - * ----------------------------------------------------------------------- - * - * libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are - * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are - * derived from libpng-1.0.6, and are distributed according to the same - * disclaimer and license as libpng-1.0.6 with the following individuals - * added to the list of Contributing Authors: - * - * Simon-Pierre Cadieux - * Eric S. Raymond - * Mans Rullgard - * Cosmin Truta - * Gilles Vollant - * James Yu - * Mandar Sahastrabuddhe - * Google Inc. - * Vadim Barkov - * - * and with the following additions to the disclaimer: - * - * There is no warranty against interference with your enjoyment of - * the library or against infringement. There is no warranty that our - * efforts or the library will fulfill any of your particular purposes - * or needs. This library is provided with all faults, and the entire - * risk of satisfactory quality, performance, accuracy, and effort is - * with the user. - * - * Some files in the "contrib" directory and some configure-generated - * files that are distributed with libpng have other copyright owners, and - * are released under other open source licenses. - * - * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are - * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from - * libpng-0.96, and are distributed according to the same disclaimer and - * license as libpng-0.96, with the following individuals added to the - * list of Contributing Authors: - * - * Tom Lane - * Glenn Randers-Pehrson - * Willem van Schaik - * - * libpng versions 0.89, June 1996, through 0.96, May 1997, are - * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, - * and are distributed according to the same disclaimer and license as - * libpng-0.88, with the following individuals added to the list of - * Contributing Authors: - * - * John Bowler - * Kevin Bracey - * Sam Bushell - * Magnus Holmgren - * Greg Roelofs - * Tom Tanner - * - * Some files in the "scripts" directory have other copyright owners, - * but are released under this license. - * - * libpng versions 0.5, May 1995, through 0.88, January 1996, are - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * For the purposes of this copyright and license, "Contributing Authors" - * is defined as the following set of individuals: - * - * Andreas Dilger - * Dave Martindale - * Guy Eric Schalnat - * Paul Schmidt - * Tim Wegner - * - * The PNG Reference Library is supplied "AS IS". The Contributing - * Authors and Group 42, Inc. disclaim all warranties, expressed or - * implied, including, without limitation, the warranties of - * merchantability and of fitness for any purpose. The Contributing - * Authors and Group 42, Inc. assume no liability for direct, indirect, - * incidental, special, exemplary, or consequential damages, which may - * result from the use of the PNG Reference Library, even if advised of - * the possibility of such damage. - * - * Permission is hereby granted to use, copy, modify, and distribute this - * source code, or portions hereof, for any purpose, without fee, subject - * to the following restrictions: - * - * 1. The origin of this source code must not be misrepresented. - * - * 2. Altered versions must be plainly marked as such and must not - * be misrepresented as being the original source. - * - * 3. This Copyright notice may not be removed or altered from any - * source or altered source distribution. - * - * The Contributing Authors and Group 42, Inc. specifically permit, - * without fee, and encourage the use of this source code as a component - * to supporting the PNG file format in commercial products. If you use - * this source code in a product, acknowledgment is not required but would - * be appreciated. - * - * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE. - * - * TRADEMARK - * ========= - * - * The name "libpng" has not been registered by the Copyright owners - * as a trademark in any jurisdiction. However, because libpng has - * been distributed and maintained world-wide, continually since 1995, - * the Copyright owners claim "common-law trademark protection" in any - * jurisdiction where common-law trademark is recognized. - */ - -/* - * A "png_get_copyright" function is available, for convenient use in "about" - * boxes and the like: - * - * printf("%s", png_get_copyright(NULL)); - * - * Also, the PNG logo (in PNG format, of course) is supplied in the - * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). - */ - -/* - * The contributing authors would like to thank all those who helped - * with testing, bug fixes, and patience. This wouldn't have been - * possible without all of you. - * - * Thanks to Frank J. T. Wojcik for helping with the documentation. - */ - -/* Note about libpng version numbers: - * - * Due to various miscommunications, unforeseen code incompatibilities - * and occasional factors outside the authors' control, version numbering - * on the library has not always been consistent and straightforward. - * The following table summarizes matters since version 0.89c, which was - * the first widely used release: - * - * source png.h png.h shared-lib - * version string int version - * ------- ------ ----- ---------- - * 0.89c "1.0 beta 3" 0.89 89 1.0.89 - * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90] - * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95] - * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96] - * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97] - * 0.97c 0.97 97 2.0.97 - * 0.98 0.98 98 2.0.98 - * 0.99 0.99 98 2.0.99 - * 0.99a-m 0.99 99 2.0.99 - * 1.00 1.00 100 2.1.0 [100 should be 10000] - * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000] - * 1.0.1 png.h string is 10001 2.1.0 - * 1.0.1a-e identical to the 10002 from here on, the shared library - * 1.0.2 source version) 10002 is 2.V where V is the source code - * 1.0.2a-b 10003 version, except as noted. - * 1.0.3 10003 - * 1.0.3a-d 10004 - * 1.0.4 10004 - * 1.0.4a-f 10005 - * 1.0.5 (+ 2 patches) 10005 - * 1.0.5a-d 10006 - * 1.0.5e-r 10100 (not source compatible) - * 1.0.5s-v 10006 (not binary compatible) - * 1.0.6 (+ 3 patches) 10006 (still binary incompatible) - * 1.0.6d-f 10007 (still binary incompatible) - * 1.0.6g 10007 - * 1.0.6h 10007 10.6h (testing xy.z so-numbering) - * 1.0.6i 10007 10.6i - * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0) - * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible) - * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible) - * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) - * 1.0.7 1 10007 (still compatible) - * ... - * 1.0.69 10 10069 10.so.0.69[.0] - * ... - * 1.2.59 13 10259 12.so.0.59[.0] - * ... - * 1.4.20 14 10420 14.so.0.20[.0] - * ... - * 1.5.30 15 10530 15.so.15.30[.0] - * ... - * 1.6.37 16 10637 16.so.16.37[.0] - * - * Henceforth the source version will match the shared-library major and - * minor numbers; the shared-library major version number will be used for - * changes in backward compatibility, as it is intended. - * The PNG_LIBPNG_VER macro, which is not used within libpng but is - * available for applications, is an unsigned integer of the form XYYZZ - * corresponding to the source version X.Y.Z (leading zeros in Y and Z). - * Beta versions were given the previous public release number plus a - * letter, until version 1.0.6j; from then on they were given the upcoming - * public release number plus "betaNN" or "rcNN". - * - * Binary incompatibility exists only when applications make direct access - * to the info_ptr or png_ptr members through png.h, and the compiled - * application is loaded with a different version of the library. - * - * DLLNUM will change each time there are forward or backward changes - * in binary compatibility (e.g., when a new feature is added). - * - * See libpng.txt or libpng.3 for more information. The PNG specification - * is available as a W3C Recommendation and as an ISO/IEC Standard; see - * - */ - -#ifndef PNG_H -#define PNG_H - -/* This is not the place to learn how to use libpng. The file libpng-manual.txt - * describes how to use libpng, and the file example.c summarizes it - * with some code on which to build. This file is useful for looking - * at the actual function definitions and structure components. If that - * file has been stripped from your copy of libpng, you can find it at - * - * - * If you just need to read a PNG file and don't want to read the documentation - * skip to the end of this file and read the section entitled 'simplified API'. - */ - -/* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.37" -#define PNG_HEADER_VERSION_STRING " libpng version 1.6.37 - April 14, 2019\n" - -#define PNG_LIBPNG_VER_SONUM 16 -#define PNG_LIBPNG_VER_DLLNUM 16 - -/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ -#define PNG_LIBPNG_VER_MAJOR 1 -#define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 37 - -/* This should be zero for a public release, or non-zero for a - * development version. [Deprecated] - */ -#define PNG_LIBPNG_VER_BUILD 0 - -/* Release Status */ -#define PNG_LIBPNG_BUILD_ALPHA 1 -#define PNG_LIBPNG_BUILD_BETA 2 -#define PNG_LIBPNG_BUILD_RC 3 -#define PNG_LIBPNG_BUILD_STABLE 4 -#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7 - -/* Release-Specific Flags */ -#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with - PNG_LIBPNG_BUILD_STABLE only */ -#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with - PNG_LIBPNG_BUILD_SPECIAL */ -#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with - PNG_LIBPNG_BUILD_PRIVATE */ - -#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE - -/* Careful here. At one time, Guy wanted to use 082, but that - * would be octal. We must not include leading zeros. - * Versions 0.7 through 1.0.0 were in the range 0 to 100 here - * (only version 1.0.0 was mis-numbered 100 instead of 10000). - * From version 1.0.1 it is: - * XXYYZZ, where XX=major, YY=minor, ZZ=release - */ -#define PNG_LIBPNG_VER 10637 /* 1.6.37 */ - -/* Library configuration: these options cannot be changed after - * the library has been built. - */ -#ifndef PNGLCONF_H -/* If pnglibconf.h is missing, you can - * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h - */ -# include "pnglibconf.h" -#endif - -#ifndef PNG_VERSION_INFO_ONLY -/* Machine specific configuration. */ -# include "pngconf.h" -#endif - -/* - * Added at libpng-1.2.8 - * - * Ref MSDN: Private as priority over Special - * VS_FF_PRIVATEBUILD File *was not* built using standard release - * procedures. If this value is given, the StringFileInfo block must - * contain a PrivateBuild string. - * - * VS_FF_SPECIALBUILD File *was* built by the original company using - * standard release procedures but is a variation of the standard - * file of the same version number. If this value is given, the - * StringFileInfo block must contain a SpecialBuild string. - */ - -#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */ -# define PNG_LIBPNG_BUILD_TYPE \ - (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE) -#else -# ifdef PNG_LIBPNG_SPECIALBUILD -# define PNG_LIBPNG_BUILD_TYPE \ - (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL) -# else -# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE) -# endif -#endif - -#ifndef PNG_VERSION_INFO_ONLY - -/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Version information for C files, stored in png.c. This had better match - * the version above. - */ -#define png_libpng_ver png_get_header_ver(NULL) - -/* This file is arranged in several sections: - * - * 1. [omitted] - * 2. Any configuration options that can be specified by for the application - * code when it is built. (Build time configuration is in pnglibconf.h) - * 3. Type definitions (base types are defined in pngconf.h), structure - * definitions. - * 4. Exported library functions. - * 5. Simplified API. - * 6. Implementation options. - * - * The library source code has additional files (principally pngpriv.h) that - * allow configuration of the library. - */ - -/* Section 1: [omitted] */ - -/* Section 2: run time configuration - * See pnglibconf.h for build time configuration - * - * Run time configuration allows the application to choose between - * implementations of certain arithmetic APIs. The default is set - * at build time and recorded in pnglibconf.h, but it is safe to - * override these (and only these) settings. Note that this won't - * change what the library does, only application code, and the - * settings can (and probably should) be made on a per-file basis - * by setting the #defines before including png.h - * - * Use macros to read integers from PNG data or use the exported - * functions? - * PNG_USE_READ_MACROS: use the macros (see below) Note that - * the macros evaluate their argument multiple times. - * PNG_NO_USE_READ_MACROS: call the relevant library function. - * - * Use the alternative algorithm for compositing alpha samples that - * does not use division? - * PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division' - * algorithm. - * PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm. - * - * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is - * false? - * PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error - * APIs to png_warning. - * Otherwise the calls are mapped to png_error. - */ - -/* Section 3: type definitions, including structures and compile time - * constants. - * See pngconf.h for base types that vary by machine/system - */ - -/* This triggers a compiler error in png.c, if png.c and png.h - * do not agree upon the version number. - */ -typedef char* png_libpng_version_1_6_37; - -/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. - * - * png_struct is the cache of information used while reading or writing a single - * PNG file. One of these is always required, although the simplified API - * (below) hides the creation and destruction of it. - */ -typedef struct png_struct_def png_struct; -typedef const png_struct * png_const_structp; -typedef png_struct * png_structp; -typedef png_struct * * png_structpp; - -/* png_info contains information read from or to be written to a PNG file. One - * or more of these must exist while reading or creating a PNG file. The - * information is not used by libpng during read but is used to control what - * gets written when a PNG file is created. "png_get_" function calls read - * information during read and "png_set_" functions calls write information - * when creating a PNG. - * been moved into a separate header file that is not accessible to - * applications. Read libpng-manual.txt or libpng.3 for more info. - */ -typedef struct png_info_def png_info; -typedef png_info * png_infop; -typedef const png_info * png_const_infop; -typedef png_info * * png_infopp; - -/* Types with names ending 'p' are pointer types. The corresponding types with - * names ending 'rp' are identical pointer types except that the pointer is - * marked 'restrict', which means that it is the only pointer to the object - * passed to the function. Applications should not use the 'restrict' types; - * it is always valid to pass 'p' to a pointer with a function argument of the - * corresponding 'rp' type. Different compilers have different rules with - * regard to type matching in the presence of 'restrict'. For backward - * compatibility libpng callbacks never have 'restrict' in their parameters and, - * consequentially, writing portable application code is extremely difficult if - * an attempt is made to use 'restrict'. - */ -typedef png_struct * PNG_RESTRICT png_structrp; -typedef const png_struct * PNG_RESTRICT png_const_structrp; -typedef png_info * PNG_RESTRICT png_inforp; -typedef const png_info * PNG_RESTRICT png_const_inforp; - -/* Three color definitions. The order of the red, green, and blue, (and the - * exact size) is not important, although the size of the fields need to - * be png_byte or png_uint_16 (as defined below). - */ -typedef struct png_color_struct -{ - png_byte red; - png_byte green; - png_byte blue; -} png_color; -typedef png_color * png_colorp; -typedef const png_color * png_const_colorp; -typedef png_color * * png_colorpp; - -typedef struct png_color_16_struct -{ - png_byte index; /* used for palette files */ - png_uint_16 red; /* for use in red green blue files */ - png_uint_16 green; - png_uint_16 blue; - png_uint_16 gray; /* for use in grayscale files */ -} png_color_16; -typedef png_color_16 * png_color_16p; -typedef const png_color_16 * png_const_color_16p; -typedef png_color_16 * * png_color_16pp; - -typedef struct png_color_8_struct -{ - png_byte red; /* for use in red green blue files */ - png_byte green; - png_byte blue; - png_byte gray; /* for use in grayscale files */ - png_byte alpha; /* for alpha channel files */ -} png_color_8; -typedef png_color_8 * png_color_8p; -typedef const png_color_8 * png_const_color_8p; -typedef png_color_8 * * png_color_8pp; - -/* - * The following two structures are used for the in-core representation - * of sPLT chunks. - */ -typedef struct png_sPLT_entry_struct -{ - png_uint_16 red; - png_uint_16 green; - png_uint_16 blue; - png_uint_16 alpha; - png_uint_16 frequency; -} png_sPLT_entry; -typedef png_sPLT_entry * png_sPLT_entryp; -typedef const png_sPLT_entry * png_const_sPLT_entryp; -typedef png_sPLT_entry * * png_sPLT_entrypp; - -/* When the depth of the sPLT palette is 8 bits, the color and alpha samples - * occupy the LSB of their respective members, and the MSB of each member - * is zero-filled. The frequency member always occupies the full 16 bits. - */ - -typedef struct png_sPLT_struct -{ - png_charp name; /* palette name */ - png_byte depth; /* depth of palette samples */ - png_sPLT_entryp entries; /* palette entries */ - png_int_32 nentries; /* number of palette entries */ -} png_sPLT_t; -typedef png_sPLT_t * png_sPLT_tp; -typedef const png_sPLT_t * png_const_sPLT_tp; -typedef png_sPLT_t * * png_sPLT_tpp; - -#ifdef PNG_TEXT_SUPPORTED -/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, - * and whether that contents is compressed or not. The "key" field - * points to a regular zero-terminated C string. The "text" fields can be a - * regular C string, an empty string, or a NULL pointer. - * However, the structure returned by png_get_text() will always contain - * the "text" field as a regular zero-terminated C string (possibly - * empty), never a NULL pointer, so it can be safely used in printf() and - * other string-handling functions. Note that the "itxt_length", "lang", and - * "lang_key" members of the structure only exist when the library is built - * with iTXt chunk support. Prior to libpng-1.4.0 the library was built by - * default without iTXt support. Also note that when iTXt *is* supported, - * the "lang" and "lang_key" fields contain NULL pointers when the - * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or - * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the - * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag" - * which is always 0 or 1, or its "compression method" which is always 0. - */ -typedef struct png_text_struct -{ - int compression; /* compression value: - -1: tEXt, none - 0: zTXt, deflate - 1: iTXt, none - 2: iTXt, deflate */ - png_charp key; /* keyword, 1-79 character description of "text" */ - png_charp text; /* comment, may be an empty string (ie "") - or a NULL pointer */ - size_t text_length; /* length of the text string */ - size_t itxt_length; /* length of the itxt string */ - png_charp lang; /* language code, 0-79 characters - or a NULL pointer */ - png_charp lang_key; /* keyword translated UTF-8 string, 0 or more - chars or a NULL pointer */ -} png_text; -typedef png_text * png_textp; -typedef const png_text * png_const_textp; -typedef png_text * * png_textpp; -#endif - -/* Supported compression types for text in PNG files (tEXt, and zTXt). - * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */ -#define PNG_TEXT_COMPRESSION_NONE_WR -3 -#define PNG_TEXT_COMPRESSION_zTXt_WR -2 -#define PNG_TEXT_COMPRESSION_NONE -1 -#define PNG_TEXT_COMPRESSION_zTXt 0 -#define PNG_ITXT_COMPRESSION_NONE 1 -#define PNG_ITXT_COMPRESSION_zTXt 2 -#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */ - -/* png_time is a way to hold the time in an machine independent way. - * Two conversions are provided, both from time_t and struct tm. There - * is no portable way to convert to either of these structures, as far - * as I know. If you know of a portable way, send it to me. As a side - * note - PNG has always been Year 2000 compliant! - */ -typedef struct png_time_struct -{ - png_uint_16 year; /* full year, as in, 1995 */ - png_byte month; /* month of year, 1 - 12 */ - png_byte day; /* day of month, 1 - 31 */ - png_byte hour; /* hour of day, 0 - 23 */ - png_byte minute; /* minute of hour, 0 - 59 */ - png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ -} png_time; -typedef png_time * png_timep; -typedef const png_time * png_const_timep; -typedef png_time * * png_timepp; - -#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\ - defined(PNG_USER_CHUNKS_SUPPORTED) -/* png_unknown_chunk is a structure to hold queued chunks for which there is - * no specific support. The idea is that we can use this to queue - * up private chunks for output even though the library doesn't actually - * know about their semantics. - * - * The data in the structure is set by libpng on read and used on write. - */ -typedef struct png_unknown_chunk_t -{ - png_byte name[5]; /* Textual chunk name with '\0' terminator */ - png_byte *data; /* Data, should not be modified on read! */ - size_t size; - - /* On write 'location' must be set using the flag values listed below. - * Notice that on read it is set by libpng however the values stored have - * more bits set than are listed below. Always treat the value as a - * bitmask. On write set only one bit - setting multiple bits may cause the - * chunk to be written in multiple places. - */ - png_byte location; /* mode of operation at read time */ -} -png_unknown_chunk; - -typedef png_unknown_chunk * png_unknown_chunkp; -typedef const png_unknown_chunk * png_const_unknown_chunkp; -typedef png_unknown_chunk * * png_unknown_chunkpp; -#endif - -/* Flag values for the unknown chunk location byte. */ -#define PNG_HAVE_IHDR 0x01 -#define PNG_HAVE_PLTE 0x02 -#define PNG_AFTER_IDAT 0x08 - -/* Maximum positive integer used in PNG is (2^31)-1 */ -#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) -#define PNG_UINT_32_MAX ((png_uint_32)(-1)) -#define PNG_SIZE_MAX ((size_t)(-1)) - -/* These are constants for fixed point values encoded in the - * PNG specification manner (x100000) - */ -#define PNG_FP_1 100000 -#define PNG_FP_HALF 50000 -#define PNG_FP_MAX ((png_fixed_point)0x7fffffffL) -#define PNG_FP_MIN (-PNG_FP_MAX) - -/* These describe the color_type field in png_info. */ -/* color type masks */ -#define PNG_COLOR_MASK_PALETTE 1 -#define PNG_COLOR_MASK_COLOR 2 -#define PNG_COLOR_MASK_ALPHA 4 - -/* color types. Note that not all combinations are legal */ -#define PNG_COLOR_TYPE_GRAY 0 -#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE) -#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR) -#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA) -#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA) -/* aliases */ -#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA -#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA - -/* This is for compression type. PNG 1.0-1.2 only define the single type. */ -#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */ -#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE - -/* This is for filter type. PNG 1.0-1.2 only define the single type. */ -#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */ -#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */ -#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE - -/* These are for the interlacing type. These values should NOT be changed. */ -#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */ -#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */ -#define PNG_INTERLACE_LAST 2 /* Not a valid value */ - -/* These are for the oFFs chunk. These values should NOT be changed. */ -#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */ -#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */ -#define PNG_OFFSET_LAST 2 /* Not a valid value */ - -/* These are for the pCAL chunk. These values should NOT be changed. */ -#define PNG_EQUATION_LINEAR 0 /* Linear transformation */ -#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */ -#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */ -#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */ -#define PNG_EQUATION_LAST 4 /* Not a valid value */ - -/* These are for the sCAL chunk. These values should NOT be changed. */ -#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */ -#define PNG_SCALE_METER 1 /* meters per pixel */ -#define PNG_SCALE_RADIAN 2 /* radians per pixel */ -#define PNG_SCALE_LAST 3 /* Not a valid value */ - -/* These are for the pHYs chunk. These values should NOT be changed. */ -#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */ -#define PNG_RESOLUTION_METER 1 /* pixels/meter */ -#define PNG_RESOLUTION_LAST 2 /* Not a valid value */ - -/* These are for the sRGB chunk. These values should NOT be changed. */ -#define PNG_sRGB_INTENT_PERCEPTUAL 0 -#define PNG_sRGB_INTENT_RELATIVE 1 -#define PNG_sRGB_INTENT_SATURATION 2 -#define PNG_sRGB_INTENT_ABSOLUTE 3 -#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */ - -/* This is for text chunks */ -#define PNG_KEYWORD_MAX_LENGTH 79 - -/* Maximum number of entries in PLTE/sPLT/tRNS arrays */ -#define PNG_MAX_PALETTE_LENGTH 256 - -/* These determine if an ancillary chunk's data has been successfully read - * from the PNG header, or if the application has filled in the corresponding - * data in the info_struct to be written into the output file. The values - * of the PNG_INFO_ defines should NOT be changed. - */ -#define PNG_INFO_gAMA 0x0001U -#define PNG_INFO_sBIT 0x0002U -#define PNG_INFO_cHRM 0x0004U -#define PNG_INFO_PLTE 0x0008U -#define PNG_INFO_tRNS 0x0010U -#define PNG_INFO_bKGD 0x0020U -#define PNG_INFO_hIST 0x0040U -#define PNG_INFO_pHYs 0x0080U -#define PNG_INFO_oFFs 0x0100U -#define PNG_INFO_tIME 0x0200U -#define PNG_INFO_pCAL 0x0400U -#define PNG_INFO_sRGB 0x0800U /* GR-P, 0.96a */ -#define PNG_INFO_iCCP 0x1000U /* ESR, 1.0.6 */ -#define PNG_INFO_sPLT 0x2000U /* ESR, 1.0.6 */ -#define PNG_INFO_sCAL 0x4000U /* ESR, 1.0.6 */ -#define PNG_INFO_IDAT 0x8000U /* ESR, 1.0.6 */ -#define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */ - -/* This is used for the transformation routines, as some of them - * change these values for the row. It also should enable using - * the routines for other purposes. - */ -typedef struct png_row_info_struct -{ - png_uint_32 width; /* width of row */ - size_t rowbytes; /* number of bytes in row */ - png_byte color_type; /* color type of row */ - png_byte bit_depth; /* bit depth of row */ - png_byte channels; /* number of channels (1, 2, 3, or 4) */ - png_byte pixel_depth; /* bits per pixel (depth * channels) */ -} png_row_info; - -typedef png_row_info * png_row_infop; -typedef png_row_info * * png_row_infopp; - -/* These are the function types for the I/O functions and for the functions - * that allow the user to override the default I/O functions with his or her - * own. The png_error_ptr type should match that of user-supplied warning - * and error functions, while the png_rw_ptr type should match that of the - * user read/write data functions. Note that the 'write' function must not - * modify the buffer it is passed. The 'read' function, on the other hand, is - * expected to return the read data in the buffer. - */ -typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp)); -typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, size_t)); -typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp)); -typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32, - int)); -typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32, - int)); - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop)); -typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop)); - -/* The following callback receives png_uint_32 row_number, int pass for the - * png_bytep data of the row. When transforming an interlaced image the - * row number is the row number within the sub-image of the interlace pass, so - * the value will increase to the height of the sub-image (not the full image) - * then reset to 0 for the next pass. - * - * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to - * find the output pixel (x,y) given an interlaced sub-image pixel - * (row,col,pass). (See below for these macros.) - */ -typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep, - png_uint_32, int)); -#endif - -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) -typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop, - png_bytep)); -#endif - -#ifdef PNG_USER_CHUNKS_SUPPORTED -typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp, - png_unknown_chunkp)); -#endif -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -/* not used anywhere */ -/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */ -#endif - -#ifdef PNG_SETJMP_SUPPORTED -/* This must match the function definition in , and the application - * must include this before png.h to obtain the definition of jmp_buf. The - * function is required to be PNG_NORETURN, but this is not checked. If the - * function does return the application will crash via an abort() or similar - * system level call. - * - * If you get a warning here while building the library you may need to make - * changes to ensure that pnglibconf.h records the calling convention used by - * your compiler. This may be very difficult - try using a different compiler - * to build the library! - */ -PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef); -#endif - -/* Transform masks for the high-level interface */ -#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */ -#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */ -#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */ -#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */ -#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */ -#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */ -#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */ -#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */ -#define PNG_TRANSFORM_BGR 0x0080 /* read and write */ -#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ -#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ -#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ -#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* write only */ -/* Added to libpng-1.2.34 */ -#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER -#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */ -/* Added to libpng-1.4.0 */ -#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ -/* Added to libpng-1.5.4 */ -#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */ -#if INT_MAX >= 0x8000 /* else this might break */ -#define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */ -#endif - -/* Flags for MNG supported features */ -#define PNG_FLAG_MNG_EMPTY_PLTE 0x01 -#define PNG_FLAG_MNG_FILTER_64 0x04 -#define PNG_ALL_MNG_FEATURES 0x05 - -/* NOTE: prior to 1.5 these functions had no 'API' style declaration, - * this allowed the zlib default functions to be used on Windows - * platforms. In 1.5 the zlib default malloc (which just calls malloc and - * ignores the first argument) should be completely compatible with the - * following. - */ -typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp, - png_alloc_size_t)); -typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp)); - -/* Section 4: exported functions - * Here are the function definitions most commonly used. This is not - * the place to find out how to use libpng. See libpng-manual.txt for the - * full explanation, see example.c for the summary. This just provides - * a simple one line description of the use of each function. - * - * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in - * pngconf.h and in the *.dfn files in the scripts directory. - * - * PNG_EXPORT(ordinal, type, name, (args)); - * - * ordinal: ordinal that is used while building - * *.def files. The ordinal value is only - * relevant when preprocessing png.h with - * the *.dfn files for building symbol table - * entries, and are removed by pngconf.h. - * type: return type of the function - * name: function name - * args: function arguments, with types - * - * When we wish to append attributes to a function prototype we use - * the PNG_EXPORTA() macro instead. - * - * PNG_EXPORTA(ordinal, type, name, (args), attributes); - * - * ordinal, type, name, and args: same as in PNG_EXPORT(). - * attributes: function attributes - */ - -/* Returns the version number of the library */ -PNG_EXPORT(1, png_uint_32, png_access_version_number, (void)); - -/* Tell lib we have already handled the first magic bytes. - * Handling more than 8 bytes from the beginning of the file is an error. - */ -PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes)); - -/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a - * PNG file. Returns zero if the supplied bytes match the 8-byte PNG - * signature, and non-zero otherwise. Having num_to_check == 0 or - * start > 7 will always fail (ie return non-zero). - */ -PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start, - size_t num_to_check)); - -/* Simple signature checking function. This is the same as calling - * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). - */ -#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n)) - -/* Allocate and initialize png_ptr struct for reading, and any other memory. */ -PNG_EXPORTA(4, png_structp, png_create_read_struct, - (png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn), - PNG_ALLOCATED); - -/* Allocate and initialize png_ptr struct for writing, and any other memory */ -PNG_EXPORTA(5, png_structp, png_create_write_struct, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn), - PNG_ALLOCATED); - -PNG_EXPORT(6, size_t, png_get_compression_buffer_size, - (png_const_structrp png_ptr)); - -PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr, - size_t size)); - -/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp - * match up. - */ -#ifdef PNG_SETJMP_SUPPORTED -/* This function returns the jmp_buf built in to *png_ptr. It must be - * supplied with an appropriate 'longjmp' function to use on that jmp_buf - * unless the default error function is overridden in which case NULL is - * acceptable. The size of the jmp_buf is checked against the actual size - * allocated by the library - the call will return NULL on a mismatch - * indicating an ABI mismatch. - */ -PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr, - png_longjmp_ptr longjmp_fn, size_t jmp_buf_size)); -# define png_jmpbuf(png_ptr) \ - (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf)))) -#else -# define png_jmpbuf(png_ptr) \ - (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP) -#endif -/* This function should be used by libpng applications in place of - * longjmp(png_ptr->jmpbuf, val). If longjmp_fn() has been set, it - * will use it; otherwise it will call PNG_ABORT(). This function was - * added in libpng-1.5.0. - */ -PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val), - PNG_NORETURN); - -#ifdef PNG_READ_SUPPORTED -/* Reset the compression stream */ -PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED); -#endif - -/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ -#ifdef PNG_USER_MEM_SUPPORTED -PNG_EXPORTA(11, png_structp, png_create_read_struct_2, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn, - png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), - PNG_ALLOCATED); -PNG_EXPORTA(12, png_structp, png_create_write_struct_2, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn, - png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), - PNG_ALLOCATED); -#endif - -/* Write the PNG file signature. */ -PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr)); - -/* Write a PNG chunk - size, type, (optional) data, CRC. */ -PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep - chunk_name, png_const_bytep data, size_t length)); - -/* Write the start of a PNG chunk - length and chunk name. */ -PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr, - png_const_bytep chunk_name, png_uint_32 length)); - -/* Write the data of a PNG chunk started with png_write_chunk_start(). */ -PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr, - png_const_bytep data, size_t length)); - -/* Finish a chunk started with png_write_chunk_start() (includes CRC). */ -PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr)); - -/* Allocate and initialize the info structure */ -PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr), - PNG_ALLOCATED); - -/* DEPRECATED: this function allowed init structures to be created using the - * default allocation method (typically malloc). Use is deprecated in 1.6.0 and - * the API will be removed in the future. - */ -PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr, - size_t png_info_struct_size), PNG_DEPRECATED); - -/* Writes all the PNG information before the image. */ -PNG_EXPORT(20, void, png_write_info_before_PLTE, - (png_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(21, void, png_write_info, - (png_structrp png_ptr, png_const_inforp info_ptr)); - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the information before the actual image data. */ -PNG_EXPORT(22, void, png_read_info, - (png_structrp png_ptr, png_inforp info_ptr)); -#endif - -#ifdef PNG_TIME_RFC1123_SUPPORTED - /* Convert to a US string format: there is no localization support in this - * routine. The original implementation used a 29 character buffer in - * png_struct, this will be removed in future versions. - */ -#if PNG_LIBPNG_VER < 10700 -/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */ -PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr, - png_const_timep ptime),PNG_DEPRECATED); -#endif -PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29], - png_const_timep ptime)); -#endif - -#ifdef PNG_CONVERT_tIME_SUPPORTED -/* Convert from a struct tm to png_time */ -PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime, - const struct tm * ttime)); - -/* Convert from time_t to png_time. Uses gmtime() */ -PNG_EXPORT(25, void, png_convert_from_time_t, (png_timep ptime, time_t ttime)); -#endif /* CONVERT_tIME */ - -#ifdef PNG_READ_EXPAND_SUPPORTED -/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ -PNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr)); -PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr)); -PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr)); -PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_EXPAND_16_SUPPORTED -/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion - * of a tRNS chunk if present. - */ -PNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -/* Use blue, green, red order for pixels. */ -PNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -/* Expand the grayscale to 24-bit RGB if necessary. */ -PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -/* Reduce RGB to grayscale. */ -#define PNG_ERROR_ACTION_NONE 1 -#define PNG_ERROR_ACTION_WARN 2 -#define PNG_ERROR_ACTION_ERROR 3 -#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/ - -PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr, - int error_action, double red, double green)) -PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr, - int error_action, png_fixed_point red, png_fixed_point green)) - -PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp - png_ptr)); -#endif - -#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED -PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth, - png_colorp palette)); -#endif - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -/* How the alpha channel is interpreted - this affects how the color channels - * of a PNG file are returned to the calling application when an alpha channel, - * or a tRNS chunk in a palette file, is present. - * - * This has no effect on the way pixels are written into a PNG output - * datastream. The color samples in a PNG datastream are never premultiplied - * with the alpha samples. - * - * The default is to return data according to the PNG specification: the alpha - * channel is a linear measure of the contribution of the pixel to the - * corresponding composited pixel, and the color channels are unassociated - * (not premultiplied). The gamma encoded color channels must be scaled - * according to the contribution and to do this it is necessary to undo - * the encoding, scale the color values, perform the composition and re-encode - * the values. This is the 'PNG' mode. - * - * The alternative is to 'associate' the alpha with the color information by - * storing color channel values that have been scaled by the alpha. - * image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes - * (the latter being the two common names for associated alpha color channels). - * - * For the 'OPTIMIZED' mode, a pixel is treated as opaque only if the alpha - * value is equal to the maximum value. - * - * The final choice is to gamma encode the alpha channel as well. This is - * broken because, in practice, no implementation that uses this choice - * correctly undoes the encoding before handling alpha composition. Use this - * choice only if other serious errors in the software or hardware you use - * mandate it; the typical serious error is for dark halos to appear around - * opaque areas of the composited PNG image because of arithmetic overflow. - * - * The API function png_set_alpha_mode specifies which of these choices to use - * with an enumerated 'mode' value and the gamma of the required output: - */ -#define PNG_ALPHA_PNG 0 /* according to the PNG standard */ -#define PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */ -#define PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */ -#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */ -#define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */ -#define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */ - -PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode, - double output_gamma)) -PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr, - int mode, png_fixed_point output_gamma)) -#endif - -#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED) -/* The output_gamma value is a screen gamma in libpng terminology: it expresses - * how to decode the output values, not how they are encoded. - */ -#define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */ -#define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */ -#define PNG_GAMMA_sRGB 220000 /* Television standards--matches sRGB gamma */ -#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */ -#endif - -/* The following are examples of calls to png_set_alpha_mode to achieve the - * required overall gamma correction and, where necessary, alpha - * premultiplication. - * - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); - * This is the default libpng handling of the alpha channel - it is not - * pre-multiplied into the color components. In addition the call states - * that the output is for a sRGB system and causes all PNG files without gAMA - * chunks to be assumed to be encoded using sRGB. - * - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); - * In this case the output is assumed to be something like an sRGB conformant - * display preceded by a power-law lookup table of power 1.45. This is how - * early Mac systems behaved. - * - * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR); - * This is the classic Jim Blinn approach and will work in academic - * environments where everything is done by the book. It has the shortcoming - * of assuming that input PNG data with no gamma information is linear - this - * is unlikely to be correct unless the PNG files where generated locally. - * Most of the time the output precision will be so low as to show - * significant banding in dark areas of the image. - * - * png_set_expand_16(pp); - * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB); - * This is a somewhat more realistic Jim Blinn inspired approach. PNG files - * are assumed to have the sRGB encoding if not marked with a gamma value and - * the output is always 16 bits per component. This permits accurate scaling - * and processing of the data. If you know that your input PNG files were - * generated locally you might need to replace PNG_DEFAULT_sRGB with the - * correct value for your system. - * - * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB); - * If you just need to composite the PNG image onto an existing background - * and if you control the code that does this you can use the optimization - * setting. In this case you just copy completely opaque pixels to the - * output. For pixels that are not completely transparent (you just skip - * those) you do the composition math using png_composite or png_composite_16 - * below then encode the resultant 8-bit or 16-bit values to match the output - * encoding. - * - * Other cases - * If neither the PNG nor the standard linear encoding work for you because - * of the software or hardware you use then you have a big problem. The PNG - * case will probably result in halos around the image. The linear encoding - * will probably result in a washed out, too bright, image (it's actually too - * contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably - * substantially reduce the halos. Alternatively try: - * - * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB); - * This option will also reduce the halos, but there will be slight dark - * halos round the opaque parts of the image where the background is light. - * In the OPTIMIZED mode the halos will be light halos where the background - * is dark. Take your pick - the halos are unavoidable unless you can get - * your hardware/software fixed! (The OPTIMIZED approach is slightly - * faster.) - * - * When the default gamma of PNG files doesn't match the output gamma. - * If you have PNG files with no gamma information png_set_alpha_mode allows - * you to provide a default gamma, but it also sets the output gamma to the - * matching value. If you know your PNG files have a gamma that doesn't - * match the output you can take advantage of the fact that - * png_set_alpha_mode always sets the output gamma but only sets the PNG - * default if it is not already set: - * - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB); - * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); - * The first call sets both the default and the output gamma values, the - * second call overrides the output gamma without changing the default. This - * is easier than achieving the same effect with png_set_gamma. You must use - * PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will - * fire if more than one call to png_set_alpha_mode and png_set_background is - * made in the same read operation, however multiple calls with PNG_ALPHA_PNG - * are ignored. - */ - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -PNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) -PNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) -PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) -/* Add a filler byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */ -PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler, - int flags)); -/* The values of the PNG_FILLER_ defines should NOT be changed */ -# define PNG_FILLER_BEFORE 0 -# define PNG_FILLER_AFTER 1 -/* Add an alpha byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */ -PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr, - png_uint_32 filler, int flags)); -#endif /* READ_FILLER || WRITE_FILLER */ - -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -/* Swap bytes in 16-bit depth files. */ -PNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) -/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ -PNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ - defined(PNG_WRITE_PACKSWAP_SUPPORTED) -/* Swap packing order of pixels in bytes. */ -PNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) -/* Converts files to legal bit depths. */ -PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p - true_bits)); -#endif - -#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ - defined(PNG_WRITE_INTERLACING_SUPPORTED) -/* Have the code handle the interlacing. Returns the number of passes. - * MUST be called before png_read_update_info or png_start_read_image, - * otherwise it will not have the desired effect. Note that it is still - * necessary to call png_read_row or png_read_rows png_get_image_height - * times for each pass. -*/ -PNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr)); -#endif - -#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -/* Invert monochrome files */ -PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_BACKGROUND_SUPPORTED -/* Handle alpha and tRNS by replacing with a background color. Prior to - * libpng-1.5.4 this API must not be called before the PNG file header has been - * read. Doing so will result in unexpected behavior and possible warnings or - * errors if the PNG file contains a bKGD chunk. - */ -PNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, double background_gamma)) -PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, png_fixed_point background_gamma)) -#endif -#ifdef PNG_READ_BACKGROUND_SUPPORTED -# define PNG_BACKGROUND_GAMMA_UNKNOWN 0 -# define PNG_BACKGROUND_GAMMA_SCREEN 1 -# define PNG_BACKGROUND_GAMMA_FILE 2 -# define PNG_BACKGROUND_GAMMA_UNIQUE 3 -#endif - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -/* Scale a 16-bit depth file down to 8-bit, accurately. */ -PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -#define PNG_READ_16_TO_8_SUPPORTED /* Name prior to 1.5.4 */ -/* Strip the second byte of information from a 16-bit depth file. */ -PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr)); -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -/* Turn on quantizing, and reduce the palette to the number of colors - * available. - */ -PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr, - png_colorp palette, int num_palette, int maximum_colors, - png_const_uint_16p histogram, int full_quantize)); -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED -/* The threshold on gamma processing is configurable but hard-wired into the - * library. The following is the floating point variant. - */ -#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001) - -/* Handle gamma correction. Screen_gamma=(display_exponent). - * NOTE: this API simply sets the screen and file gamma values. It will - * therefore override the value for gamma in a PNG file if it is called after - * the file header has been read - use with care - call before reading the PNG - * file for best results! - * - * These routines accept the same gamma values as png_set_alpha_mode (described - * above). The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either - * API (floating point or fixed.) Notice, however, that the 'file_gamma' value - * is the inverse of a 'screen gamma' value. - */ -PNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr, - double screen_gamma, double override_file_gamma)) -PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr, - png_fixed_point screen_gamma, png_fixed_point override_file_gamma)) -#endif - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -/* Set how many lines between output flushes - 0 for no flushing */ -PNG_EXPORT(51, void, png_set_flush, (png_structrp png_ptr, int nrows)); -/* Flush the current PNG output buffer */ -PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr)); -#endif - -/* Optional update palette with requested transformations */ -PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr)); - -/* Optional call to update the users info structure */ -PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr, - png_inforp info_ptr)); - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read one or more rows of image data. */ -PNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row, - png_bytepp display_row, png_uint_32 num_rows)); -#endif - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read a row of data. */ -PNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row, - png_bytep display_row)); -#endif - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the whole image into memory at once. */ -PNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image)); -#endif - -/* Write a row of image data */ -PNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr, - png_const_bytep row)); - -/* Write a few rows of image data: (*row) is not written; however, the type - * is declared as writeable to maintain compatibility with previous versions - * of libpng and to allow the 'display_row' array from read_rows to be passed - * unchanged to write_rows. - */ -PNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row, - png_uint_32 num_rows)); - -/* Write the image data */ -PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image)); - -/* Write the end of the PNG file. */ -PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr, - png_inforp info_ptr)); - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the end of the PNG file. */ -PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr)); -#endif - -/* Free any memory associated with the png_info_struct */ -PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr, - png_infopp info_ptr_ptr)); - -/* Free any memory associated with the png_struct and the png_info_structs */ -PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr, - png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); - -/* Free any memory associated with the png_struct and the png_info_structs */ -PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr, - png_infopp info_ptr_ptr)); - -/* Set the libpng method of handling chunk CRC errors */ -PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action, - int ancil_action)); - -/* Values for png_set_crc_action() say how to handle CRC errors in - * ancillary and critical chunks, and whether to use the data contained - * therein. Note that it is impossible to "discard" data in a critical - * chunk. For versions prior to 0.90, the action was always error/quit, - * whereas in version 0.90 and later, the action for CRC errors in ancillary - * chunks is warn/discard. These values should NOT be changed. - * - * value action:critical action:ancillary - */ -#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */ -#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */ -#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */ -#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */ -#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */ -#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */ - -#ifdef PNG_WRITE_SUPPORTED -/* These functions give the user control over the scan-line filtering in - * libpng and the compression methods used by zlib. These functions are - * mainly useful for testing, as the defaults should work with most users. - * Those users who are tight on memory or want faster performance at the - * expense of compression can modify them. See the compression library - * header file (zlib.h) for an explination of the compression functions. - */ - -/* Set the filtering method(s) used by libpng. Currently, the only valid - * value for "method" is 0. - */ -PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method, - int filters)); -#endif /* WRITE */ - -/* Flags for png_set_filter() to say which filters to use. The flags - * are chosen so that they don't conflict with real filter types - * below, in case they are supplied instead of the #defined constants. - * These values should NOT be changed. - */ -#define PNG_NO_FILTERS 0x00 -#define PNG_FILTER_NONE 0x08 -#define PNG_FILTER_SUB 0x10 -#define PNG_FILTER_UP 0x20 -#define PNG_FILTER_AVG 0x40 -#define PNG_FILTER_PAETH 0x80 -#define PNG_FAST_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP) -#define PNG_ALL_FILTERS (PNG_FAST_FILTERS | PNG_FILTER_AVG | PNG_FILTER_PAETH) - -/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now. - * These defines should NOT be changed. - */ -#define PNG_FILTER_VALUE_NONE 0 -#define PNG_FILTER_VALUE_SUB 1 -#define PNG_FILTER_VALUE_UP 2 -#define PNG_FILTER_VALUE_AVG 3 -#define PNG_FILTER_VALUE_PAETH 4 -#define PNG_FILTER_VALUE_LAST 5 - -#ifdef PNG_WRITE_SUPPORTED -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */ -PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr, - int heuristic_method, int num_weights, png_const_doublep filter_weights, - png_const_doublep filter_costs)) -PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, - (png_structrp png_ptr, int heuristic_method, int num_weights, - png_const_fixed_point_p filter_weights, - png_const_fixed_point_p filter_costs)) -#endif /* WRITE_WEIGHTED_FILTER */ - -/* The following are no longer used and will be removed from libpng-1.7: */ -#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */ -#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */ -#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */ -#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */ - -/* Set the library compression level. Currently, valid values range from - * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 - * (0 - no compression, 9 - "maximal" compression). Note that tests have - * shown that zlib compression levels 3-6 usually perform as well as level 9 - * for PNG images, and do considerably fewer caclulations. In the future, - * these values may not correspond directly to the zlib compression levels. - */ -#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED -PNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr, - int level)); - -PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr, - int mem_level)); - -PNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp png_ptr, - int strategy)); - -/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a - * smaller value of window_bits if it can do so safely. - */ -PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr, - int window_bits)); - -PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr, - int method)); -#endif /* WRITE_CUSTOMIZE_COMPRESSION */ - -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED -/* Also set zlib parameters for compressing non-IDAT chunks */ -PNG_EXPORT(222, void, png_set_text_compression_level, (png_structrp png_ptr, - int level)); - -PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr, - int mem_level)); - -PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp png_ptr, - int strategy)); - -/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a - * smaller value of window_bits if it can do so safely. - */ -PNG_EXPORT(225, void, png_set_text_compression_window_bits, - (png_structrp png_ptr, int window_bits)); - -PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr, - int method)); -#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ -#endif /* WRITE */ - -/* These next functions are called for input/output, memory, and error - * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, - * and call standard C I/O routines such as fread(), fwrite(), and - * fprintf(). These functions can be made to use other I/O routines - * at run time for those applications that need to handle I/O in a - * different manner by calling png_set_???_fn(). See libpng-manual.txt for - * more information. - */ - -#ifdef PNG_STDIO_SUPPORTED -/* Initialize the input/output for the PNG file to the default functions. */ -PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp)); -#endif - -/* Replace the (error and abort), and warning functions with user - * supplied functions. If no messages are to be printed you must still - * write and use replacement functions. The replacement error_fn should - * still do a longjmp to the last setjmp location if you are using this - * method of error handling. If error_fn or warning_fn is NULL, the - * default function will be used. - */ - -PNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr, - png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); - -/* Return the user pointer associated with the error functions */ -PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr)); - -/* Replace the default data output functions with a user supplied one(s). - * If buffered output is not used, then output_flush_fn can be set to NULL. - * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time - * output_flush_fn will be ignored (and thus can be NULL). - * It is probably a mistake to use NULL for output_flush_fn if - * write_data_fn is not also NULL unless you have built libpng with - * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's - * default flush function, which uses the standard *FILE structure, will - * be used. - */ -PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); - -/* Replace the default data input function with a user supplied one. */ -PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr read_data_fn)); - -/* Return the user pointer associated with the I/O functions */ -PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr)); - -PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr, - png_read_status_ptr read_row_fn)); - -PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr, - png_write_status_ptr write_row_fn)); - -#ifdef PNG_USER_MEM_SUPPORTED -/* Replace the default memory allocation functions with user supplied one(s). */ -PNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn)); -/* Return the user pointer associated with the memory functions */ -PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr)); -#endif - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr, - png_user_transform_ptr read_user_transform_fn)); -#endif - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr, - png_user_transform_ptr write_user_transform_fn)); -#endif - -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -PNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr, - png_voidp user_transform_ptr, int user_transform_depth, - int user_transform_channels)); -/* Return the user pointer associated with the user transform functions */ -PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr, - (png_const_structrp png_ptr)); -#endif - -#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED -/* Return information about the row currently being processed. Note that these - * APIs do not fail but will return unexpected results if called outside a user - * transform callback. Also note that when transforming an interlaced image the - * row number is the row number within the sub-image of the interlace pass, so - * the value will increase to the height of the sub-image (not the full image) - * then reset to 0 for the next pass. - * - * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to - * find the output pixel (x,y) given an interlaced sub-image pixel - * (row,col,pass). (See below for these macros.) - */ -PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp)); -PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp)); -#endif - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -/* This callback is called only for *unknown* chunks. If - * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known - * chunks to be treated as unknown, however in this case the callback must do - * any processing required by the chunk (e.g. by calling the appropriate - * png_set_ APIs.) - * - * There is no write support - on write, by default, all the chunks in the - * 'unknown' list are written in the specified position. - * - * The integer return from the callback function is interpreted thus: - * - * negative: An error occurred; png_chunk_error will be called. - * zero: The chunk was not handled, the chunk will be saved. A critical - * chunk will cause an error at this point unless it is to be saved. - * positive: The chunk was handled, libpng will ignore/discard it. - * - * See "INTERACTION WITH USER CHUNK CALLBACKS" below for important notes about - * how this behavior will change in libpng 1.7 - */ -PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr, - png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); -#endif - -#ifdef PNG_USER_CHUNKS_SUPPORTED -PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr)); -#endif - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -/* Sets the function callbacks for the push reader, and a pointer to a - * user-defined structure available to the callback functions. - */ -PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr, - png_voidp progressive_ptr, png_progressive_info_ptr info_fn, - png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn)); - -/* Returns the user pointer associated with the push read functions */ -PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, - (png_const_structrp png_ptr)); - -/* Function to be called when data becomes available */ -PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr, - png_inforp info_ptr, png_bytep buffer, size_t buffer_size)); - -/* A function which may be called *only* within png_process_data to stop the - * processing of any more data. The function returns the number of bytes - * remaining, excluding any that libpng has cached internally. A subsequent - * call to png_process_data must supply these bytes again. If the argument - * 'save' is set to true the routine will first save all the pending data and - * will always return 0. - */ -PNG_EXPORT(219, size_t, png_process_data_pause, (png_structrp, int save)); - -/* A function which may be called *only* outside (after) a call to - * png_process_data. It returns the number of bytes of data to skip in the - * input. Normally it will return 0, but if it returns a non-zero value the - * application must skip than number of bytes of input data and pass the - * following data to the next call to png_process_data. - */ -PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp)); - -/* Function that combines rows. 'new_row' is a flag that should come from - * the callback and be non-NULL if anything needs to be done; the library - * stores its own version of the new data internally and ignores the passed - * in value. - */ -PNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr, - png_bytep old_row, png_const_bytep new_row)); -#endif /* PROGRESSIVE_READ */ - -PNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED); -/* Added at libpng version 1.4.0 */ -PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED); - -/* Added at libpng version 1.2.4 */ -PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED); - -/* Frees a pointer allocated by png_malloc() */ -PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr)); - -/* Free data that was allocated internally */ -PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr, - png_inforp info_ptr, png_uint_32 free_me, int num)); - -/* Reassign responsibility for freeing existing data, whether allocated - * by libpng or by the application; this works on the png_info structure passed - * in, it does not change the state for other png_info structures. - * - * It is unlikely that this function works correctly as of 1.6.0 and using it - * may result either in memory leaks or double free of allocated data. - */ -PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr, - png_inforp info_ptr, int freer, png_uint_32 mask)); - -/* Assignments for png_data_freer */ -#define PNG_DESTROY_WILL_FREE_DATA 1 -#define PNG_SET_WILL_FREE_DATA 1 -#define PNG_USER_WILL_FREE_DATA 2 -/* Flags for png_ptr->free_me and info_ptr->free_me */ -#define PNG_FREE_HIST 0x0008U -#define PNG_FREE_ICCP 0x0010U -#define PNG_FREE_SPLT 0x0020U -#define PNG_FREE_ROWS 0x0040U -#define PNG_FREE_PCAL 0x0080U -#define PNG_FREE_SCAL 0x0100U -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -# define PNG_FREE_UNKN 0x0200U -#endif -/* PNG_FREE_LIST 0x0400U removed in 1.6.0 because it is ignored */ -#define PNG_FREE_PLTE 0x1000U -#define PNG_FREE_TRNS 0x2000U -#define PNG_FREE_TEXT 0x4000U -#define PNG_FREE_EXIF 0x8000U /* Added at libpng-1.6.31 */ -#define PNG_FREE_ALL 0xffffU -#define PNG_FREE_MUL 0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ - -#ifdef PNG_USER_MEM_SUPPORTED -PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr, - png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED); -PNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr, - png_voidp ptr), PNG_DEPRECATED); -#endif - -#ifdef PNG_ERROR_TEXT_SUPPORTED -/* Fatal error in PNG image of libpng - can't continue */ -PNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr, - png_const_charp error_message), PNG_NORETURN); - -/* The same, but the chunk name is prepended to the error string. */ -PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr, - png_const_charp error_message), PNG_NORETURN); - -#else -/* Fatal error in PNG image of libpng - can't continue */ -PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN); -# define png_error(s1,s2) png_err(s1) -# define png_chunk_error(s1,s2) png_err(s1) -#endif - -#ifdef PNG_WARNINGS_SUPPORTED -/* Non-fatal error in libpng. Can continue, but may have a problem. */ -PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr, - png_const_charp warning_message)); - -/* Non-fatal error in libpng, chunk name is prepended to message. */ -PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr, - png_const_charp warning_message)); -#else -# define png_warning(s1,s2) ((void)(s1)) -# define png_chunk_warning(s1,s2) ((void)(s1)) -#endif - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -/* Benign error in libpng. Can continue, but may have a problem. - * User can choose whether to handle as a fatal error or as a warning. */ -PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr, - png_const_charp warning_message)); - -#ifdef PNG_READ_SUPPORTED -/* Same, chunk name is prepended to message (only during read) */ -PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr, - png_const_charp warning_message)); -#endif - -PNG_EXPORT(109, void, png_set_benign_errors, - (png_structrp png_ptr, int allowed)); -#else -# ifdef PNG_ALLOW_BENIGN_ERRORS -# define png_benign_error png_warning -# define png_chunk_benign_error png_chunk_warning -# else -# define png_benign_error png_error -# define png_chunk_benign_error png_chunk_error -# endif -#endif - -/* The png_set_ functions are for storing values in the png_info_struct. - * Similarly, the png_get_ calls are used to read values from the - * png_info_struct, either storing the parameters in the passed variables, or - * setting pointers into the png_info_struct where the data is stored. The - * png_get_ functions return a non-zero value if the data was available - * in info_ptr, or return zero and do not change any of the parameters if the - * data was not available. - * - * These functions should be used instead of directly accessing png_info - * to avoid problems with future changes in the size and internal layout of - * png_info_struct. - */ -/* Returns "flag" if chunk data is valid in info_ptr. */ -PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_uint_32 flag)); - -/* Returns number of bytes needed to hold a transformed row. */ -PNG_EXPORT(111, size_t, png_get_rowbytes, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -#ifdef PNG_INFO_IMAGE_SUPPORTED -/* Returns row_pointers, which is an array of pointers to scanlines that was - * returned from png_read_png(). - */ -PNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Set row_pointers, which is an array of pointers to scanlines for use - * by png_write_png(). - */ -PNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr, - png_inforp info_ptr, png_bytepp row_pointers)); -#endif - -/* Returns number of color channels in image. */ -PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -#ifdef PNG_EASY_ACCESS_SUPPORTED -/* Returns image width in pixels. */ -PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image height in pixels. */ -PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image bit_depth. */ -PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image color_type. */ -PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image filter_type. */ -PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image interlace_type. */ -PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image compression_type. */ -PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); - -/* Returns image resolution in pixels per meter, from pHYs chunk data. */ -PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -/* Returns pixel aspect ratio, computed from pHYs chunk data. */ -PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) -PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) - -/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ -PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(128, png_int_32, png_get_x_offset_microns, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); -PNG_EXPORT(129, png_int_32, png_get_y_offset_microns, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -#endif /* EASY_ACCESS */ - -#ifdef PNG_READ_SUPPORTED -/* Returns pointer to signature string read from PNG header */ -PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr, - png_const_inforp info_ptr)); -#endif - -#ifdef PNG_bKGD_SUPPORTED -PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr, - png_inforp info_ptr, png_color_16p *background)); -#endif - -#ifdef PNG_bKGD_SUPPORTED -PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_color_16p background)); -#endif - -#ifdef PNG_cHRM_SUPPORTED -PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr, - png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x, - double *red_y, double *green_x, double *green_y, double *blue_x, - double *blue_y)) -PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr, - png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z, - double *green_X, double *green_Y, double *green_Z, double *blue_X, - double *blue_Y, double *blue_Z)) -PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *int_white_x, png_fixed_point *int_white_y, - png_fixed_point *int_red_x, png_fixed_point *int_red_y, - png_fixed_point *int_green_x, png_fixed_point *int_green_y, - png_fixed_point *int_blue_x, png_fixed_point *int_blue_y)) -PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *int_red_X, png_fixed_point *int_red_Y, - png_fixed_point *int_red_Z, png_fixed_point *int_green_X, - png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, - png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, - png_fixed_point *int_blue_Z)) -#endif - -#ifdef PNG_cHRM_SUPPORTED -PNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr, - png_inforp info_ptr, - double white_x, double white_y, double red_x, double red_y, double green_x, - double green_y, double blue_x, double blue_y)) -PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr, - png_inforp info_ptr, double red_X, double red_Y, double red_Z, - double green_X, double green_Y, double green_Z, double blue_X, - double blue_Y, double blue_Z)) -PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr, - png_inforp info_ptr, png_fixed_point int_white_x, - png_fixed_point int_white_y, png_fixed_point int_red_x, - png_fixed_point int_red_y, png_fixed_point int_green_x, - png_fixed_point int_green_y, png_fixed_point int_blue_x, - png_fixed_point int_blue_y)) -PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr, - png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y, - png_fixed_point int_red_Z, png_fixed_point int_green_X, - png_fixed_point int_green_Y, png_fixed_point int_green_Z, - png_fixed_point int_blue_X, png_fixed_point int_blue_Y, - png_fixed_point int_blue_Z)) -#endif - -#ifdef PNG_eXIf_SUPPORTED -PNG_EXPORT(246, png_uint_32, png_get_eXIf, (png_const_structrp png_ptr, - png_inforp info_ptr, png_bytep *exif)); -PNG_EXPORT(247, void, png_set_eXIf, (png_const_structrp png_ptr, - png_inforp info_ptr, png_bytep exif)); - -PNG_EXPORT(248, png_uint_32, png_get_eXIf_1, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_uint_32 *num_exif, png_bytep *exif)); -PNG_EXPORT(249, void, png_set_eXIf_1, (png_const_structrp png_ptr, - png_inforp info_ptr, png_uint_32 num_exif, png_bytep exif)); -#endif - -#ifdef PNG_gAMA_SUPPORTED -PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr, - png_const_inforp info_ptr, double *file_gamma)) -PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *int_file_gamma)) -#endif - -#ifdef PNG_gAMA_SUPPORTED -PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr, - png_inforp info_ptr, double file_gamma)) -PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr, - png_inforp info_ptr, png_fixed_point int_file_gamma)) -#endif - -#ifdef PNG_hIST_SUPPORTED -PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr, - png_inforp info_ptr, png_uint_16p *hist)); -PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_uint_16p hist)); -#endif - -PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height, - int *bit_depth, int *color_type, int *interlace_method, - int *compression_method, int *filter_method)); - -PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr, - png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_method, int compression_method, - int filter_method)); - -#ifdef PNG_oFFs_SUPPORTED -PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, - int *unit_type)); -#endif - -#ifdef PNG_oFFs_SUPPORTED -PNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr, - png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y, - int unit_type)); -#endif - -#ifdef PNG_pCAL_SUPPORTED -PNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr, - png_inforp info_ptr, png_charp *purpose, png_int_32 *X0, - png_int_32 *X1, int *type, int *nparams, png_charp *units, - png_charpp *params)); -#endif - -#ifdef PNG_pCAL_SUPPORTED -PNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1, - int type, int nparams, png_const_charp units, png_charpp params)); -#endif - -#ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, - int *unit_type)); -#endif - -#ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr, - png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); -#endif - -PNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr, - png_inforp info_ptr, png_colorp *palette, int *num_palette)); - -PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr, - png_inforp info_ptr, png_const_colorp palette, int num_palette)); - -#ifdef PNG_sBIT_SUPPORTED -PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr, - png_inforp info_ptr, png_color_8p *sig_bit)); -#endif - -#ifdef PNG_sBIT_SUPPORTED -PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_color_8p sig_bit)); -#endif - -#ifdef PNG_sRGB_SUPPORTED -PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr, - png_const_inforp info_ptr, int *file_srgb_intent)); -#endif - -#ifdef PNG_sRGB_SUPPORTED -PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr, - png_inforp info_ptr, int srgb_intent)); -PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr, - png_inforp info_ptr, int srgb_intent)); -#endif - -#ifdef PNG_iCCP_SUPPORTED -PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr, - png_inforp info_ptr, png_charpp name, int *compression_type, - png_bytepp profile, png_uint_32 *proflen)); -#endif - -#ifdef PNG_iCCP_SUPPORTED -PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_charp name, int compression_type, - png_const_bytep profile, png_uint_32 proflen)); -#endif - -#ifdef PNG_sPLT_SUPPORTED -PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr, - png_inforp info_ptr, png_sPLT_tpp entries)); -#endif - -#ifdef PNG_sPLT_SUPPORTED -PNG_EXPORT(161, void, png_set_sPLT, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)); -#endif - -#ifdef PNG_TEXT_SUPPORTED -/* png_get_text also returns the number of text chunks in *num_text */ -PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr, - png_inforp info_ptr, png_textp *text_ptr, int *num_text)); -#endif - -/* Note while png_set_text() will accept a structure whose text, - * language, and translated keywords are NULL pointers, the structure - * returned by png_get_text will always contain regular - * zero-terminated C strings. They might be empty strings but - * they will never be NULL pointers. - */ - -#ifdef PNG_TEXT_SUPPORTED -PNG_EXPORT(163, void, png_set_text, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_textp text_ptr, int num_text)); -#endif - -#ifdef PNG_tIME_SUPPORTED -PNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr, - png_inforp info_ptr, png_timep *mod_time)); -#endif - -#ifdef PNG_tIME_SUPPORTED -PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_timep mod_time)); -#endif - -#ifdef PNG_tRNS_SUPPORTED -PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr, - png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans, - png_color_16p *trans_color)); -#endif - -#ifdef PNG_tRNS_SUPPORTED -PNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr, - png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans, - png_const_color_16p trans_color)); -#endif - -#ifdef PNG_sCAL_SUPPORTED -PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr, - png_const_inforp info_ptr, int *unit, double *width, double *height)) -#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ - defined(PNG_FLOATING_POINT_SUPPORTED) -/* NOTE: this API is currently implemented using floating point arithmetic, - * consequently it can only be used on systems with floating point support. - * In any case the range of values supported by png_fixed_point is small and it - * is highly recommended that png_get_sCAL_s be used instead. - */ -PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, - png_fixed_point *width, png_fixed_point *height)) -#endif -PNG_EXPORT(169, png_uint_32, png_get_sCAL_s, - (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, - png_charpp swidth, png_charpp sheight)); - -PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr, - png_inforp info_ptr, int unit, double width, double height)) -PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr, - png_inforp info_ptr, int unit, png_fixed_point width, - png_fixed_point height)) -PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr, - png_inforp info_ptr, int unit, - png_const_charp swidth, png_const_charp sheight)); -#endif /* sCAL */ - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -/* Provide the default handling for all unknown chunks or, optionally, for - * specific unknown chunks. - * - * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was - * ignored and the default was used, the per-chunk setting only had an effect on - * write. If you wish to have chunk-specific handling on read in code that must - * work on earlier versions you must use a user chunk callback to specify the - * desired handling (keep or discard.) - * - * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below. The - * parameter is interpreted as follows: - * - * READ: - * PNG_HANDLE_CHUNK_AS_DEFAULT: - * Known chunks: do normal libpng processing, do not keep the chunk (but - * see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED) - * Unknown chunks: for a specific chunk use the global default, when used - * as the default discard the chunk data. - * PNG_HANDLE_CHUNK_NEVER: - * Discard the chunk data. - * PNG_HANDLE_CHUNK_IF_SAFE: - * Keep the chunk data if the chunk is not critical else raise a chunk - * error. - * PNG_HANDLE_CHUNK_ALWAYS: - * Keep the chunk data. - * - * If the chunk data is saved it can be retrieved using png_get_unknown_chunks, - * below. Notice that specifying "AS_DEFAULT" as a global default is equivalent - * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks - * it simply resets the behavior to the libpng default. - * - * INTERACTION WITH USER CHUNK CALLBACKS: - * The per-chunk handling is always used when there is a png_user_chunk_ptr - * callback and the callback returns 0; the chunk is then always stored *unless* - * it is critical and the per-chunk setting is other than ALWAYS. Notice that - * the global default is *not* used in this case. (In effect the per-chunk - * value is incremented to at least IF_SAFE.) - * - * IMPORTANT NOTE: this behavior will change in libpng 1.7 - the global and - * per-chunk defaults will be honored. If you want to preserve the current - * behavior when your callback returns 0 you must set PNG_HANDLE_CHUNK_IF_SAFE - * as the default - if you don't do this libpng 1.6 will issue a warning. - * - * If you want unhandled unknown chunks to be discarded in libpng 1.6 and - * earlier simply return '1' (handled). - * - * PNG_HANDLE_AS_UNKNOWN_SUPPORTED: - * If this is *not* set known chunks will always be handled by libpng and - * will never be stored in the unknown chunk list. Known chunks listed to - * png_set_keep_unknown_chunks will have no effect. If it is set then known - * chunks listed with a keep other than AS_DEFAULT will *never* be processed - * by libpng, in addition critical chunks must either be processed by the - * callback or saved. - * - * The IHDR and IEND chunks must not be listed. Because this turns off the - * default handling for chunks that would otherwise be recognized the - * behavior of libpng transformations may well become incorrect! - * - * WRITE: - * When writing chunks the options only apply to the chunks specified by - * png_set_unknown_chunks (below), libpng will *always* write known chunks - * required by png_set_ calls and will always write the core critical chunks - * (as required for PLTE). - * - * Each chunk in the png_set_unknown_chunks list is looked up in the - * png_set_keep_unknown_chunks list to find the keep setting, this is then - * interpreted as follows: - * - * PNG_HANDLE_CHUNK_AS_DEFAULT: - * Write safe-to-copy chunks and write other chunks if the global - * default is set to _ALWAYS, otherwise don't write this chunk. - * PNG_HANDLE_CHUNK_NEVER: - * Do not write the chunk. - * PNG_HANDLE_CHUNK_IF_SAFE: - * Write the chunk if it is safe-to-copy, otherwise do not write it. - * PNG_HANDLE_CHUNK_ALWAYS: - * Write the chunk. - * - * Note that the default behavior is effectively the opposite of the read case - - * in read unknown chunks are not stored by default, in write they are written - * by default. Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different - * - on write the safe-to-copy bit is checked, on read the critical bit is - * checked and on read if the chunk is critical an error will be raised. - * - * num_chunks: - * =========== - * If num_chunks is positive, then the "keep" parameter specifies the manner - * for handling only those chunks appearing in the chunk_list array, - * otherwise the chunk list array is ignored. - * - * If num_chunks is 0 the "keep" parameter specifies the default behavior for - * unknown chunks, as described above. - * - * If num_chunks is negative, then the "keep" parameter specifies the manner - * for handling all unknown chunks plus all chunks recognized by libpng - * except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to - * be processed by libpng. - */ -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr, - int keep, png_const_bytep chunk_list, int num_chunks)); -#endif /* HANDLE_AS_UNKNOWN */ - -/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned; - * the result is therefore true (non-zero) if special handling is required, - * false for the default handling. - */ -PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr, - png_const_bytep chunk_name)); -#endif /* SET_UNKNOWN_CHUNKS */ - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr, - png_inforp info_ptr, png_const_unknown_chunkp unknowns, - int num_unknowns)); - /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added - * unknowns to the location currently stored in the png_struct. This is - * invariably the wrong value on write. To fix this call the following API - * for each chunk in the list with the correct location. If you know your - * code won't be compiled on earlier versions you can rely on - * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing - * the correct thing. - */ - -PNG_EXPORT(175, void, png_set_unknown_chunk_location, - (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location)); - -PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr, - png_inforp info_ptr, png_unknown_chunkpp entries)); -#endif - -/* Png_free_data() will turn off the "valid" flag for anything it frees. - * If you need to turn it off for a chunk that your application has freed, - * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); - */ -PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr, - png_inforp info_ptr, int mask)); - -#ifdef PNG_INFO_IMAGE_SUPPORTED -/* The "params" pointer is currently not used and is for future expansion. */ -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr, - int transforms, png_voidp params)); -#endif -#ifdef PNG_WRITE_SUPPORTED -PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr, - int transforms, png_voidp params)); -#endif -#endif - -PNG_EXPORT(180, png_const_charp, png_get_copyright, - (png_const_structrp png_ptr)); -PNG_EXPORT(181, png_const_charp, png_get_header_ver, - (png_const_structrp png_ptr)); -PNG_EXPORT(182, png_const_charp, png_get_header_version, - (png_const_structrp png_ptr)); -PNG_EXPORT(183, png_const_charp, png_get_libpng_ver, - (png_const_structrp png_ptr)); - -#ifdef PNG_MNG_FEATURES_SUPPORTED -PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr, - png_uint_32 mng_features_permitted)); -#endif - -/* For use in png_set_keep_unknown, added to version 1.2.6 */ -#define PNG_HANDLE_CHUNK_AS_DEFAULT 0 -#define PNG_HANDLE_CHUNK_NEVER 1 -#define PNG_HANDLE_CHUNK_IF_SAFE 2 -#define PNG_HANDLE_CHUNK_ALWAYS 3 -#define PNG_HANDLE_CHUNK_LAST 4 - -/* Strip the prepended error numbers ("#nnn ") from error and warning - * messages before passing them to the error or warning handler. - */ -#ifdef PNG_ERROR_NUMBERS_SUPPORTED -PNG_EXPORT(185, void, png_set_strip_error_numbers, (png_structrp png_ptr, - png_uint_32 strip_mode)); -#endif - -/* Added in libpng-1.2.6 */ -#ifdef PNG_SET_USER_LIMITS_SUPPORTED -PNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr, - png_uint_32 user_width_max, png_uint_32 user_height_max)); -PNG_EXPORT(187, png_uint_32, png_get_user_width_max, - (png_const_structrp png_ptr)); -PNG_EXPORT(188, png_uint_32, png_get_user_height_max, - (png_const_structrp png_ptr)); -/* Added in libpng-1.4.0 */ -PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr, - png_uint_32 user_chunk_cache_max)); -PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max, - (png_const_structrp png_ptr)); -/* Added in libpng-1.4.1 */ -PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr, - png_alloc_size_t user_chunk_cache_max)); -PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max, - (png_const_structrp png_ptr)); -#endif - -#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) -PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch, - (png_const_structrp png_ptr, png_const_inforp info_ptr)); - -PNG_FP_EXPORT(196, float, png_get_x_offset_inches, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) -#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ -PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) -#endif - -PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr, - png_const_inforp info_ptr)) -#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ -PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed, - (png_const_structrp png_ptr, png_const_inforp info_ptr)) -#endif - -# ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr, - png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, - int *unit_type)); -# endif /* pHYs */ -#endif /* INCH_CONVERSIONS */ - -/* Added in libpng-1.4.0 */ -#ifdef PNG_IO_STATE_SUPPORTED -PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr)); - -/* Removed from libpng 1.6; use png_get_io_chunk_type. */ -PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr), - PNG_DEPRECATED) - -PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type, - (png_const_structrp png_ptr)); - -/* The flags returned by png_get_io_state() are the following: */ -# define PNG_IO_NONE 0x0000 /* no I/O at this moment */ -# define PNG_IO_READING 0x0001 /* currently reading */ -# define PNG_IO_WRITING 0x0002 /* currently writing */ -# define PNG_IO_SIGNATURE 0x0010 /* currently at the file signature */ -# define PNG_IO_CHUNK_HDR 0x0020 /* currently at the chunk header */ -# define PNG_IO_CHUNK_DATA 0x0040 /* currently at the chunk data */ -# define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */ -# define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */ -# define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ -#endif /* IO_STATE */ - -/* Interlace support. The following macros are always defined so that if - * libpng interlace handling is turned off the macros may be used to handle - * interlaced images within the application. - */ -#define PNG_INTERLACE_ADAM7_PASSES 7 - -/* Two macros to return the first row and first column of the original, - * full, image which appears in a given pass. 'pass' is in the range 0 - * to 6 and the result is in the range 0 to 7. - */ -#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7) -#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7) - -/* A macro to return the offset between pixels in the output row for a pair of - * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that - * follows. Note that ROW_OFFSET is the offset from one row to the next whereas - * COL_OFFSET is from one column to the next, within a row. - */ -#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8) -#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1)) - -/* Two macros to help evaluate the number of rows or columns in each - * pass. This is expressed as a shift - effectively log2 of the number or - * rows or columns in each 8x8 tile of the original image. - */ -#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) -#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) - -/* Hence two macros to determine the number of rows or columns in a given - * pass of an image given its height or width. In fact these macros may - * return non-zero even though the sub-image is empty, because the other - * dimension may be empty for a small image. - */ -#define PNG_PASS_ROWS(height, pass) (((height)+(((1<>PNG_PASS_ROW_SHIFT(pass)) -#define PNG_PASS_COLS(width, pass) (((width)+(((1<>PNG_PASS_COL_SHIFT(pass)) - -/* For the reader row callbacks (both progressive and sequential) it is - * necessary to find the row in the output image given a row in an interlaced - * image, so two more macros: - */ -#define PNG_ROW_FROM_PASS_ROW(y_in, pass) \ - (((y_in)<>(((7-(off))-(pass))<<2)) & 0xF) | \ - ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0)) - -#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ - ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) -#define PNG_COL_IN_INTERLACE_PASS(x, pass) \ - ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) - -#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED -/* With these routines we avoid an integer divide, which will be slower on - * most machines. However, it does take more operations than the corresponding - * divide method, so it may be slower on a few RISC systems. There are two - * shifts (by 8 or 16 bits) and an addition, versus a single integer divide. - * - * Note that the rounding factors are NOT supposed to be the same! 128 and - * 32768 are correct for the NODIV code; 127 and 32767 are correct for the - * standard method. - * - * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] - */ - - /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ - -# define png_composite(composite, fg, alpha, bg) \ - { \ - png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \ - * (png_uint_16)(alpha) \ - + (png_uint_16)(bg)*(png_uint_16)(255 \ - - (png_uint_16)(alpha)) + 128); \ - (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); \ - } - -# define png_composite_16(composite, fg, alpha, bg) \ - { \ - png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \ - * (png_uint_32)(alpha) \ - + (png_uint_32)(bg)*(65535 \ - - (png_uint_32)(alpha)) + 32768); \ - (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); \ - } - -#else /* Standard method using integer division */ - -# define png_composite(composite, fg, alpha, bg) \ - (composite) = \ - (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) + \ - (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ - 127) / 255)) - -# define png_composite_16(composite, fg, alpha, bg) \ - (composite) = \ - (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \ - (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \ - 32767) / 65535)) -#endif /* READ_COMPOSITE_NODIV */ - -#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED -PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf)); -PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf)); -PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf)); -#endif - -PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr, - png_const_bytep buf)); -/* No png_get_int_16 -- may be added if there's a real need for it. */ - -/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */ -#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED -PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i)); -#endif -#ifdef PNG_SAVE_INT_32_SUPPORTED -PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i)); -#endif - -/* Place a 16-bit number into a buffer in PNG byte order. - * The parameter is declared unsigned int, not png_uint_16, - * just to avoid potential problems on pre-ANSI C compilers. - */ -#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED -PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i)); -/* No png_save_int_16 -- may be added if there's a real need for it. */ -#endif - -#ifdef PNG_USE_READ_MACROS -/* Inline macros to do direct reads of bytes from the input buffer. - * The png_get_int_32() routine assumes we are using two's complement - * format for negative values, which is almost certainly true. - */ -# define PNG_get_uint_32(buf) \ - (((png_uint_32)(*(buf)) << 24) + \ - ((png_uint_32)(*((buf) + 1)) << 16) + \ - ((png_uint_32)(*((buf) + 2)) << 8) + \ - ((png_uint_32)(*((buf) + 3)))) - - /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the - * function) incorrectly returned a value of type png_uint_32. - */ -# define PNG_get_uint_16(buf) \ - ((png_uint_16) \ - (((unsigned int)(*(buf)) << 8) + \ - ((unsigned int)(*((buf) + 1))))) - -# define PNG_get_int_32(buf) \ - ((png_int_32)((*(buf) & 0x80) \ - ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \ - : (png_int_32)png_get_uint_32(buf))) - -/* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h, - * but defining a macro name prefixed with PNG_PREFIX. - */ -# ifndef PNG_PREFIX -# define png_get_uint_32(buf) PNG_get_uint_32(buf) -# define png_get_uint_16(buf) PNG_get_uint_16(buf) -# define png_get_int_32(buf) PNG_get_int_32(buf) -# endif -#else -# ifdef PNG_PREFIX - /* No macros; revert to the (redefined) function */ -# define PNG_get_uint_32 (png_get_uint_32) -# define PNG_get_uint_16 (png_get_uint_16) -# define PNG_get_int_32 (png_get_int_32) -# endif -#endif - -#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED -PNG_EXPORT(242, void, png_set_check_for_invalid_index, - (png_structrp png_ptr, int allowed)); -# ifdef PNG_GET_PALETTE_MAX_SUPPORTED -PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr, - png_const_infop info_ptr)); -# endif -#endif /* CHECK_FOR_INVALID_INDEX */ - -/******************************************************************************* - * Section 5: SIMPLIFIED API - ******************************************************************************* - * - * Please read the documentation in libpng-manual.txt (TODO: write said - * documentation) if you don't understand what follows. - * - * The simplified API hides the details of both libpng and the PNG file format - * itself. It allows PNG files to be read into a very limited number of - * in-memory bitmap formats or to be written from the same formats. If these - * formats do not accommodate your needs then you can, and should, use the more - * sophisticated APIs above - these support a wide variety of in-memory formats - * and a wide variety of sophisticated transformations to those formats as well - * as a wide variety of APIs to manipulate ancillary information. - * - * To read a PNG file using the simplified API: - * - * 1) Declare a 'png_image' structure (see below) on the stack, set the - * version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL - * (this is REQUIRED, your program may crash if you don't do it.) - * 2) Call the appropriate png_image_begin_read... function. - * 3) Set the png_image 'format' member to the required sample format. - * 4) Allocate a buffer for the image and, if required, the color-map. - * 5) Call png_image_finish_read to read the image and, if required, the - * color-map into your buffers. - * - * There are no restrictions on the format of the PNG input itself; all valid - * color types, bit depths, and interlace methods are acceptable, and the - * input image is transformed as necessary to the requested in-memory format - * during the png_image_finish_read() step. The only caveat is that if you - * request a color-mapped image from a PNG that is full-color or makes - * complex use of an alpha channel the transformation is extremely lossy and the - * result may look terrible. - * - * To write a PNG file using the simplified API: - * - * 1) Declare a 'png_image' structure on the stack and memset() it to all zero. - * 2) Initialize the members of the structure that describe the image, setting - * the 'format' member to the format of the image samples. - * 3) Call the appropriate png_image_write... function with a pointer to the - * image and, if necessary, the color-map to write the PNG data. - * - * png_image is a structure that describes the in-memory format of an image - * when it is being read or defines the in-memory format of an image that you - * need to write: - */ -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) - -#define PNG_IMAGE_VERSION 1 - -typedef struct png_control *png_controlp; -typedef struct -{ - png_controlp opaque; /* Initialize to NULL, free with png_image_free */ - png_uint_32 version; /* Set to PNG_IMAGE_VERSION */ - png_uint_32 width; /* Image width in pixels (columns) */ - png_uint_32 height; /* Image height in pixels (rows) */ - png_uint_32 format; /* Image format as defined below */ - png_uint_32 flags; /* A bit mask containing informational flags */ - png_uint_32 colormap_entries; - /* Number of entries in the color-map */ - - /* In the event of an error or warning the following field will be set to a - * non-zero value and the 'message' field will contain a '\0' terminated - * string with the libpng error or warning message. If both warnings and - * an error were encountered, only the error is recorded. If there - * are multiple warnings, only the first one is recorded. - * - * The upper 30 bits of this value are reserved, the low two bits contain - * a value as follows: - */ -# define PNG_IMAGE_WARNING 1 -# define PNG_IMAGE_ERROR 2 - /* - * The result is a two-bit code such that a value more than 1 indicates - * a failure in the API just called: - * - * 0 - no warning or error - * 1 - warning - * 2 - error - * 3 - error preceded by warning - */ -# define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1) - - png_uint_32 warning_or_error; - - char message[64]; -} png_image, *png_imagep; - -/* The samples of the image have one to four channels whose components have - * original values in the range 0 to 1.0: - * - * 1: A single gray or luminance channel (G). - * 2: A gray/luminance channel and an alpha channel (GA). - * 3: Three red, green, blue color channels (RGB). - * 4: Three color channels and an alpha channel (RGBA). - * - * The components are encoded in one of two ways: - * - * a) As a small integer, value 0..255, contained in a single byte. For the - * alpha channel the original value is simply value/255. For the color or - * luminance channels the value is encoded according to the sRGB specification - * and matches the 8-bit format expected by typical display devices. - * - * The color/gray channels are not scaled (pre-multiplied) by the alpha - * channel and are suitable for passing to color management software. - * - * b) As a value in the range 0..65535, contained in a 2-byte integer. All - * channels can be converted to the original value by dividing by 65535; all - * channels are linear. Color channels use the RGB encoding (RGB end-points) of - * the sRGB specification. This encoding is identified by the - * PNG_FORMAT_FLAG_LINEAR flag below. - * - * When the simplified API needs to convert between sRGB and linear colorspaces, - * the actual sRGB transfer curve defined in the sRGB specification (see the - * article at ) is used, not the gamma=1/2.2 - * approximation used elsewhere in libpng. - * - * When an alpha channel is present it is expected to denote pixel coverage - * of the color or luminance channels and is returned as an associated alpha - * channel: the color/gray channels are scaled (pre-multiplied) by the alpha - * value. - * - * The samples are either contained directly in the image data, between 1 and 8 - * bytes per pixel according to the encoding, or are held in a color-map indexed - * by bytes in the image data. In the case of a color-map the color-map entries - * are individual samples, encoded as above, and the image data has one byte per - * pixel to select the relevant sample from the color-map. - */ - -/* PNG_FORMAT_* - * - * #defines to be used in png_image::format. Each #define identifies a - * particular layout of sample data and, if present, alpha values. There are - * separate defines for each of the two component encodings. - * - * A format is built up using single bit flag values. All combinations are - * valid. Formats can be built up from the flag values or you can use one of - * the predefined values below. When testing formats always use the FORMAT_FLAG - * macros to test for individual features - future versions of the library may - * add new flags. - * - * When reading or writing color-mapped images the format should be set to the - * format of the entries in the color-map then png_image_{read,write}_colormap - * called to read or write the color-map and set the format correctly for the - * image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly! - * - * NOTE: libpng can be built with particular features disabled. If you see - * compiler errors because the definition of one of the following flags has been - * compiled out it is because libpng does not have the required support. It is - * possible, however, for the libpng configuration to enable the format on just - * read or just write; in that case you may see an error at run time. You can - * guard against this by checking for the definition of the appropriate - * "_SUPPORTED" macro, one of: - * - * PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED - */ -#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */ -#define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */ -#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2-byte channels else 1-byte */ -#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */ - -#ifdef PNG_FORMAT_BGR_SUPPORTED -# define PNG_FORMAT_FLAG_BGR 0x10U /* BGR colors, else order is RGB */ -#endif - -#ifdef PNG_FORMAT_AFIRST_SUPPORTED -# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */ -#endif - -#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U /* alpha channel is associated */ - -/* Commonly used formats have predefined macros. - * - * First the single byte (sRGB) formats: - */ -#define PNG_FORMAT_GRAY 0 -#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA -#define PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST) -#define PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR -#define PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR) -#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA) -#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST) -#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA) -#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST) - -/* Then the linear 2-byte formats. When naming these "Y" is used to - * indicate a luminance (gray) channel. - */ -#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR -#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA) -#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR) -#define PNG_FORMAT_LINEAR_RGB_ALPHA \ - (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA) - -/* With color-mapped formats the image data is one byte for each pixel, the byte - * is an index into the color-map which is formatted as above. To obtain a - * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP - * to one of the above definitions, or you can use one of the definitions below. - */ -#define PNG_FORMAT_RGB_COLORMAP (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_BGR_COLORMAP (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP) -#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP) - -/* PNG_IMAGE macros - * - * These are convenience macros to derive information from a png_image - * structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the - * actual image sample values - either the entries in the color-map or the - * pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values - * for the pixels and will always return 1 for color-mapped formats. The - * remaining macros return information about the rows in the image and the - * complete image. - * - * NOTE: All the macros that take a png_image::format parameter are compile time - * constants if the format parameter is, itself, a constant. Therefore these - * macros can be used in array declarations and case labels where required. - * Similarly the macros are also pre-processor constants (sizeof is not used) so - * they can be used in #if tests. - * - * First the information about the samples. - */ -#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\ - (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1) - /* Return the total number of channels in a given format: 1..4 */ - -#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\ - ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1) - /* Return the size in bytes of a single component of a pixel or color-map - * entry (as appropriate) in the image: 1 or 2. - */ - -#define PNG_IMAGE_SAMPLE_SIZE(fmt)\ - (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)) - /* This is the size of the sample data for one sample. If the image is - * color-mapped it is the size of one color-map entry (and image pixels are - * one byte in size), otherwise it is the size of one image pixel. - */ - -#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\ - (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256) - /* The maximum size of the color-map required by the format expressed in a - * count of components. This can be used to compile-time allocate a - * color-map: - * - * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)]; - * - * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)]; - * - * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the - * information from one of the png_image_begin_read_ APIs and dynamically - * allocate the required memory. - */ - -/* Corresponding information about the pixels */ -#define PNG_IMAGE_PIXEL_(test,fmt)\ - (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt)) - -#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\ - PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt) - /* The number of separate channels (components) in a pixel; 1 for a - * color-mapped image. - */ - -#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\ - PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt) - /* The size, in bytes, of each component in a pixel; 1 for a color-mapped - * image. - */ - -#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt) - /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */ - -/* Information about the whole row, or whole image */ -#define PNG_IMAGE_ROW_STRIDE(image)\ - (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width) - /* Return the total number of components in a single row of the image; this - * is the minimum 'row stride', the minimum count of components between each - * row. For a color-mapped image this is the minimum number of bytes in a - * row. - * - * WARNING: this macro overflows for some images with more than one component - * and very large image widths. libpng will refuse to process an image where - * this macro would overflow. - */ - -#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\ - (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride)) - /* Return the size, in bytes, of an image buffer given a png_image and a row - * stride - the number of components to leave space for in each row. - * - * WARNING: this macro overflows a 32-bit integer for some large PNG images, - * libpng will refuse to process an image where such an overflow would occur. - */ - -#define PNG_IMAGE_SIZE(image)\ - PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image)) - /* Return the size, in bytes, of the image in memory given just a png_image; - * the row stride is the minimum stride required for the image. - */ - -#define PNG_IMAGE_COLORMAP_SIZE(image)\ - (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries) - /* Return the size, in bytes, of the color-map of this image. If the image - * format is not a color-map format this will return a size sufficient for - * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if - * you don't want to allocate a color-map in this case. - */ - -/* PNG_IMAGE_FLAG_* - * - * Flags containing additional information about the image are held in the - * 'flags' field of png_image. - */ -#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01 - /* This indicates that the RGB values of the in-memory bitmap do not - * correspond to the red, green and blue end-points defined by sRGB. - */ - -#define PNG_IMAGE_FLAG_FAST 0x02 - /* On write emphasise speed over compression; the resultant PNG file will be - * larger but will be produced significantly faster, particular for large - * images. Do not use this option for images which will be distributed, only - * used it when producing intermediate files that will be read back in - * repeatedly. For a typical 24-bit image the option will double the read - * speed at the cost of increasing the image size by 25%, however for many - * more compressible images the PNG file can be 10 times larger with only a - * slight speed gain. - */ - -#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04 - /* On read if the image is a 16-bit per component image and there is no gAMA - * or sRGB chunk assume that the components are sRGB encoded. Notice that - * images output by the simplified API always have gamma information; setting - * this flag only affects the interpretation of 16-bit images from an - * external source. It is recommended that the application expose this flag - * to the user; the user can normally easily recognize the difference between - * linear and sRGB encoding. This flag has no effect on write - the data - * passed to the write APIs must have the correct encoding (as defined - * above.) - * - * If the flag is not set (the default) input 16-bit per component data is - * assumed to be linear. - * - * NOTE: the flag can only be set after the png_image_begin_read_ call, - * because that call initializes the 'flags' field. - */ - -#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -/* READ APIs - * --------- - * - * The png_image passed to the read APIs must have been initialized by setting - * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.) - */ -#ifdef PNG_STDIO_SUPPORTED -PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image, - const char *file_name)); - /* The named file is opened for read and the image header is filled in - * from the PNG header in the file. - */ - -PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image, - FILE* file)); - /* The PNG header is read from the stdio FILE object. */ -#endif /* STDIO */ - -PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image, - png_const_voidp memory, size_t size)); - /* The PNG header is read from the given memory buffer. */ - -PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image, - png_const_colorp background, void *buffer, png_int_32 row_stride, - void *colormap)); - /* Finish reading the image into the supplied buffer and clean up the - * png_image structure. - * - * row_stride is the step, in byte or 2-byte units as appropriate, - * between adjacent rows. A positive stride indicates that the top-most row - * is first in the buffer - the normal top-down arrangement. A negative - * stride indicates that the bottom-most row is first in the buffer. - * - * background need only be supplied if an alpha channel must be removed from - * a png_byte format and the removal is to be done by compositing on a solid - * color; otherwise it may be NULL and any composition will be done directly - * onto the buffer. The value is an sRGB color to use for the background, - * for grayscale output the green channel is used. - * - * background must be supplied when an alpha channel must be removed from a - * single byte color-mapped output format, in other words if: - * - * 1) The original format from png_image_begin_read_from_* had - * PNG_FORMAT_FLAG_ALPHA set. - * 2) The format set by the application does not. - * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and - * PNG_FORMAT_FLAG_LINEAR *not* set. - * - * For linear output removing the alpha channel is always done by compositing - * on black and background is ignored. - * - * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set. It must - * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE. - * image->colormap_entries will be updated to the actual number of entries - * written to the colormap; this may be less than the original value. - */ - -PNG_EXPORT(238, void, png_image_free, (png_imagep image)); - /* Free any data allocated by libpng in image->opaque, setting the pointer to - * NULL. May be called at any time after the structure is initialized. - */ -#endif /* SIMPLIFIED_READ */ - -#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED -/* WRITE APIS - * ---------- - * For write you must initialize a png_image structure to describe the image to - * be written. To do this use memset to set the whole structure to 0 then - * initialize fields describing your image. - * - * version: must be set to PNG_IMAGE_VERSION - * opaque: must be initialized to NULL - * width: image width in pixels - * height: image height in rows - * format: the format of the data (image and color-map) you wish to write - * flags: set to 0 unless one of the defined flags applies; set - * PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB - * values do not correspond to the colors in sRGB. - * colormap_entries: set to the number of entries in the color-map (0 to 256) - */ -#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED -PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image, - const char *file, int convert_to_8bit, const void *buffer, - png_int_32 row_stride, const void *colormap)); - /* Write the image to the named file. */ - -PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file, - int convert_to_8_bit, const void *buffer, png_int_32 row_stride, - const void *colormap)); - /* Write the image to the given (FILE*). */ -#endif /* SIMPLIFIED_WRITE_STDIO */ - -/* With all write APIs if image is in one of the linear formats with 16-bit - * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG - * gamma encoded according to the sRGB specification, otherwise a 16-bit linear - * encoded PNG file is written. - * - * With color-mapped data formats the colormap parameter point to a color-map - * with at least image->colormap_entries encoded in the specified format. If - * the format is linear the written PNG color-map will be converted to sRGB - * regardless of the convert_to_8_bit flag. - * - * With all APIs row_stride is handled as in the read APIs - it is the spacing - * from one row to the next in component sized units (1 or 2 bytes) and if - * negative indicates a bottom-up row layout in the buffer. If row_stride is - * zero, libpng will calculate it for you from the image width and number of - * channels. - * - * Note that the write API does not support interlacing, sub-8-bit pixels or - * most ancillary chunks. If you need to write text chunks (e.g. for copyright - * notices) you need to use one of the other APIs. - */ - -PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory, - png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8_bit, - const void *buffer, png_int_32 row_stride, const void *colormap)); - /* Write the image to the given memory buffer. The function both writes the - * whole PNG data stream to *memory and updates *memory_bytes with the count - * of bytes written. - * - * 'memory' may be NULL. In this case *memory_bytes is not read however on - * success the number of bytes which would have been written will still be - * stored in *memory_bytes. On failure *memory_bytes will contain 0. - * - * If 'memory' is not NULL it must point to memory[*memory_bytes] of - * writeable memory. - * - * If the function returns success memory[*memory_bytes] (if 'memory' is not - * NULL) contains the written PNG data. *memory_bytes will always be less - * than or equal to the original value. - * - * If the function returns false and *memory_bytes was not changed an error - * occurred during write. If *memory_bytes was changed, or is not 0 if - * 'memory' was NULL, the write would have succeeded but for the memory - * buffer being too small. *memory_bytes contains the required number of - * bytes and will be bigger that the original value. - */ - -#define png_image_write_get_memory_size(image, size, convert_to_8_bit, buffer,\ - row_stride, colormap)\ - png_image_write_to_memory(&(image), 0, &(size), convert_to_8_bit, buffer,\ - row_stride, colormap) - /* Return the amount of memory in 'size' required to compress this image. - * The png_image structure 'image' must be filled in as in the above - * function and must not be changed before the actual write call, the buffer - * and all other parameters must also be identical to that in the final - * write call. The 'size' variable need not be initialized. - * - * NOTE: the macro returns true/false, if false is returned 'size' will be - * set to zero and the write failed and probably will fail if tried again. - */ - -/* You can pre-allocate the buffer by making sure it is of sufficient size - * regardless of the amount of compression achieved. The buffer size will - * always be bigger than the original image and it will never be filled. The - * following macros are provided to assist in allocating the buffer. - */ -#define PNG_IMAGE_DATA_SIZE(image) (PNG_IMAGE_SIZE(image)+(image).height) - /* The number of uncompressed bytes in the PNG byte encoding of the image; - * uncompressing the PNG IDAT data will give this number of bytes. - * - * NOTE: while PNG_IMAGE_SIZE cannot overflow for an image in memory this - * macro can because of the extra bytes used in the PNG byte encoding. You - * need to avoid this macro if your image size approaches 2^30 in width or - * height. The same goes for the remainder of these macros; they all produce - * bigger numbers than the actual in-memory image size. - */ -#ifndef PNG_ZLIB_MAX_SIZE -# define PNG_ZLIB_MAX_SIZE(b) ((b)+(((b)+7U)>>3)+(((b)+63U)>>6)+11U) - /* An upper bound on the number of compressed bytes given 'b' uncompressed - * bytes. This is based on deflateBounds() in zlib; different - * implementations of zlib compression may conceivably produce more data so - * if your zlib implementation is not zlib itself redefine this macro - * appropriately. - */ -#endif - -#define PNG_IMAGE_COMPRESSED_SIZE_MAX(image)\ - PNG_ZLIB_MAX_SIZE((png_alloc_size_t)PNG_IMAGE_DATA_SIZE(image)) - /* An upper bound on the size of the data in the PNG IDAT chunks. */ - -#define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\ - ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\ - (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\ - 12U+3U*(image).colormap_entries/*PLTE data*/+\ - (((image).format&PNG_FORMAT_FLAG_ALPHA)?\ - 12U/*tRNS*/+(image).colormap_entries:0U):0U)+\ - 12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size)) - /* A helper for the following macro; if your compiler cannot handle the - * following macro use this one with the result of - * PNG_IMAGE_COMPRESSED_SIZE_MAX(image) as the second argument (most - * compilers should handle this just fine.) - */ - -#define PNG_IMAGE_PNG_SIZE_MAX(image)\ - PNG_IMAGE_PNG_SIZE_MAX_(image, PNG_IMAGE_COMPRESSED_SIZE_MAX(image)) - /* An upper bound on the total length of the PNG data stream for 'image'. - * The result is of type png_alloc_size_t, on 32-bit systems this may - * overflow even though PNG_IMAGE_DATA_SIZE does not overflow; the write will - * run out of buffer space but return a corrected size which should work. - */ -#endif /* SIMPLIFIED_WRITE */ -/******************************************************************************* - * END OF SIMPLIFIED API - ******************************************************************************/ -#endif /* SIMPLIFIED_{READ|WRITE} */ - -/******************************************************************************* - * Section 6: IMPLEMENTATION OPTIONS - ******************************************************************************* - * - * Support for arbitrary implementation-specific optimizations. The API allows - * particular options to be turned on or off. 'Option' is the number of the - * option and 'onoff' is 0 (off) or non-0 (on). The value returned is given - * by the PNG_OPTION_ defines below. - * - * HARDWARE: normally hardware capabilities, such as the Intel SSE instructions, - * are detected at run time, however sometimes it may be impossible - * to do this in user mode, in which case it is necessary to discover - * the capabilities in an OS specific way. Such capabilities are - * listed here when libpng has support for them and must be turned - * ON by the application if present. - * - * SOFTWARE: sometimes software optimizations actually result in performance - * decrease on some architectures or systems, or with some sets of - * PNG images. 'Software' options allow such optimizations to be - * selected at run time. - */ -#ifdef PNG_SET_OPTION_SUPPORTED -#ifdef PNG_ARM_NEON_API_SUPPORTED -# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */ -#endif -#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */ -#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */ -#ifdef PNG_MIPS_MSA_API_SUPPORTED -# define PNG_MIPS_MSA 6 /* HARDWARE: MIPS Msa SIMD instructions supported */ -#endif -#define PNG_IGNORE_ADLER32 8 -#ifdef PNG_POWERPC_VSX_API_SUPPORTED -# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions supported */ -#endif -#define PNG_OPTION_NEXT 12 /* Next option - numbers must be even */ - -/* Return values: NOTE: there are four values and 'off' is *not* zero */ -#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ -#define PNG_OPTION_INVALID 1 /* Option number out of range */ -#define PNG_OPTION_OFF 2 -#define PNG_OPTION_ON 3 - -PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option, - int onoff)); -#endif /* SET_OPTION */ - -/******************************************************************************* - * END OF HARDWARE AND SOFTWARE OPTIONS - ******************************************************************************/ - -/* Maintainer: Put new public prototypes here ^, in libpng.3, in project - * defs, and in scripts/symbols.def. - */ - -/* The last ordinal number (this is the *last* one already used; the next - * one to use is one more than this.) - */ -#ifdef PNG_EXPORT_LAST_ORDINAL - PNG_EXPORT_LAST_ORDINAL(249); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* PNG_VERSION_INFO_ONLY */ -/* Do not put anything past this line */ -#endif /* PNG_H */ diff --git a/extern/libpng/pngconf.h b/extern/libpng/pngconf.h deleted file mode 100644 index 927a769db..000000000 --- a/extern/libpng/pngconf.h +++ /dev/null @@ -1,623 +0,0 @@ - -/* pngconf.h - machine-configurable file for libpng - * - * libpng version 1.6.37 - * - * Copyright (c) 2018-2019 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * Any machine specific code is near the front of this file, so if you - * are configuring libpng for a machine, you may want to read the section - * starting here down to where it starts to typedef png_color, png_text, - * and png_info. - */ - -#ifndef PNGCONF_H -#define PNGCONF_H - -#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */ - -/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C - * compiler for correct compilation. The following header files are required by - * the standard. If your compiler doesn't provide these header files, or they - * do not match the standard, you will need to provide/improve them. - */ -#include -#include - -/* Library header files. These header files are all defined by ISOC90; libpng - * expects conformant implementations, however, an ISOC90 conformant system need - * not provide these header files if the functionality cannot be implemented. - * In this case it will be necessary to disable the relevant parts of libpng in - * the build of pnglibconf.h. - * - * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not - * include this unnecessary header file. - */ - -#ifdef PNG_STDIO_SUPPORTED - /* Required for the definition of FILE: */ -# include -#endif - -#ifdef PNG_SETJMP_SUPPORTED - /* Required for the definition of jmp_buf and the declaration of longjmp: */ -# include -#endif - -#ifdef PNG_CONVERT_tIME_SUPPORTED - /* Required for struct tm: */ -# include -#endif - -#endif /* PNG_BUILDING_SYMBOL_TABLE */ - -/* Prior to 1.6.0, it was possible to turn off 'const' in declarations, - * using PNG_NO_CONST. This is no longer supported. - */ -#define PNG_CONST const /* backward compatibility only */ - -/* This controls optimization of the reading of 16-bit and 32-bit - * values from PNG files. It can be set on a per-app-file basis: it - * just changes whether a macro is used when the function is called. - * The library builder sets the default; if read functions are not - * built into the library the macro implementation is forced on. - */ -#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED -# define PNG_USE_READ_MACROS -#endif -#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS) -# if PNG_DEFAULT_READ_MACROS -# define PNG_USE_READ_MACROS -# endif -#endif - -/* COMPILER SPECIFIC OPTIONS. - * - * These options are provided so that a variety of difficult compilers - * can be used. Some are fixed at build time (e.g. PNG_API_RULE - * below) but still have compiler specific implementations, others - * may be changed on a per-file basis when compiling against libpng. - */ - -/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect - * against legacy (pre ISOC90) compilers that did not understand function - * prototypes. It is not required for modern C compilers. - */ -#ifndef PNGARG -# define PNGARG(arglist) arglist -#endif - -/* Function calling conventions. - * ============================= - * Normally it is not necessary to specify to the compiler how to call - * a function - it just does it - however on x86 systems derived from - * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems - * and some others) there are multiple ways to call a function and the - * default can be changed on the compiler command line. For this reason - * libpng specifies the calling convention of every exported function and - * every function called via a user supplied function pointer. This is - * done in this file by defining the following macros: - * - * PNGAPI Calling convention for exported functions. - * PNGCBAPI Calling convention for user provided (callback) functions. - * PNGCAPI Calling convention used by the ANSI-C library (required - * for longjmp callbacks and sometimes used internally to - * specify the calling convention for zlib). - * - * These macros should never be overridden. If it is necessary to - * change calling convention in a private build this can be done - * by setting PNG_API_RULE (which defaults to 0) to one of the values - * below to select the correct 'API' variants. - * - * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout. - * This is correct in every known environment. - * PNG_API_RULE=1 Use the operating system convention for PNGAPI and - * the 'C' calling convention (from PNGCAPI) for - * callbacks (PNGCBAPI). This is no longer required - * in any known environment - if it has to be used - * please post an explanation of the problem to the - * libpng mailing list. - * - * These cases only differ if the operating system does not use the C - * calling convention, at present this just means the above cases - * (x86 DOS/Windows systems) and, even then, this does not apply to - * Cygwin running on those systems. - * - * Note that the value must be defined in pnglibconf.h so that what - * the application uses to call the library matches the conventions - * set when building the library. - */ - -/* Symbol export - * ============= - * When building a shared library it is almost always necessary to tell - * the compiler which symbols to export. The png.h macro 'PNG_EXPORT' - * is used to mark the symbols. On some systems these symbols can be - * extracted at link time and need no special processing by the compiler, - * on other systems the symbols are flagged by the compiler and just - * the declaration requires a special tag applied (unfortunately) in a - * compiler dependent way. Some systems can do either. - * - * A small number of older systems also require a symbol from a DLL to - * be flagged to the program that calls it. This is a problem because - * we do not know in the header file included by application code that - * the symbol will come from a shared library, as opposed to a statically - * linked one. For this reason the application must tell us by setting - * the magic flag PNG_USE_DLL to turn on the special processing before - * it includes png.h. - * - * Four additional macros are used to make this happen: - * - * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from - * the build or imported if PNG_USE_DLL is set - compiler - * and system specific. - * - * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to - * 'type', compiler specific. - * - * PNG_DLL_EXPORT Set to the magic to use during a libpng build to - * make a symbol exported from the DLL. Not used in the - * public header files; see pngpriv.h for how it is used - * in the libpng build. - * - * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come - * from a DLL - used to define PNG_IMPEXP when - * PNG_USE_DLL is set. - */ - -/* System specific discovery. - * ========================== - * This code is used at build time to find PNG_IMPEXP, the API settings - * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL - * import processing is possible. On Windows systems it also sets - * compiler-specific macros to the values required to change the calling - * conventions of the various functions. - */ -#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ - defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) - /* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or - * MinGW on any architecture currently supported by Windows. Also includes - * Watcom builds but these need special treatment because they are not - * compatible with GCC or Visual C because of different calling conventions. - */ -# if PNG_API_RULE == 2 - /* If this line results in an error, either because __watcall is not - * understood or because of a redefine just below you cannot use *this* - * build of the library with the compiler you are using. *This* build was - * build using Watcom and applications must also be built using Watcom! - */ -# define PNGCAPI __watcall -# endif - -# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800)) -# define PNGCAPI __cdecl -# if PNG_API_RULE == 1 - /* If this line results in an error __stdcall is not understood and - * PNG_API_RULE should not have been set to '1'. - */ -# define PNGAPI __stdcall -# endif -# else - /* An older compiler, or one not detected (erroneously) above, - * if necessary override on the command line to get the correct - * variants for the compiler. - */ -# ifndef PNGCAPI -# define PNGCAPI _cdecl -# endif -# if PNG_API_RULE == 1 && !defined(PNGAPI) -# define PNGAPI _stdcall -# endif -# endif /* compiler/api */ - - /* NOTE: PNGCBAPI always defaults to PNGCAPI. */ - -# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD) -# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed" -# endif - -# if (defined(_MSC_VER) && _MSC_VER < 800) ||\ - (defined(__BORLANDC__) && __BORLANDC__ < 0x500) - /* older Borland and MSC - * compilers used '__export' and required this to be after - * the type. - */ -# ifndef PNG_EXPORT_TYPE -# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP -# endif -# define PNG_DLL_EXPORT __export -# else /* newer compiler */ -# define PNG_DLL_EXPORT __declspec(dllexport) -# ifndef PNG_DLL_IMPORT -# define PNG_DLL_IMPORT __declspec(dllimport) -# endif -# endif /* compiler */ - -#else /* !Windows */ -# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) -# define PNGAPI _System -# else /* !Windows/x86 && !OS/2 */ - /* Use the defaults, or define PNG*API on the command line (but - * this will have to be done for every compile!) - */ -# endif /* other system, !OS/2 */ -#endif /* !Windows/x86 */ - -/* Now do all the defaulting . */ -#ifndef PNGCAPI -# define PNGCAPI -#endif -#ifndef PNGCBAPI -# define PNGCBAPI PNGCAPI -#endif -#ifndef PNGAPI -# define PNGAPI PNGCAPI -#endif - -/* PNG_IMPEXP may be set on the compilation system command line or (if not set) - * then in an internal header file when building the library, otherwise (when - * using the library) it is set here. - */ -#ifndef PNG_IMPEXP -# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) - /* This forces use of a DLL, disallowing static linking */ -# define PNG_IMPEXP PNG_DLL_IMPORT -# endif - -# ifndef PNG_IMPEXP -# define PNG_IMPEXP -# endif -#endif - -/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat - * 'attributes' as a storage class - the attributes go at the start of the - * function definition, and attributes are always appended regardless of the - * compiler. This considerably simplifies these macros but may cause problems - * if any compilers both need function attributes and fail to handle them as - * a storage class (this is unlikely.) - */ -#ifndef PNG_FUNCTION -# define PNG_FUNCTION(type, name, args, attributes) attributes type name args -#endif - -#ifndef PNG_EXPORT_TYPE -# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type -#endif - - /* The ordinal value is only relevant when preprocessing png.h for symbol - * table entries, so we discard it here. See the .dfn files in the - * scripts directory. - */ - -#ifndef PNG_EXPORTA -# define PNG_EXPORTA(ordinal, type, name, args, attributes) \ - PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), PNGARG(args), \ - PNG_LINKAGE_API attributes) -#endif - -/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument, - * so make something non-empty to satisfy the requirement: - */ -#define PNG_EMPTY /*empty list*/ - -#define PNG_EXPORT(ordinal, type, name, args) \ - PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY) - -/* Use PNG_REMOVED to comment out a removed interface. */ -#ifndef PNG_REMOVED -# define PNG_REMOVED(ordinal, type, name, args, attributes) -#endif - -#ifndef PNG_CALLBACK -# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args) -#endif - -/* Support for compiler specific function attributes. These are used - * so that where compiler support is available incorrect use of API - * functions in png.h will generate compiler warnings. - * - * Added at libpng-1.2.41. - */ - -#ifndef PNG_NO_PEDANTIC_WARNINGS -# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED -# define PNG_PEDANTIC_WARNINGS_SUPPORTED -# endif -#endif - -#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED - /* Support for compiler specific function attributes. These are used - * so that where compiler support is available, incorrect use of API - * functions in png.h will generate compiler warnings. Added at libpng - * version 1.2.41. Disabling these removes the warnings but may also produce - * less efficient code. - */ -# if defined(__clang__) && defined(__has_attribute) - /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */ -# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__) -# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) -# endif -# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__) -# define PNG_NORETURN __attribute__((__noreturn__)) -# endif -# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__) -# define PNG_ALLOCATED __attribute__((__malloc__)) -# endif -# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__) -# define PNG_DEPRECATED __attribute__((__deprecated__)) -# endif -# if !defined(PNG_PRIVATE) -# ifdef __has_extension -# if __has_extension(attribute_unavailable_with_message) -# define PNG_PRIVATE __attribute__((__unavailable__(\ - "This function is not exported by libpng."))) -# endif -# endif -# endif -# ifndef PNG_RESTRICT -# define PNG_RESTRICT __restrict -# endif - -# elif defined(__GNUC__) -# ifndef PNG_USE_RESULT -# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) -# endif -# ifndef PNG_NORETURN -# define PNG_NORETURN __attribute__((__noreturn__)) -# endif -# if __GNUC__ >= 3 -# ifndef PNG_ALLOCATED -# define PNG_ALLOCATED __attribute__((__malloc__)) -# endif -# ifndef PNG_DEPRECATED -# define PNG_DEPRECATED __attribute__((__deprecated__)) -# endif -# ifndef PNG_PRIVATE -# if 0 /* Doesn't work so we use deprecated instead*/ -# define PNG_PRIVATE \ - __attribute__((warning("This function is not exported by libpng."))) -# else -# define PNG_PRIVATE \ - __attribute__((__deprecated__)) -# endif -# endif -# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1)) -# ifndef PNG_RESTRICT -# define PNG_RESTRICT __restrict -# endif -# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */ -# endif /* __GNUC__ >= 3 */ - -# elif defined(_MSC_VER) && (_MSC_VER >= 1300) -# ifndef PNG_USE_RESULT -# define PNG_USE_RESULT /* not supported */ -# endif -# ifndef PNG_NORETURN -# define PNG_NORETURN __declspec(noreturn) -# endif -# ifndef PNG_ALLOCATED -# if (_MSC_VER >= 1400) -# define PNG_ALLOCATED __declspec(restrict) -# endif -# endif -# ifndef PNG_DEPRECATED -# define PNG_DEPRECATED __declspec(deprecated) -# endif -# ifndef PNG_PRIVATE -# define PNG_PRIVATE __declspec(deprecated) -# endif -# ifndef PNG_RESTRICT -# if (_MSC_VER >= 1400) -# define PNG_RESTRICT __restrict -# endif -# endif - -# elif defined(__WATCOMC__) -# ifndef PNG_RESTRICT -# define PNG_RESTRICT __restrict -# endif -# endif -#endif /* PNG_PEDANTIC_WARNINGS */ - -#ifndef PNG_DEPRECATED -# define PNG_DEPRECATED /* Use of this function is deprecated */ -#endif -#ifndef PNG_USE_RESULT -# define PNG_USE_RESULT /* The result of this function must be checked */ -#endif -#ifndef PNG_NORETURN -# define PNG_NORETURN /* This function does not return */ -#endif -#ifndef PNG_ALLOCATED -# define PNG_ALLOCATED /* The result of the function is new memory */ -#endif -#ifndef PNG_PRIVATE -# define PNG_PRIVATE /* This is a private libpng function */ -#endif -#ifndef PNG_RESTRICT -# define PNG_RESTRICT /* The C99 "restrict" feature */ -#endif - -#ifndef PNG_FP_EXPORT /* A floating point API. */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -# define PNG_FP_EXPORT(ordinal, type, name, args)\ - PNG_EXPORT(ordinal, type, name, args); -# else /* No floating point APIs */ -# define PNG_FP_EXPORT(ordinal, type, name, args) -# endif -#endif -#ifndef PNG_FIXED_EXPORT /* A fixed point API. */ -# ifdef PNG_FIXED_POINT_SUPPORTED -# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ - PNG_EXPORT(ordinal, type, name, args); -# else /* No fixed point APIs */ -# define PNG_FIXED_EXPORT(ordinal, type, name, args) -# endif -#endif - -#ifndef PNG_BUILDING_SYMBOL_TABLE -/* Some typedefs to get us started. These should be safe on most of the common - * platforms. - * - * png_uint_32 and png_int_32 may, currently, be larger than required to hold a - * 32-bit value however this is not normally advisable. - * - * png_uint_16 and png_int_16 should always be two bytes in size - this is - * verified at library build time. - * - * png_byte must always be one byte in size. - * - * The checks below use constants from limits.h, as defined by the ISOC90 - * standard. - */ -#if CHAR_BIT == 8 && UCHAR_MAX == 255 - typedef unsigned char png_byte; -#else -# error "libpng requires 8-bit bytes" -#endif - -#if INT_MIN == -32768 && INT_MAX == 32767 - typedef int png_int_16; -#elif SHRT_MIN == -32768 && SHRT_MAX == 32767 - typedef short png_int_16; -#else -# error "libpng requires a signed 16-bit type" -#endif - -#if UINT_MAX == 65535 - typedef unsigned int png_uint_16; -#elif USHRT_MAX == 65535 - typedef unsigned short png_uint_16; -#else -# error "libpng requires an unsigned 16-bit type" -#endif - -#if INT_MIN < -2147483646 && INT_MAX > 2147483646 - typedef int png_int_32; -#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646 - typedef long int png_int_32; -#else -# error "libpng requires a signed 32-bit (or more) type" -#endif - -#if UINT_MAX > 4294967294U - typedef unsigned int png_uint_32; -#elif ULONG_MAX > 4294967294U - typedef unsigned long int png_uint_32; -#else -# error "libpng requires an unsigned 32-bit (or more) type" -#endif - -/* Prior to 1.6.0, it was possible to disable the use of size_t and ptrdiff_t. - * From 1.6.0 onwards, an ISO C90 compiler, as well as a standard-compliant - * behavior of sizeof and ptrdiff_t are required. - * The legacy typedefs are provided here for backwards compatibility. - */ -typedef size_t png_size_t; -typedef ptrdiff_t png_ptrdiff_t; - -/* libpng needs to know the maximum value of 'size_t' and this controls the - * definition of png_alloc_size_t, below. This maximum value of size_t limits - * but does not control the maximum allocations the library makes - there is - * direct application control of this through png_set_user_limits(). - */ -#ifndef PNG_SMALL_SIZE_T - /* Compiler specific tests for systems where size_t is known to be less than - * 32 bits (some of these systems may no longer work because of the lack of - * 'far' support; see above.) - */ -# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\ - (defined(_MSC_VER) && defined(MAXSEG_64K)) -# define PNG_SMALL_SIZE_T -# endif -#endif - -/* png_alloc_size_t is guaranteed to be no smaller than size_t, and no smaller - * than png_uint_32. Casts from size_t or png_uint_32 to png_alloc_size_t are - * not necessary; in fact, it is recommended not to use them at all, so that - * the compiler can complain when something turns out to be problematic. - * - * Casts in the other direction (from png_alloc_size_t to size_t or - * png_uint_32) should be explicitly applied; however, we do not expect to - * encounter practical situations that require such conversions. - * - * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than - * 4294967295 - i.e. less than the maximum value of png_uint_32. - */ -#ifdef PNG_SMALL_SIZE_T - typedef png_uint_32 png_alloc_size_t; -#else - typedef size_t png_alloc_size_t; -#endif - -/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler - * implementations of Intel CPU specific support of user-mode segmented address - * spaces, where 16-bit pointers address more than 65536 bytes of memory using - * separate 'segment' registers. The implementation requires two different - * types of pointer (only one of which includes the segment value.) - * - * If required this support is available in version 1.2 of libpng and may be - * available in versions through 1.5, although the correctness of the code has - * not been verified recently. - */ - -/* Typedef for floating-point numbers that are converted to fixed-point with a - * multiple of 100,000, e.g., gamma - */ -typedef png_int_32 png_fixed_point; - -/* Add typedefs for pointers */ -typedef void * png_voidp; -typedef const void * png_const_voidp; -typedef png_byte * png_bytep; -typedef const png_byte * png_const_bytep; -typedef png_uint_32 * png_uint_32p; -typedef const png_uint_32 * png_const_uint_32p; -typedef png_int_32 * png_int_32p; -typedef const png_int_32 * png_const_int_32p; -typedef png_uint_16 * png_uint_16p; -typedef const png_uint_16 * png_const_uint_16p; -typedef png_int_16 * png_int_16p; -typedef const png_int_16 * png_const_int_16p; -typedef char * png_charp; -typedef const char * png_const_charp; -typedef png_fixed_point * png_fixed_point_p; -typedef const png_fixed_point * png_const_fixed_point_p; -typedef size_t * png_size_tp; -typedef const size_t * png_const_size_tp; - -#ifdef PNG_STDIO_SUPPORTED -typedef FILE * png_FILE_p; -#endif - -#ifdef PNG_FLOATING_POINT_SUPPORTED -typedef double * png_doublep; -typedef const double * png_const_doublep; -#endif - -/* Pointers to pointers; i.e. arrays */ -typedef png_byte * * png_bytepp; -typedef png_uint_32 * * png_uint_32pp; -typedef png_int_32 * * png_int_32pp; -typedef png_uint_16 * * png_uint_16pp; -typedef png_int_16 * * png_int_16pp; -typedef const char * * png_const_charpp; -typedef char * * png_charpp; -typedef png_fixed_point * * png_fixed_point_pp; -#ifdef PNG_FLOATING_POINT_SUPPORTED -typedef double * * png_doublepp; -#endif - -/* Pointers to pointers to pointers; i.e., pointer to array */ -typedef char * * * png_charppp; - -#endif /* PNG_BUILDING_SYMBOL_TABLE */ - -#endif /* PNGCONF_H */ diff --git a/extern/libpng/pngdebug.h b/extern/libpng/pngdebug.h deleted file mode 100644 index 00d5a4569..000000000 --- a/extern/libpng/pngdebug.h +++ /dev/null @@ -1,153 +0,0 @@ - -/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* Define PNG_DEBUG at compile time for debugging information. Higher - * numbers for PNG_DEBUG mean more debugging information. This has - * only been added since version 0.95 so it is not implemented throughout - * libpng yet, but more support will be added as needed. - * - * png_debug[1-2]?(level, message ,arg{0-2}) - * Expands to a statement (either a simple expression or a compound - * do..while(0) statement) that outputs a message with parameter - * substitution if PNG_DEBUG is defined to 2 or more. If PNG_DEBUG - * is undefined, 0 or 1 every png_debug expands to a simple expression - * (actually ((void)0)). - * - * level: level of detail of message, starting at 0. A level 'n' - * message is preceded by 'n' 3-space indentations (not implemented - * on Microsoft compilers unless PNG_DEBUG_FILE is also - * defined, to allow debug DLL compilation with no standard IO). - * message: a printf(3) style text string. A trailing '\n' is added - * to the message. - * arg: 0 to 2 arguments for printf(3) style substitution in message. - */ -#ifndef PNGDEBUG_H -#define PNGDEBUG_H -/* These settings control the formatting of messages in png.c and pngerror.c */ -/* Moved to pngdebug.h at 1.5.0 */ -# ifndef PNG_LITERAL_SHARP -# define PNG_LITERAL_SHARP 0x23 -# endif -# ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET -# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b -# endif -# ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET -# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d -# endif -# ifndef PNG_STRING_NEWLINE -# define PNG_STRING_NEWLINE "\n" -# endif - -#ifdef PNG_DEBUG -# if (PNG_DEBUG > 0) -# if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) -# include -# if (PNG_DEBUG > 1) -# ifndef _DEBUG -# define _DEBUG -# endif -# ifndef png_debug -# define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE) -# endif -# ifndef png_debug1 -# define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1) -# endif -# ifndef png_debug2 -# define png_debug2(l,m,p1,p2) \ - _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2) -# endif -# endif -# else /* PNG_DEBUG_FILE || !_MSC_VER */ -# ifndef PNG_STDIO_SUPPORTED -# include /* not included yet */ -# endif -# ifndef PNG_DEBUG_FILE -# define PNG_DEBUG_FILE stderr -# endif /* PNG_DEBUG_FILE */ - -# if (PNG_DEBUG > 1) -# ifdef __STDC__ -# ifndef png_debug -# define png_debug(l,m) \ - do { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ - (num_tabs==2 ? " " : (num_tabs>2 ? " " : "")))); \ - } while (0) -# endif -# ifndef png_debug1 -# define png_debug1(l,m,p1) \ - do { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ - (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1); \ - } while (0) -# endif -# ifndef png_debug2 -# define png_debug2(l,m,p1,p2) \ - do { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \ - (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1,p2);\ - } while (0) -# endif -# else /* __STDC __ */ -# ifndef png_debug -# define png_debug(l,m) \ - do { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format); \ - } while (0) -# endif -# ifndef png_debug1 -# define png_debug1(l,m,p1) \ - do { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format,p1); \ - } while (0) -# endif -# ifndef png_debug2 -# define png_debug2(l,m,p1,p2) \ - do { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format,p1,p2); \ - } while (0) -# endif -# endif /* __STDC __ */ -# endif /* (PNG_DEBUG > 1) */ - -# endif /* _MSC_VER */ -# endif /* (PNG_DEBUG > 0) */ -#endif /* PNG_DEBUG */ -#ifndef png_debug -# define png_debug(l, m) ((void)0) -#endif -#ifndef png_debug1 -# define png_debug1(l, m, p1) ((void)0) -#endif -#ifndef png_debug2 -# define png_debug2(l, m, p1, p2) ((void)0) -#endif -#endif /* PNGDEBUG_H */ diff --git a/extern/libpng/pngerror.c b/extern/libpng/pngerror.c deleted file mode 100644 index ec3a709b9..000000000 --- a/extern/libpng/pngerror.c +++ /dev/null @@ -1,963 +0,0 @@ - -/* pngerror.c - stub functions for i/o and memory allocation - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all error handling. Users who - * need special error handling are expected to write replacement functions - * and use png_set_error_fn() to use those functions. See the instructions - * at each function. - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr, - png_const_charp error_message)),PNG_NORETURN); - -#ifdef PNG_WARNINGS_SUPPORTED -static void /* PRIVATE */ -png_default_warning PNGARG((png_const_structrp png_ptr, - png_const_charp warning_message)); -#endif /* WARNINGS */ - -/* This function is called whenever there is a fatal error. This function - * should not be changed. If there is a need to handle errors differently, - * you should supply a replacement error function and use png_set_error_fn() - * to replace the error function at run-time. - */ -#ifdef PNG_ERROR_TEXT_SUPPORTED -PNG_FUNCTION(void,PNGAPI -png_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) -{ -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - char msg[16]; - if (png_ptr != NULL) - { - if ((png_ptr->flags & - (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0) - { - if (*error_message == PNG_LITERAL_SHARP) - { - /* Strip "#nnnn " from beginning of error message. */ - int offset; - for (offset = 1; offset<15; offset++) - if (error_message[offset] == ' ') - break; - - if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0) - { - int i; - for (i = 0; i < offset - 1; i++) - msg[i] = error_message[i + 1]; - msg[i - 1] = '\0'; - error_message = msg; - } - - else - error_message += offset; - } - - else - { - if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0) - { - msg[0] = '0'; - msg[1] = '\0'; - error_message = msg; - } - } - } - } -#endif - if (png_ptr != NULL && png_ptr->error_fn != NULL) - (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), - error_message); - - /* If the custom handler doesn't exist, or if it returns, - use the default handler, which will not return. */ - png_default_error(png_ptr, error_message); -} -#else -PNG_FUNCTION(void,PNGAPI -png_err,(png_const_structrp png_ptr),PNG_NORETURN) -{ - /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed - * erroneously as '\0', instead of the empty string "". This was - * apparently an error, introduced in libpng-1.2.20, and png_default_error - * will crash in this case. - */ - if (png_ptr != NULL && png_ptr->error_fn != NULL) - (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), ""); - - /* If the custom handler doesn't exist, or if it returns, - use the default handler, which will not return. */ - png_default_error(png_ptr, ""); -} -#endif /* ERROR_TEXT */ - -/* Utility to safely appends strings to a buffer. This never errors out so - * error checking is not required in the caller. - */ -size_t -png_safecat(png_charp buffer, size_t bufsize, size_t pos, - png_const_charp string) -{ - if (buffer != NULL && pos < bufsize) - { - if (string != NULL) - while (*string != '\0' && pos < bufsize-1) - buffer[pos++] = *string++; - - buffer[pos] = '\0'; - } - - return pos; -} - -#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) -/* Utility to dump an unsigned value into a buffer, given a start pointer and - * and end pointer (which should point just *beyond* the end of the buffer!) - * Returns the pointer to the start of the formatted string. - */ -png_charp -png_format_number(png_const_charp start, png_charp end, int format, - png_alloc_size_t number) -{ - int count = 0; /* number of digits output */ - int mincount = 1; /* minimum number required */ - int output = 0; /* digit output (for the fixed point format) */ - - *--end = '\0'; - - /* This is written so that the loop always runs at least once, even with - * number zero. - */ - while (end > start && (number != 0 || count < mincount)) - { - - static const char digits[] = "0123456789ABCDEF"; - - switch (format) - { - case PNG_NUMBER_FORMAT_fixed: - /* Needs five digits (the fraction) */ - mincount = 5; - if (output != 0 || number % 10 != 0) - { - *--end = digits[number % 10]; - output = 1; - } - number /= 10; - break; - - case PNG_NUMBER_FORMAT_02u: - /* Expects at least 2 digits. */ - mincount = 2; - /* FALLTHROUGH */ - - case PNG_NUMBER_FORMAT_u: - *--end = digits[number % 10]; - number /= 10; - break; - - case PNG_NUMBER_FORMAT_02x: - /* This format expects at least two digits */ - mincount = 2; - /* FALLTHROUGH */ - - case PNG_NUMBER_FORMAT_x: - *--end = digits[number & 0xf]; - number >>= 4; - break; - - default: /* an error */ - number = 0; - break; - } - - /* Keep track of the number of digits added */ - ++count; - - /* Float a fixed number here: */ - if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start)) - { - /* End of the fraction, but maybe nothing was output? In that case - * drop the decimal point. If the number is a true zero handle that - * here. - */ - if (output != 0) - *--end = '.'; - else if (number == 0) /* and !output */ - *--end = '0'; - } - } - - return end; -} -#endif - -#ifdef PNG_WARNINGS_SUPPORTED -/* This function is called whenever there is a non-fatal error. This function - * should not be changed. If there is a need to handle warnings differently, - * you should supply a replacement warning function and use - * png_set_error_fn() to replace the warning function at run-time. - */ -void PNGAPI -png_warning(png_const_structrp png_ptr, png_const_charp warning_message) -{ - int offset = 0; - if (png_ptr != NULL) - { -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - if ((png_ptr->flags & - (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0) -#endif - { - if (*warning_message == PNG_LITERAL_SHARP) - { - for (offset = 1; offset < 15; offset++) - if (warning_message[offset] == ' ') - break; - } - } - } - if (png_ptr != NULL && png_ptr->warning_fn != NULL) - (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr), - warning_message + offset); - else - png_default_warning(png_ptr, warning_message + offset); -} - -/* These functions support 'formatted' warning messages with up to - * PNG_WARNING_PARAMETER_COUNT parameters. In the format string the parameter - * is introduced by @, where 'number' starts at 1. This follows the - * standard established by X/Open for internationalizable error messages. - */ -void -png_warning_parameter(png_warning_parameters p, int number, - png_const_charp string) -{ - if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT) - (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string); -} - -void -png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, - png_alloc_size_t value) -{ - char buffer[PNG_NUMBER_BUFFER_SIZE]; - png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value)); -} - -void -png_warning_parameter_signed(png_warning_parameters p, int number, int format, - png_int_32 value) -{ - png_alloc_size_t u; - png_charp str; - char buffer[PNG_NUMBER_BUFFER_SIZE]; - - /* Avoid overflow by doing the negate in a png_alloc_size_t: */ - u = (png_alloc_size_t)value; - if (value < 0) - u = ~u + 1; - - str = PNG_FORMAT_NUMBER(buffer, format, u); - - if (value < 0 && str > buffer) - *--str = '-'; - - png_warning_parameter(p, number, str); -} - -void -png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p, - png_const_charp message) -{ - /* The internal buffer is just 192 bytes - enough for all our messages, - * overflow doesn't happen because this code checks! If someone figures - * out how to send us a message longer than 192 bytes, all that will - * happen is that the message will be truncated appropriately. - */ - size_t i = 0; /* Index in the msg[] buffer: */ - char msg[192]; - - /* Each iteration through the following loop writes at most one character - * to msg[i++] then returns here to validate that there is still space for - * the trailing '\0'. It may (in the case of a parameter) read more than - * one character from message[]; it must check for '\0' and continue to the - * test if it finds the end of string. - */ - while (i<(sizeof msg)-1 && *message != '\0') - { - /* '@' at end of string is now just printed (previously it was skipped); - * it is an error in the calling code to terminate the string with @. - */ - if (p != NULL && *message == '@' && message[1] != '\0') - { - int parameter_char = *++message; /* Consume the '@' */ - static const char valid_parameters[] = "123456789"; - int parameter = 0; - - /* Search for the parameter digit, the index in the string is the - * parameter to use. - */ - while (valid_parameters[parameter] != parameter_char && - valid_parameters[parameter] != '\0') - ++parameter; - - /* If the parameter digit is out of range it will just get printed. */ - if (parameter < PNG_WARNING_PARAMETER_COUNT) - { - /* Append this parameter */ - png_const_charp parm = p[parameter]; - png_const_charp pend = p[parameter] + (sizeof p[parameter]); - - /* No need to copy the trailing '\0' here, but there is no guarantee - * that parm[] has been initialized, so there is no guarantee of a - * trailing '\0': - */ - while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend) - msg[i++] = *parm++; - - /* Consume the parameter digit too: */ - ++message; - continue; - } - - /* else not a parameter and there is a character after the @ sign; just - * copy that. This is known not to be '\0' because of the test above. - */ - } - - /* At this point *message can't be '\0', even in the bad parameter case - * above where there is a lone '@' at the end of the message string. - */ - msg[i++] = *message++; - } - - /* i is always less than (sizeof msg), so: */ - msg[i] = '\0'; - - /* And this is the formatted message. It may be larger than - * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these - * are not (currently) formatted. - */ - png_warning(png_ptr, msg); -} -#endif /* WARNINGS */ - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -void PNGAPI -png_benign_error(png_const_structrp png_ptr, png_const_charp error_message) -{ - if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0) - { -# ifdef PNG_READ_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && - png_ptr->chunk_name != 0) - png_chunk_warning(png_ptr, error_message); - else -# endif - png_warning(png_ptr, error_message); - } - - else - { -# ifdef PNG_READ_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && - png_ptr->chunk_name != 0) - png_chunk_error(png_ptr, error_message); - else -# endif - png_error(png_ptr, error_message); - } - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(error_message) -# endif -} - -void /* PRIVATE */ -png_app_warning(png_const_structrp png_ptr, png_const_charp error_message) -{ - if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0) - png_warning(png_ptr, error_message); - else - png_error(png_ptr, error_message); - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(error_message) -# endif -} - -void /* PRIVATE */ -png_app_error(png_const_structrp png_ptr, png_const_charp error_message) -{ - if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0) - png_warning(png_ptr, error_message); - else - png_error(png_ptr, error_message); - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(error_message) -# endif -} -#endif /* BENIGN_ERRORS */ - -#define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */ -#if defined(PNG_WARNINGS_SUPPORTED) || \ - (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)) -/* These utilities are used internally to build an error message that relates - * to the current chunk. The chunk name comes from png_ptr->chunk_name, - * which is used to prefix the message. The message is limited in length - * to 63 bytes. The name characters are output as hex digits wrapped in [] - * if the character is invalid. - */ -#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) -static const char png_digit[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F' -}; - -static void /* PRIVATE */ -png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp - error_message) -{ - png_uint_32 chunk_name = png_ptr->chunk_name; - int iout = 0, ishift = 24; - - while (ishift >= 0) - { - int c = (int)(chunk_name >> ishift) & 0xff; - - ishift -= 8; - if (isnonalpha(c) != 0) - { - buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET; - buffer[iout++] = png_digit[(c & 0xf0) >> 4]; - buffer[iout++] = png_digit[c & 0x0f]; - buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET; - } - - else - { - buffer[iout++] = (char)c; - } - } - - if (error_message == NULL) - buffer[iout] = '\0'; - - else - { - int iin = 0; - - buffer[iout++] = ':'; - buffer[iout++] = ' '; - - while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0') - buffer[iout++] = error_message[iin++]; - - /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */ - buffer[iout] = '\0'; - } -} -#endif /* WARNINGS || ERROR_TEXT */ - -#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) -PNG_FUNCTION(void,PNGAPI -png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) -{ - char msg[18+PNG_MAX_ERROR_TEXT]; - if (png_ptr == NULL) - png_error(png_ptr, error_message); - - else - { - png_format_buffer(png_ptr, msg, error_message); - png_error(png_ptr, msg); - } -} -#endif /* READ && ERROR_TEXT */ - -#ifdef PNG_WARNINGS_SUPPORTED -void PNGAPI -png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message) -{ - char msg[18+PNG_MAX_ERROR_TEXT]; - if (png_ptr == NULL) - png_warning(png_ptr, warning_message); - - else - { - png_format_buffer(png_ptr, msg, warning_message); - png_warning(png_ptr, msg); - } -} -#endif /* WARNINGS */ - -#ifdef PNG_READ_SUPPORTED -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -void PNGAPI -png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp - error_message) -{ - if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0) - png_chunk_warning(png_ptr, error_message); - - else - png_chunk_error(png_ptr, error_message); - -# ifndef PNG_ERROR_TEXT_SUPPORTED - PNG_UNUSED(error_message) -# endif -} -#endif -#endif /* READ */ - -void /* PRIVATE */ -png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error) -{ -# ifndef PNG_WARNINGS_SUPPORTED - PNG_UNUSED(message) -# endif - - /* This is always supported, but for just read or just write it - * unconditionally does the right thing. - */ -# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) -# endif - -# ifdef PNG_READ_SUPPORTED - { - if (error < PNG_CHUNK_ERROR) - png_chunk_warning(png_ptr, message); - - else - png_chunk_benign_error(png_ptr, message); - } -# endif - -# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED) - else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) -# endif - -# ifdef PNG_WRITE_SUPPORTED - { - if (error < PNG_CHUNK_WRITE_ERROR) - png_app_warning(png_ptr, message); - - else - png_app_error(png_ptr, message); - } -# endif -} - -#ifdef PNG_ERROR_TEXT_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_FUNCTION(void, -png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN) -{ -# define fixed_message "fixed point overflow in " -# define fixed_message_ln ((sizeof fixed_message)-1) - unsigned int iin; - char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT]; - memcpy(msg, fixed_message, fixed_message_ln); - iin = 0; - if (name != NULL) - while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0) - { - msg[fixed_message_ln + iin] = name[iin]; - ++iin; - } - msg[fixed_message_ln + iin] = 0; - png_error(png_ptr, msg); -} -#endif -#endif - -#ifdef PNG_SETJMP_SUPPORTED -/* This API only exists if ANSI-C style error handling is used, - * otherwise it is necessary for png_default_error to be overridden. - */ -jmp_buf* PNGAPI -png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn, - size_t jmp_buf_size) -{ - /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value - * and it must not change after that. Libpng doesn't care how big the - * buffer is, just that it doesn't change. - * - * If the buffer size is no *larger* than the size of jmp_buf when libpng is - * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0 - * semantics that this call will not fail. If the size is larger, however, - * the buffer is allocated and this may fail, causing the function to return - * NULL. - */ - if (png_ptr == NULL) - return NULL; - - if (png_ptr->jmp_buf_ptr == NULL) - { - png_ptr->jmp_buf_size = 0; /* not allocated */ - - if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local)) - png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; - - else - { - png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *, - png_malloc_warn(png_ptr, jmp_buf_size)); - - if (png_ptr->jmp_buf_ptr == NULL) - return NULL; /* new NULL return on OOM */ - - png_ptr->jmp_buf_size = jmp_buf_size; - } - } - - else /* Already allocated: check the size */ - { - size_t size = png_ptr->jmp_buf_size; - - if (size == 0) - { - size = (sizeof png_ptr->jmp_buf_local); - if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local) - { - /* This is an internal error in libpng: somehow we have been left - * with a stack allocated jmp_buf when the application regained - * control. It's always possible to fix this up, but for the moment - * this is a png_error because that makes it easy to detect. - */ - png_error(png_ptr, "Libpng jmp_buf still allocated"); - /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */ - } - } - - if (size != jmp_buf_size) - { - png_warning(png_ptr, "Application jmp_buf size changed"); - return NULL; /* caller will probably crash: no choice here */ - } - } - - /* Finally fill in the function, now we have a satisfactory buffer. It is - * valid to change the function on every call. - */ - png_ptr->longjmp_fn = longjmp_fn; - return png_ptr->jmp_buf_ptr; -} - -void /* PRIVATE */ -png_free_jmpbuf(png_structrp png_ptr) -{ - if (png_ptr != NULL) - { - jmp_buf *jb = png_ptr->jmp_buf_ptr; - - /* A size of 0 is used to indicate a local, stack, allocation of the - * pointer; used here and in png.c - */ - if (jb != NULL && png_ptr->jmp_buf_size > 0) - { - - /* This stuff is so that a failure to free the error control structure - * does not leave libpng in a state with no valid error handling: the - * free always succeeds, if there is an error it gets ignored. - */ - if (jb != &png_ptr->jmp_buf_local) - { - /* Make an internal, libpng, jmp_buf to return here */ - jmp_buf free_jmp_buf; - - if (!setjmp(free_jmp_buf)) - { - png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */ - png_ptr->jmp_buf_size = 0; /* stack allocation */ - png_ptr->longjmp_fn = longjmp; - png_free(png_ptr, jb); /* Return to setjmp on error */ - } - } - } - - /* *Always* cancel everything out: */ - png_ptr->jmp_buf_size = 0; - png_ptr->jmp_buf_ptr = NULL; - png_ptr->longjmp_fn = 0; - } -} -#endif - -/* This is the default error handling function. Note that replacements for - * this function MUST NOT RETURN, or the program will likely crash. This - * function is used by default, or if the program supplies NULL for the - * error function pointer in png_set_error_fn(). - */ -static PNG_FUNCTION(void /* PRIVATE */, -png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) -{ -#ifdef PNG_CONSOLE_IO_SUPPORTED -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - /* Check on NULL only added in 1.5.4 */ - if (error_message != NULL && *error_message == PNG_LITERAL_SHARP) - { - /* Strip "#nnnn " from beginning of error message. */ - int offset; - char error_number[16]; - for (offset = 0; offset<15; offset++) - { - error_number[offset] = error_message[offset + 1]; - if (error_message[offset] == ' ') - break; - } - - if ((offset > 1) && (offset < 15)) - { - error_number[offset - 1] = '\0'; - fprintf(stderr, "libpng error no. %s: %s", - error_number, error_message + offset + 1); - fprintf(stderr, PNG_STRING_NEWLINE); - } - - else - { - fprintf(stderr, "libpng error: %s, offset=%d", - error_message, offset); - fprintf(stderr, PNG_STRING_NEWLINE); - } - } - else -#endif - { - fprintf(stderr, "libpng error: %s", error_message ? error_message : - "undefined"); - fprintf(stderr, PNG_STRING_NEWLINE); - } -#else - PNG_UNUSED(error_message) /* Make compiler happy */ -#endif - png_longjmp(png_ptr, 1); -} - -PNG_FUNCTION(void,PNGAPI -png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN) -{ -#ifdef PNG_SETJMP_SUPPORTED - if (png_ptr != NULL && png_ptr->longjmp_fn != NULL && - png_ptr->jmp_buf_ptr != NULL) - png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val); -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(val) -#endif - - /* If control reaches this point, png_longjmp() must not return. The only - * choice is to terminate the whole process (or maybe the thread); to do - * this the ANSI-C abort() function is used unless a different method is - * implemented by overriding the default configuration setting for - * PNG_ABORT(). - */ - PNG_ABORT(); -} - -#ifdef PNG_WARNINGS_SUPPORTED -/* This function is called when there is a warning, but the library thinks - * it can continue anyway. Replacement functions don't have to do anything - * here if you don't want them to. In the default configuration, png_ptr is - * not used, but it is passed in case it may be useful. - */ -static void /* PRIVATE */ -png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message) -{ -#ifdef PNG_CONSOLE_IO_SUPPORTED -# ifdef PNG_ERROR_NUMBERS_SUPPORTED - if (*warning_message == PNG_LITERAL_SHARP) - { - int offset; - char warning_number[16]; - for (offset = 0; offset < 15; offset++) - { - warning_number[offset] = warning_message[offset + 1]; - if (warning_message[offset] == ' ') - break; - } - - if ((offset > 1) && (offset < 15)) - { - warning_number[offset + 1] = '\0'; - fprintf(stderr, "libpng warning no. %s: %s", - warning_number, warning_message + offset); - fprintf(stderr, PNG_STRING_NEWLINE); - } - - else - { - fprintf(stderr, "libpng warning: %s", - warning_message); - fprintf(stderr, PNG_STRING_NEWLINE); - } - } - else -# endif - - { - fprintf(stderr, "libpng warning: %s", warning_message); - fprintf(stderr, PNG_STRING_NEWLINE); - } -#else - PNG_UNUSED(warning_message) /* Make compiler happy */ -#endif - PNG_UNUSED(png_ptr) /* Make compiler happy */ -} -#endif /* WARNINGS */ - -/* This function is called when the application wants to use another method - * of handling errors and warnings. Note that the error function MUST NOT - * return to the calling routine or serious problems will occur. The return - * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1) - */ -void PNGAPI -png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warning_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->error_ptr = error_ptr; - png_ptr->error_fn = error_fn; -#ifdef PNG_WARNINGS_SUPPORTED - png_ptr->warning_fn = warning_fn; -#else - PNG_UNUSED(warning_fn) -#endif -} - - -/* This function returns a pointer to the error_ptr associated with the user - * functions. The application should free any memory associated with this - * pointer before png_write_destroy and png_read_destroy are called. - */ -png_voidp PNGAPI -png_get_error_ptr(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return NULL; - - return ((png_voidp)png_ptr->error_ptr); -} - - -#ifdef PNG_ERROR_NUMBERS_SUPPORTED -void PNGAPI -png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode) -{ - if (png_ptr != NULL) - { - png_ptr->flags &= - ((~(PNG_FLAG_STRIP_ERROR_NUMBERS | - PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode); - } -} -#endif - -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) - /* Currently the above both depend on SETJMP_SUPPORTED, however it would be - * possible to implement without setjmp support just so long as there is some - * way to handle the error return here: - */ -PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI -png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), - PNG_NORETURN) -{ - png_const_structrp png_ptr = png_nonconst_ptr; - png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); - - /* An error is always logged here, overwriting anything (typically a warning) - * that is already there: - */ - if (image != NULL) - { - png_safecat(image->message, (sizeof image->message), 0, error_message); - image->warning_or_error |= PNG_IMAGE_ERROR; - - /* Retrieve the jmp_buf from within the png_control, making this work for - * C++ compilation too is pretty tricky: C++ wants a pointer to the first - * element of a jmp_buf, but C doesn't tell us the type of that. - */ - if (image->opaque != NULL && image->opaque->error_buf != NULL) - longjmp(png_control_jmp_buf(image->opaque), 1); - - /* Missing longjmp buffer, the following is to help debugging: */ - { - size_t pos = png_safecat(image->message, (sizeof image->message), 0, - "bad longjmp: "); - png_safecat(image->message, (sizeof image->message), pos, - error_message); - } - } - - /* Here on an internal programming error. */ - abort(); -} - -#ifdef PNG_WARNINGS_SUPPORTED -void /* PRIVATE */ PNGCBAPI -png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message) -{ - png_const_structrp png_ptr = png_nonconst_ptr; - png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); - - /* A warning is only logged if there is no prior warning or error. */ - if (image->warning_or_error == 0) - { - png_safecat(image->message, (sizeof image->message), 0, warning_message); - image->warning_or_error |= PNG_IMAGE_WARNING; - } -} -#endif - -int /* PRIVATE */ -png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg) -{ - volatile png_imagep image = image_in; - volatile int result; - volatile png_voidp saved_error_buf; - jmp_buf safe_jmpbuf; - - /* Safely execute function(arg) with png_error returning to this function. */ - saved_error_buf = image->opaque->error_buf; - result = setjmp(safe_jmpbuf) == 0; - - if (result != 0) - { - - image->opaque->error_buf = safe_jmpbuf; - result = function(arg); - } - - image->opaque->error_buf = saved_error_buf; - - /* And do the cleanup prior to any failure return. */ - if (result == 0) - png_image_free(image); - - return result; -} -#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */ -#endif /* READ || WRITE */ diff --git a/extern/libpng/pngget.c b/extern/libpng/pngget.c deleted file mode 100644 index 5abf1efd9..000000000 --- a/extern/libpng/pngget.c +++ /dev/null @@ -1,1249 +0,0 @@ - -/* pngget.c - retrieval of values from info struct - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -png_uint_32 PNGAPI -png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 flag) -{ - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->valid & flag); - - return(0); -} - -size_t PNGAPI -png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->rowbytes); - - return(0); -} - -#ifdef PNG_INFO_IMAGE_SUPPORTED -png_bytepp PNGAPI -png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->row_pointers); - - return(0); -} -#endif - -#ifdef PNG_EASY_ACCESS_SUPPORTED -/* Easy access to info, added in libpng-0.99 */ -png_uint_32 PNGAPI -png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->width; - - return (0); -} - -png_uint_32 PNGAPI -png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->height; - - return (0); -} - -png_byte PNGAPI -png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->bit_depth; - - return (0); -} - -png_byte PNGAPI -png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->color_type; - - return (0); -} - -png_byte PNGAPI -png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->filter_type; - - return (0); -} - -png_byte PNGAPI -png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->interlace_type; - - return (0); -} - -png_byte PNGAPI -png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return info_ptr->compression_type; - - return (0); -} - -png_uint_32 PNGAPI -png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp - info_ptr) -{ -#ifdef PNG_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", - "png_get_x_pixels_per_meter"); - - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return (info_ptr->x_pixels_per_unit); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (0); -} - -png_uint_32 PNGAPI -png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp - info_ptr) -{ -#ifdef PNG_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", - "png_get_y_pixels_per_meter"); - - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return (info_ptr->y_pixels_per_unit); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (0); -} - -png_uint_32 PNGAPI -png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter"); - - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER && - info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit) - return (info_ptr->x_pixels_per_unit); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (0); -} - -#ifdef PNG_FLOATING_POINT_SUPPORTED -float PNGAPI -png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp - info_ptr) -{ -#ifdef PNG_READ_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio"); - - if (info_ptr->x_pixels_per_unit != 0) - return ((float)((float)info_ptr->y_pixels_per_unit - /(float)info_ptr->x_pixels_per_unit)); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return ((float)0.0); -} -#endif - -#ifdef PNG_FIXED_POINT_SUPPORTED -png_fixed_point PNGAPI -png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr, - png_const_inforp info_ptr) -{ -#ifdef PNG_READ_pHYs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0 && - info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 && - info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX && - info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX) - { - png_fixed_point res; - - png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed"); - - /* The following casts work because a PNG 4 byte integer only has a valid - * range of 0..2^31-1; otherwise the cast might overflow. - */ - if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1, - (png_int_32)info_ptr->x_pixels_per_unit) != 0) - return res; - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return 0; -} -#endif - -png_int_32 PNGAPI -png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return (info_ptr->x_offset); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (0); -} - -png_int_32 PNGAPI -png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return (info_ptr->y_offset); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (0); -} - -png_int_32 PNGAPI -png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return (info_ptr->x_offset); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (0); -} - -png_int_32 PNGAPI -png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ -#ifdef PNG_oFFs_SUPPORTED - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels"); - - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return (info_ptr->y_offset); - } -#else - PNG_UNUSED(png_ptr) - PNG_UNUSED(info_ptr) -#endif - - return (0); -} - -#ifdef PNG_INCH_CONVERSIONS_SUPPORTED -static png_uint_32 -ppi_from_ppm(png_uint_32 ppm) -{ -#if 0 - /* The conversion is *(2.54/100), in binary (32 digits): - * .00000110100000001001110101001001 - */ - png_uint_32 t1001, t1101; - ppm >>= 1; /* .1 */ - t1001 = ppm + (ppm >> 3); /* .1001 */ - t1101 = t1001 + (ppm >> 1); /* .1101 */ - ppm >>= 20; /* .000000000000000000001 */ - t1101 += t1101 >> 15; /* .1101000000000001101 */ - t1001 >>= 11; /* .000000000001001 */ - t1001 += t1001 >> 12; /* .000000000001001000000001001 */ - ppm += t1001; /* .000000000001001000001001001 */ - ppm += t1101; /* .110100000001001110101001001 */ - return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */ -#else - /* The argument is a PNG unsigned integer, so it is not permitted - * to be bigger than 2^31. - */ - png_fixed_point result; - if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127, - 5000) != 0) - return (png_uint_32)result; - - /* Overflow. */ - return 0; -#endif -} - -png_uint_32 PNGAPI -png_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr)); -} - -png_uint_32 PNGAPI -png_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr)); -} - -png_uint_32 PNGAPI -png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr)); -} - -#ifdef PNG_FIXED_POINT_SUPPORTED -static png_fixed_point -png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns) -{ - /* Convert from meters * 1,000,000 to inches * 100,000, meters to - * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127. - * Notice that this can overflow - a warning is output and 0 is - * returned. - */ - return png_muldiv_warn(png_ptr, microns, 500, 127); -} - -png_fixed_point PNGAPI -png_get_x_offset_inches_fixed(png_const_structrp png_ptr, - png_const_inforp info_ptr) -{ - return png_fixed_inches_from_microns(png_ptr, - png_get_x_offset_microns(png_ptr, info_ptr)); -} -#endif - -#ifdef PNG_FIXED_POINT_SUPPORTED -png_fixed_point PNGAPI -png_get_y_offset_inches_fixed(png_const_structrp png_ptr, - png_const_inforp info_ptr) -{ - return png_fixed_inches_from_microns(png_ptr, - png_get_y_offset_microns(png_ptr, info_ptr)); -} -#endif - -#ifdef PNG_FLOATING_POINT_SUPPORTED -float PNGAPI -png_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - /* To avoid the overflow do the conversion directly in floating - * point. - */ - return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937); -} -#endif - -#ifdef PNG_FLOATING_POINT_SUPPORTED -float PNGAPI -png_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - /* To avoid the overflow do the conversion directly in floating - * point. - */ - return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937); -} -#endif - -#ifdef PNG_pHYs_SUPPORTED -png_uint_32 PNGAPI -png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) -{ - png_uint_32 retval = 0; - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", "pHYs"); - - if (res_x != NULL) - { - *res_x = info_ptr->x_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (res_y != NULL) - { - *res_y = info_ptr->y_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (unit_type != NULL) - { - *unit_type = (int)info_ptr->phys_unit_type; - retval |= PNG_INFO_pHYs; - - if (*unit_type == 1) - { - if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50); - if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50); - } - } - } - - return (retval); -} -#endif /* pHYs */ -#endif /* INCH_CONVERSIONS */ - -/* png_get_channels really belongs in here, too, but it's been around longer */ - -#endif /* EASY_ACCESS */ - - -png_byte PNGAPI -png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->channels); - - return (0); -} - -#ifdef PNG_READ_SUPPORTED -png_const_bytep PNGAPI -png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->signature); - - return (NULL); -} -#endif - -#ifdef PNG_bKGD_SUPPORTED -png_uint_32 PNGAPI -png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, - png_color_16p *background) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_bKGD) != 0 && - background != NULL) - { - png_debug1(1, "in %s retrieval function", "bKGD"); - - *background = &(info_ptr->background); - return (PNG_INFO_bKGD); - } - - return (0); -} -#endif - -#ifdef PNG_cHRM_SUPPORTED -/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the - * same time to correct the rgb grayscale coefficient defaults obtained from the - * cHRM chunk in 1.5.4 - */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, - double *white_x, double *white_y, double *red_x, double *red_y, - double *green_x, double *green_y, double *blue_x, double *blue_y) -{ - /* Quiet API change: this code used to only return the end points if a cHRM - * chunk was present, but the end points can also come from iCCP or sRGB - * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and - * the png_set_ APIs merely check that set end points are mutually - * consistent. - */ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - png_debug1(1, "in %s retrieval function", "cHRM"); - - if (white_x != NULL) - *white_x = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); - if (white_y != NULL) - *white_y = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y"); - if (red_x != NULL) - *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx, - "cHRM red X"); - if (red_y != NULL) - *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy, - "cHRM red Y"); - if (green_x != NULL) - *green_x = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.greenx, "cHRM green X"); - if (green_y != NULL) - *green_y = png_float(png_ptr, - info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y"); - if (blue_x != NULL) - *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex, - "cHRM blue X"); - if (blue_y != NULL) - *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey, - "cHRM blue Y"); - return (PNG_INFO_cHRM); - } - - return (0); -} - -png_uint_32 PNGAPI -png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, - double *red_X, double *red_Y, double *red_Z, double *green_X, - double *green_Y, double *green_Z, double *blue_X, double *blue_Y, - double *blue_Z) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); - - if (red_X != NULL) - *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X, - "cHRM red X"); - if (red_Y != NULL) - *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y, - "cHRM red Y"); - if (red_Z != NULL) - *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z, - "cHRM red Z"); - if (green_X != NULL) - *green_X = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X"); - if (green_Y != NULL) - *green_Y = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y"); - if (green_Z != NULL) - *green_Z = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z"); - if (blue_X != NULL) - *blue_X = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X"); - if (blue_Y != NULL) - *blue_Y = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y"); - if (blue_Z != NULL) - *blue_Z = png_float(png_ptr, - info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); - return (PNG_INFO_cHRM); - } - - return (0); -} -# endif - -# ifdef PNG_FIXED_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *int_red_X, png_fixed_point *int_red_Y, - png_fixed_point *int_red_Z, png_fixed_point *int_green_X, - png_fixed_point *int_green_Y, png_fixed_point *int_green_Z, - png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, - png_fixed_point *int_blue_Z) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); - - if (int_red_X != NULL) - *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X; - if (int_red_Y != NULL) - *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y; - if (int_red_Z != NULL) - *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z; - if (int_green_X != NULL) - *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X; - if (int_green_Y != NULL) - *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y; - if (int_green_Z != NULL) - *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z; - if (int_blue_X != NULL) - *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X; - if (int_blue_Y != NULL) - *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y; - if (int_blue_Z != NULL) - *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z; - return (PNG_INFO_cHRM); - } - - return (0); -} - -png_uint_32 PNGAPI -png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x, - png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y, - png_fixed_point *blue_x, png_fixed_point *blue_y) -{ - png_debug1(1, "in %s retrieval function", "cHRM"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) - { - if (white_x != NULL) - *white_x = info_ptr->colorspace.end_points_xy.whitex; - if (white_y != NULL) - *white_y = info_ptr->colorspace.end_points_xy.whitey; - if (red_x != NULL) - *red_x = info_ptr->colorspace.end_points_xy.redx; - if (red_y != NULL) - *red_y = info_ptr->colorspace.end_points_xy.redy; - if (green_x != NULL) - *green_x = info_ptr->colorspace.end_points_xy.greenx; - if (green_y != NULL) - *green_y = info_ptr->colorspace.end_points_xy.greeny; - if (blue_x != NULL) - *blue_x = info_ptr->colorspace.end_points_xy.bluex; - if (blue_y != NULL) - *blue_y = info_ptr->colorspace.end_points_xy.bluey; - return (PNG_INFO_cHRM); - } - - return (0); -} -# endif -#endif - -#ifdef PNG_gAMA_SUPPORTED -# ifdef PNG_FIXED_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_fixed_point *file_gamma) -{ - png_debug1(1, "in %s retrieval function", "gAMA"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && - file_gamma != NULL) - { - *file_gamma = info_ptr->colorspace.gamma; - return (PNG_INFO_gAMA); - } - - return (0); -} -# endif - -# ifdef PNG_FLOATING_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr, - double *file_gamma) -{ - png_debug1(1, "in %s retrieval function", "gAMA(float)"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 && - file_gamma != NULL) - { - *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma, - "png_get_gAMA"); - return (PNG_INFO_gAMA); - } - - return (0); -} -# endif -#endif - -#ifdef PNG_sRGB_SUPPORTED -png_uint_32 PNGAPI -png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *file_srgb_intent) -{ - png_debug1(1, "in %s retrieval function", "sRGB"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL) - { - *file_srgb_intent = info_ptr->colorspace.rendering_intent; - return (PNG_INFO_sRGB); - } - - return (0); -} -#endif - -#ifdef PNG_iCCP_SUPPORTED -png_uint_32 PNGAPI -png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, - png_charpp name, int *compression_type, - png_bytepp profile, png_uint_32 *proflen) -{ - png_debug1(1, "in %s retrieval function", "iCCP"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_iCCP) != 0 && - name != NULL && profile != NULL && proflen != NULL) - { - *name = info_ptr->iccp_name; - *profile = info_ptr->iccp_profile; - *proflen = png_get_uint_32(info_ptr->iccp_profile); - /* This is somewhat irrelevant since the profile data returned has - * actually been uncompressed. - */ - if (compression_type != NULL) - *compression_type = PNG_COMPRESSION_TYPE_BASE; - return (PNG_INFO_iCCP); - } - - return (0); - -} -#endif - -#ifdef PNG_sPLT_SUPPORTED -int PNGAPI -png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr, - png_sPLT_tpp spalettes) -{ - if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) - { - *spalettes = info_ptr->splt_palettes; - return info_ptr->splt_palettes_num; - } - - return (0); -} -#endif - -#ifdef PNG_eXIf_SUPPORTED -png_uint_32 PNGAPI -png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr, - png_bytep *exif) -{ - png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1"); - PNG_UNUSED(info_ptr) - PNG_UNUSED(exif) - return 0; -} - -png_uint_32 PNGAPI -png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 *num_exif, png_bytep *exif) -{ - png_debug1(1, "in %s retrieval function", "eXIf"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL) - { - *num_exif = info_ptr->num_exif; - *exif = info_ptr->exif; - return (PNG_INFO_eXIf); - } - - return (0); -} -#endif - -#ifdef PNG_hIST_SUPPORTED -png_uint_32 PNGAPI -png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_16p *hist) -{ - png_debug1(1, "in %s retrieval function", "hIST"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL) - { - *hist = info_ptr->hist; - return (PNG_INFO_hIST); - } - - return (0); -} -#endif - -png_uint_32 PNGAPI -png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 *width, png_uint_32 *height, int *bit_depth, - int *color_type, int *interlace_type, int *compression_type, - int *filter_type) -{ - png_debug1(1, "in %s retrieval function", "IHDR"); - - if (png_ptr == NULL || info_ptr == NULL) - return (0); - - if (width != NULL) - *width = info_ptr->width; - - if (height != NULL) - *height = info_ptr->height; - - if (bit_depth != NULL) - *bit_depth = info_ptr->bit_depth; - - if (color_type != NULL) - *color_type = info_ptr->color_type; - - if (compression_type != NULL) - *compression_type = info_ptr->compression_type; - - if (filter_type != NULL) - *filter_type = info_ptr->filter_type; - - if (interlace_type != NULL) - *interlace_type = info_ptr->interlace_type; - - /* This is redundant if we can be sure that the info_ptr values were all - * assigned in png_set_IHDR(). We do the check anyhow in case an - * application has ignored our advice not to mess with the members - * of info_ptr directly. - */ - png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height, - info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, - info_ptr->compression_type, info_ptr->filter_type); - - return (1); -} - -#ifdef PNG_oFFs_SUPPORTED -png_uint_32 PNGAPI -png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) -{ - png_debug1(1, "in %s retrieval function", "oFFs"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_oFFs) != 0 && - offset_x != NULL && offset_y != NULL && unit_type != NULL) - { - *offset_x = info_ptr->x_offset; - *offset_y = info_ptr->y_offset; - *unit_type = (int)info_ptr->offset_unit_type; - return (PNG_INFO_oFFs); - } - - return (0); -} -#endif - -#ifdef PNG_pCAL_SUPPORTED -png_uint_32 PNGAPI -png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, - png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, - png_charp *units, png_charpp *params) -{ - png_debug1(1, "in %s retrieval function", "pCAL"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pCAL) != 0 && - purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && - nparams != NULL && units != NULL && params != NULL) - { - *purpose = info_ptr->pcal_purpose; - *X0 = info_ptr->pcal_X0; - *X1 = info_ptr->pcal_X1; - *type = (int)info_ptr->pcal_type; - *nparams = (int)info_ptr->pcal_nparams; - *units = info_ptr->pcal_units; - *params = info_ptr->pcal_params; - return (PNG_INFO_pCAL); - } - - return (0); -} -#endif - -#ifdef PNG_sCAL_SUPPORTED -# ifdef PNG_FIXED_POINT_SUPPORTED -# if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \ - defined(PNG_FLOATING_POINT_SUPPORTED) -png_uint_32 PNGAPI -png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *unit, png_fixed_point *width, png_fixed_point *height) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - *unit = info_ptr->scal_unit; - /*TODO: make this work without FP support; the API is currently eliminated - * if neither floating point APIs nor internal floating point arithmetic - * are enabled. - */ - *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); - *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), - "sCAL height"); - return (PNG_INFO_sCAL); - } - - return(0); -} -# endif /* FLOATING_ARITHMETIC */ -# endif /* FIXED_POINT */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *unit, double *width, double *height) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - *unit = info_ptr->scal_unit; - *width = atof(info_ptr->scal_s_width); - *height = atof(info_ptr->scal_s_height); - return (PNG_INFO_sCAL); - } - - return(0); -} -# endif /* FLOATING POINT */ -png_uint_32 PNGAPI -png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr, - int *unit, png_charpp width, png_charpp height) -{ - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - *unit = info_ptr->scal_unit; - *width = info_ptr->scal_s_width; - *height = info_ptr->scal_s_height; - return (PNG_INFO_sCAL); - } - - return(0); -} -#endif /* sCAL */ - -#ifdef PNG_pHYs_SUPPORTED -png_uint_32 PNGAPI -png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr, - png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) -{ - png_uint_32 retval = 0; - - png_debug1(1, "in %s retrieval function", "pHYs"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - if (res_x != NULL) - { - *res_x = info_ptr->x_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (res_y != NULL) - { - *res_y = info_ptr->y_pixels_per_unit; - retval |= PNG_INFO_pHYs; - } - - if (unit_type != NULL) - { - *unit_type = (int)info_ptr->phys_unit_type; - retval |= PNG_INFO_pHYs; - } - } - - return (retval); -} -#endif /* pHYs */ - -png_uint_32 PNGAPI -png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr, - png_colorp *palette, int *num_palette) -{ - png_debug1(1, "in %s retrieval function", "PLTE"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL) - { - *palette = info_ptr->palette; - *num_palette = info_ptr->num_palette; - png_debug1(3, "num_palette = %d", *num_palette); - return (PNG_INFO_PLTE); - } - - return (0); -} - -#ifdef PNG_sBIT_SUPPORTED -png_uint_32 PNGAPI -png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, - png_color_8p *sig_bit) -{ - png_debug1(1, "in %s retrieval function", "sBIT"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL) - { - *sig_bit = &(info_ptr->sig_bit); - return (PNG_INFO_sBIT); - } - - return (0); -} -#endif - -#ifdef PNG_TEXT_SUPPORTED -int PNGAPI -png_get_text(png_const_structrp png_ptr, png_inforp info_ptr, - png_textp *text_ptr, int *num_text) -{ - if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) - { - png_debug1(1, "in 0x%lx retrieval function", - (unsigned long)png_ptr->chunk_name); - - if (text_ptr != NULL) - *text_ptr = info_ptr->text; - - if (num_text != NULL) - *num_text = info_ptr->num_text; - - return info_ptr->num_text; - } - - if (num_text != NULL) - *num_text = 0; - - return(0); -} -#endif - -#ifdef PNG_tIME_SUPPORTED -png_uint_32 PNGAPI -png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr, - png_timep *mod_time) -{ - png_debug1(1, "in %s retrieval function", "tIME"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL) - { - *mod_time = &(info_ptr->mod_time); - return (PNG_INFO_tIME); - } - - return (0); -} -#endif - -#ifdef PNG_tRNS_SUPPORTED -png_uint_32 PNGAPI -png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr, - png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color) -{ - png_uint_32 retval = 0; - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_tRNS) != 0) - { - png_debug1(1, "in %s retrieval function", "tRNS"); - - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (trans_alpha != NULL) - { - *trans_alpha = info_ptr->trans_alpha; - retval |= PNG_INFO_tRNS; - } - - if (trans_color != NULL) - *trans_color = &(info_ptr->trans_color); - } - - else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */ - { - if (trans_color != NULL) - { - *trans_color = &(info_ptr->trans_color); - retval |= PNG_INFO_tRNS; - } - - if (trans_alpha != NULL) - *trans_alpha = NULL; - } - - if (num_trans != NULL) - { - *num_trans = info_ptr->num_trans; - retval |= PNG_INFO_tRNS; - } - } - - return (retval); -} -#endif - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -int PNGAPI -png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr, - png_unknown_chunkpp unknowns) -{ - if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL) - { - *unknowns = info_ptr->unknown_chunks; - return info_ptr->unknown_chunks_num; - } - - return (0); -} -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -png_byte PNGAPI -png_get_rgb_to_gray_status (png_const_structrp png_ptr) -{ - return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0); -} -#endif - -#ifdef PNG_USER_CHUNKS_SUPPORTED -png_voidp PNGAPI -png_get_user_chunk_ptr(png_const_structrp png_ptr) -{ - return (png_ptr ? png_ptr->user_chunk_ptr : NULL); -} -#endif - -size_t PNGAPI -png_get_compression_buffer_size(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return 0; - -#ifdef PNG_WRITE_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) -#endif - { -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED - return png_ptr->IDAT_read_size; -#else - return PNG_IDAT_READ_SIZE; -#endif - } - -#ifdef PNG_WRITE_SUPPORTED - else - return png_ptr->zbuffer_size; -#endif -} - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED -/* These functions were added to libpng 1.2.6 and were enabled - * by default in libpng-1.4.0 */ -png_uint_32 PNGAPI -png_get_user_width_max (png_const_structrp png_ptr) -{ - return (png_ptr ? png_ptr->user_width_max : 0); -} - -png_uint_32 PNGAPI -png_get_user_height_max (png_const_structrp png_ptr) -{ - return (png_ptr ? png_ptr->user_height_max : 0); -} - -/* This function was added to libpng 1.4.0 */ -png_uint_32 PNGAPI -png_get_chunk_cache_max (png_const_structrp png_ptr) -{ - return (png_ptr ? png_ptr->user_chunk_cache_max : 0); -} - -/* This function was added to libpng 1.4.1 */ -png_alloc_size_t PNGAPI -png_get_chunk_malloc_max (png_const_structrp png_ptr) -{ - return (png_ptr ? png_ptr->user_chunk_malloc_max : 0); -} -#endif /* SET_USER_LIMITS */ - -/* These functions were added to libpng 1.4.0 */ -#ifdef PNG_IO_STATE_SUPPORTED -png_uint_32 PNGAPI -png_get_io_state (png_const_structrp png_ptr) -{ - return png_ptr->io_state; -} - -png_uint_32 PNGAPI -png_get_io_chunk_type (png_const_structrp png_ptr) -{ - return png_ptr->chunk_name; -} -#endif /* IO_STATE */ - -#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED -# ifdef PNG_GET_PALETTE_MAX_SUPPORTED -int PNGAPI -png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr) -{ - if (png_ptr != NULL && info_ptr != NULL) - return png_ptr->num_palette_max; - - return (-1); -} -# endif -#endif - -#endif /* READ || WRITE */ diff --git a/extern/libpng/pnginfo.h b/extern/libpng/pnginfo.h deleted file mode 100644 index 1f98dedc4..000000000 --- a/extern/libpng/pnginfo.h +++ /dev/null @@ -1,267 +0,0 @@ - -/* pnginfo.h - header file for PNG reference library - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2013,2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - - /* png_info is a structure that holds the information in a PNG file so - * that the application can find out the characteristics of the image. - * If you are reading the file, this structure will tell you what is - * in the PNG file. If you are writing the file, fill in the information - * you want to put into the PNG file, using png_set_*() functions, then - * call png_write_info(). - * - * The names chosen should be very close to the PNG specification, so - * consult that document for information about the meaning of each field. - * - * With libpng < 0.95, it was only possible to directly set and read the - * the values in the png_info_struct, which meant that the contents and - * order of the values had to remain fixed. With libpng 0.95 and later, - * however, there are now functions that abstract the contents of - * png_info_struct from the application, so this makes it easier to use - * libpng with dynamic libraries, and even makes it possible to use - * libraries that don't have all of the libpng ancillary chunk-handing - * functionality. In libpng-1.5.0 this was moved into a separate private - * file that is not visible to applications. - * - * The following members may have allocated storage attached that should be - * cleaned up before the structure is discarded: palette, trans, text, - * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile, - * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these - * are automatically freed when the info structure is deallocated, if they were - * allocated internally by libpng. This behavior can be changed by means - * of the png_data_freer() function. - * - * More allocation details: all the chunk-reading functions that - * change these members go through the corresponding png_set_* - * functions. A function to clear these members is available: see - * png_free_data(). The png_set_* functions do not depend on being - * able to point info structure members to any of the storage they are - * passed (they make their own copies), EXCEPT that the png_set_text - * functions use the same storage passed to them in the text_ptr or - * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns - * functions do not make their own copies. - */ -#ifndef PNGINFO_H -#define PNGINFO_H - -struct png_info_def -{ - /* The following are necessary for every PNG file */ - png_uint_32 width; /* width of image in pixels (from IHDR) */ - png_uint_32 height; /* height of image in pixels (from IHDR) */ - png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */ - size_t rowbytes; /* bytes needed to hold an untransformed row */ - png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */ - png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */ - png_uint_16 num_trans; /* number of transparent palette color (tRNS) */ - png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */ - png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */ - /* The following three should have been named *_method not *_type */ - png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */ - png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */ - png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ - - /* The following are set by png_set_IHDR, called from the application on - * write, but the are never actually used by the write code. - */ - png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */ - png_byte pixel_depth; /* number of bits per pixel */ - png_byte spare_byte; /* to align the data, and for future use */ - -#ifdef PNG_READ_SUPPORTED - /* This is never set during write */ - png_byte signature[8]; /* magic bytes read by libpng from start of file */ -#endif - - /* The rest of the data is optional. If you are reading, check the - * valid field to see if the information in these are valid. If you - * are writing, set the valid field to those chunks you want written, - * and initialize the appropriate fields below. - */ - -#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) - /* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are - * defined. When COLORSPACE is switched on all the colorspace-defining - * chunks should be enabled, when GAMMA is switched on all the gamma-defining - * chunks should be enabled. If this is not done it becomes possible to read - * inconsistent PNG files and assign a probably incorrect interpretation to - * the information. (In other words, by carefully choosing which chunks to - * recognize the system configuration can select an interpretation for PNG - * files containing ambiguous data and this will result in inconsistent - * behavior between different libpng builds!) - */ - png_colorspace colorspace; -#endif - -#ifdef PNG_iCCP_SUPPORTED - /* iCCP chunk data. */ - png_charp iccp_name; /* profile name */ - png_bytep iccp_profile; /* International Color Consortium profile data */ - png_uint_32 iccp_proflen; /* ICC profile data length */ -#endif - -#ifdef PNG_TEXT_SUPPORTED - /* The tEXt, and zTXt chunks contain human-readable textual data in - * uncompressed, compressed, and optionally compressed forms, respectively. - * The data in "text" is an array of pointers to uncompressed, - * null-terminated C strings. Each chunk has a keyword that describes the - * textual data contained in that chunk. Keywords are not required to be - * unique, and the text string may be empty. Any number of text chunks may - * be in an image. - */ - int num_text; /* number of comments read or comments to write */ - int max_text; /* current size of text array */ - png_textp text; /* array of comments read or comments to write */ -#endif /* TEXT */ - -#ifdef PNG_tIME_SUPPORTED - /* The tIME chunk holds the last time the displayed image data was - * modified. See the png_time struct for the contents of this struct. - */ - png_time mod_time; -#endif - -#ifdef PNG_sBIT_SUPPORTED - /* The sBIT chunk specifies the number of significant high-order bits - * in the pixel data. Values are in the range [1, bit_depth], and are - * only specified for the channels in the pixel data. The contents of - * the low-order bits is not specified. Data is valid if - * (valid & PNG_INFO_sBIT) is non-zero. - */ - png_color_8 sig_bit; /* significant bits in color channels */ -#endif - -#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \ -defined(PNG_READ_BACKGROUND_SUPPORTED) - /* The tRNS chunk supplies transparency data for paletted images and - * other image types that don't need a full alpha channel. There are - * "num_trans" transparency values for a paletted image, stored in the - * same order as the palette colors, starting from index 0. Values - * for the data are in the range [0, 255], ranging from fully transparent - * to fully opaque, respectively. For non-paletted images, there is a - * single color specified that should be treated as fully transparent. - * Data is valid if (valid & PNG_INFO_tRNS) is non-zero. - */ - png_bytep trans_alpha; /* alpha values for paletted image */ - png_color_16 trans_color; /* transparent color for non-palette image */ -#endif - -#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - /* The bKGD chunk gives the suggested image background color if the - * display program does not have its own background color and the image - * is needs to composited onto a background before display. The colors - * in "background" are normally in the same color space/depth as the - * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero. - */ - png_color_16 background; -#endif - -#ifdef PNG_oFFs_SUPPORTED - /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards - * and downwards from the top-left corner of the display, page, or other - * application-specific co-ordinate space. See the PNG_OFFSET_ defines - * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero. - */ - png_int_32 x_offset; /* x offset on page */ - png_int_32 y_offset; /* y offset on page */ - png_byte offset_unit_type; /* offset units type */ -#endif - -#ifdef PNG_pHYs_SUPPORTED - /* The pHYs chunk gives the physical pixel density of the image for - * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_ - * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero. - */ - png_uint_32 x_pixels_per_unit; /* horizontal pixel density */ - png_uint_32 y_pixels_per_unit; /* vertical pixel density */ - png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */ -#endif - -#ifdef PNG_eXIf_SUPPORTED - int num_exif; /* Added at libpng-1.6.31 */ - png_bytep exif; -# ifdef PNG_READ_eXIf_SUPPORTED - png_bytep eXIf_buf; /* Added at libpng-1.6.32 */ -# endif -#endif - -#ifdef PNG_hIST_SUPPORTED - /* The hIST chunk contains the relative frequency or importance of the - * various palette entries, so that a viewer can intelligently select a - * reduced-color palette, if required. Data is an array of "num_palette" - * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST) - * is non-zero. - */ - png_uint_16p hist; -#endif - -#ifdef PNG_pCAL_SUPPORTED - /* The pCAL chunk describes a transformation between the stored pixel - * values and original physical data values used to create the image. - * The integer range [0, 2^bit_depth - 1] maps to the floating-point - * range given by [pcal_X0, pcal_X1], and are further transformed by a - * (possibly non-linear) transformation function given by "pcal_type" - * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_ - * defines below, and the PNG-Group's PNG extensions document for a - * complete description of the transformations and how they should be - * implemented, and for a description of the ASCII parameter strings. - * Data values are valid if (valid & PNG_INFO_pCAL) non-zero. - */ - png_charp pcal_purpose; /* pCAL chunk description string */ - png_int_32 pcal_X0; /* minimum value */ - png_int_32 pcal_X1; /* maximum value */ - png_charp pcal_units; /* Latin-1 string giving physical units */ - png_charpp pcal_params; /* ASCII strings containing parameter values */ - png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */ - png_byte pcal_nparams; /* number of parameters given in pcal_params */ -#endif - -/* New members added in libpng-1.0.6 */ - png_uint_32 free_me; /* flags items libpng is responsible for freeing */ - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED - /* Storage for unknown chunks that the library doesn't recognize. */ - png_unknown_chunkp unknown_chunks; - - /* The type of this field is limited by the type of - * png_struct::user_chunk_cache_max, else overflow can occur. - */ - int unknown_chunks_num; -#endif - -#ifdef PNG_sPLT_SUPPORTED - /* Data on sPLT chunks (there may be more than one). */ - png_sPLT_tp splt_palettes; - int splt_palettes_num; /* Match type returned by png_get API */ -#endif - -#ifdef PNG_sCAL_SUPPORTED - /* The sCAL chunk describes the actual physical dimensions of the - * subject matter of the graphic. The chunk contains a unit specification - * a byte value, and two ASCII strings representing floating-point - * values. The values are width and height corresponding to one pixel - * in the image. Data values are valid if (valid & PNG_INFO_sCAL) is - * non-zero. - */ - png_byte scal_unit; /* unit of physical scale */ - png_charp scal_s_width; /* string containing height */ - png_charp scal_s_height; /* string containing width */ -#endif - -#ifdef PNG_INFO_IMAGE_SUPPORTED - /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) - non-zero */ - /* Data valid if (valid & PNG_INFO_IDAT) non-zero */ - png_bytepp row_pointers; /* the image bits */ -#endif - -}; -#endif /* PNGINFO_H */ diff --git a/extern/libpng/pnglibconf.h b/extern/libpng/pnglibconf.h deleted file mode 100644 index e1e27e957..000000000 --- a/extern/libpng/pnglibconf.h +++ /dev/null @@ -1,219 +0,0 @@ -/* pnglibconf.h - library build configuration */ - -/* libpng version 1.6.37 */ - -/* Copyright (c) 2018-2019 Cosmin Truta */ -/* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */ - -/* This code is released under the libpng license. */ -/* For conditions of distribution and use, see the disclaimer */ -/* and license in png.h */ - -/* pnglibconf.h */ -/* Machine generated file: DO NOT EDIT */ -/* Derived from: scripts/pnglibconf.dfa */ -#ifndef PNGLCONF_H -#define PNGLCONF_H -/* options */ -#define PNG_16BIT_SUPPORTED -#define PNG_ALIGNED_MEMORY_SUPPORTED -/*#undef PNG_ARM_NEON_API_SUPPORTED*/ -/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/ -#define PNG_BENIGN_ERRORS_SUPPORTED -#define PNG_BENIGN_READ_ERRORS_SUPPORTED -/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/ -#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED -#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED -#define PNG_COLORSPACE_SUPPORTED -#define PNG_CONSOLE_IO_SUPPORTED -#define PNG_CONVERT_tIME_SUPPORTED -#define PNG_EASY_ACCESS_SUPPORTED -/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/ -#define PNG_ERROR_TEXT_SUPPORTED -#define PNG_FIXED_POINT_SUPPORTED -#define PNG_FLOATING_ARITHMETIC_SUPPORTED -#define PNG_FLOATING_POINT_SUPPORTED -#define PNG_FORMAT_AFIRST_SUPPORTED -#define PNG_FORMAT_BGR_SUPPORTED -#define PNG_GAMMA_SUPPORTED -#define PNG_GET_PALETTE_MAX_SUPPORTED -#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED -#define PNG_INCH_CONVERSIONS_SUPPORTED -#define PNG_INFO_IMAGE_SUPPORTED -#define PNG_IO_STATE_SUPPORTED -#define PNG_MNG_FEATURES_SUPPORTED -#define PNG_POINTER_INDEXING_SUPPORTED -/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/ -/*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/ -#define PNG_PROGRESSIVE_READ_SUPPORTED -#define PNG_READ_16BIT_SUPPORTED -#define PNG_READ_ALPHA_MODE_SUPPORTED -#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED -#define PNG_READ_BACKGROUND_SUPPORTED -#define PNG_READ_BGR_SUPPORTED -#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED -#define PNG_READ_COMPOSITE_NODIV_SUPPORTED -#define PNG_READ_COMPRESSED_TEXT_SUPPORTED -#define PNG_READ_EXPAND_16_SUPPORTED -#define PNG_READ_EXPAND_SUPPORTED -#define PNG_READ_FILLER_SUPPORTED -#define PNG_READ_GAMMA_SUPPORTED -#define PNG_READ_GET_PALETTE_MAX_SUPPORTED -#define PNG_READ_GRAY_TO_RGB_SUPPORTED -#define PNG_READ_INTERLACING_SUPPORTED -#define PNG_READ_INT_FUNCTIONS_SUPPORTED -#define PNG_READ_INVERT_ALPHA_SUPPORTED -#define PNG_READ_INVERT_SUPPORTED -#define PNG_READ_OPT_PLTE_SUPPORTED -#define PNG_READ_PACKSWAP_SUPPORTED -#define PNG_READ_PACK_SUPPORTED -#define PNG_READ_QUANTIZE_SUPPORTED -#define PNG_READ_RGB_TO_GRAY_SUPPORTED -#define PNG_READ_SCALE_16_TO_8_SUPPORTED -#define PNG_READ_SHIFT_SUPPORTED -#define PNG_READ_STRIP_16_TO_8_SUPPORTED -#define PNG_READ_STRIP_ALPHA_SUPPORTED -#define PNG_READ_SUPPORTED -#define PNG_READ_SWAP_ALPHA_SUPPORTED -#define PNG_READ_SWAP_SUPPORTED -#define PNG_READ_TEXT_SUPPORTED -#define PNG_READ_TRANSFORMS_SUPPORTED -#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_READ_USER_CHUNKS_SUPPORTED -#define PNG_READ_USER_TRANSFORM_SUPPORTED -#define PNG_READ_bKGD_SUPPORTED -#define PNG_READ_cHRM_SUPPORTED -#define PNG_READ_eXIf_SUPPORTED -#define PNG_READ_gAMA_SUPPORTED -#define PNG_READ_hIST_SUPPORTED -#define PNG_READ_iCCP_SUPPORTED -#define PNG_READ_iTXt_SUPPORTED -#define PNG_READ_oFFs_SUPPORTED -#define PNG_READ_pCAL_SUPPORTED -#define PNG_READ_pHYs_SUPPORTED -#define PNG_READ_sBIT_SUPPORTED -#define PNG_READ_sCAL_SUPPORTED -#define PNG_READ_sPLT_SUPPORTED -#define PNG_READ_sRGB_SUPPORTED -#define PNG_READ_tEXt_SUPPORTED -#define PNG_READ_tIME_SUPPORTED -#define PNG_READ_tRNS_SUPPORTED -#define PNG_READ_zTXt_SUPPORTED -#define PNG_SAVE_INT_32_SUPPORTED -#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_SEQUENTIAL_READ_SUPPORTED -#define PNG_SETJMP_SUPPORTED -#define PNG_SET_OPTION_SUPPORTED -#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_SET_USER_LIMITS_SUPPORTED -#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED -#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED -#define PNG_SIMPLIFIED_READ_SUPPORTED -#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED -#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED -#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED -#define PNG_SIMPLIFIED_WRITE_SUPPORTED -#define PNG_STDIO_SUPPORTED -#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_TEXT_SUPPORTED -#define PNG_TIME_RFC1123_SUPPORTED -#define PNG_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_USER_CHUNKS_SUPPORTED -#define PNG_USER_LIMITS_SUPPORTED -#define PNG_USER_MEM_SUPPORTED -#define PNG_USER_TRANSFORM_INFO_SUPPORTED -#define PNG_USER_TRANSFORM_PTR_SUPPORTED -#define PNG_WARNINGS_SUPPORTED -#define PNG_WRITE_16BIT_SUPPORTED -#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED -#define PNG_WRITE_BGR_SUPPORTED -#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED -#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED -#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED -#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED -#define PNG_WRITE_FILLER_SUPPORTED -#define PNG_WRITE_FILTER_SUPPORTED -#define PNG_WRITE_FLUSH_SUPPORTED -#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED -#define PNG_WRITE_INTERLACING_SUPPORTED -#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED -#define PNG_WRITE_INVERT_ALPHA_SUPPORTED -#define PNG_WRITE_INVERT_SUPPORTED -#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED -#define PNG_WRITE_PACKSWAP_SUPPORTED -#define PNG_WRITE_PACK_SUPPORTED -#define PNG_WRITE_SHIFT_SUPPORTED -#define PNG_WRITE_SUPPORTED -#define PNG_WRITE_SWAP_ALPHA_SUPPORTED -#define PNG_WRITE_SWAP_SUPPORTED -#define PNG_WRITE_TEXT_SUPPORTED -#define PNG_WRITE_TRANSFORMS_SUPPORTED -#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -#define PNG_WRITE_USER_TRANSFORM_SUPPORTED -#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED -#define PNG_WRITE_bKGD_SUPPORTED -#define PNG_WRITE_cHRM_SUPPORTED -#define PNG_WRITE_eXIf_SUPPORTED -#define PNG_WRITE_gAMA_SUPPORTED -#define PNG_WRITE_hIST_SUPPORTED -#define PNG_WRITE_iCCP_SUPPORTED -#define PNG_WRITE_iTXt_SUPPORTED -#define PNG_WRITE_oFFs_SUPPORTED -#define PNG_WRITE_pCAL_SUPPORTED -#define PNG_WRITE_pHYs_SUPPORTED -#define PNG_WRITE_sBIT_SUPPORTED -#define PNG_WRITE_sCAL_SUPPORTED -#define PNG_WRITE_sPLT_SUPPORTED -#define PNG_WRITE_sRGB_SUPPORTED -#define PNG_WRITE_tEXt_SUPPORTED -#define PNG_WRITE_tIME_SUPPORTED -#define PNG_WRITE_tRNS_SUPPORTED -#define PNG_WRITE_zTXt_SUPPORTED -#define PNG_bKGD_SUPPORTED -#define PNG_cHRM_SUPPORTED -#define PNG_eXIf_SUPPORTED -#define PNG_gAMA_SUPPORTED -#define PNG_hIST_SUPPORTED -#define PNG_iCCP_SUPPORTED -#define PNG_iTXt_SUPPORTED -#define PNG_oFFs_SUPPORTED -#define PNG_pCAL_SUPPORTED -#define PNG_pHYs_SUPPORTED -#define PNG_sBIT_SUPPORTED -#define PNG_sCAL_SUPPORTED -#define PNG_sPLT_SUPPORTED -#define PNG_sRGB_SUPPORTED -#define PNG_tEXt_SUPPORTED -#define PNG_tIME_SUPPORTED -#define PNG_tRNS_SUPPORTED -#define PNG_zTXt_SUPPORTED -/* end of options */ -/* settings */ -#define PNG_API_RULE 0 -#define PNG_DEFAULT_READ_MACROS 1 -#define PNG_GAMMA_THRESHOLD_FIXED 5000 -#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE -#define PNG_INFLATE_BUF_SIZE 1024 -#define PNG_LINKAGE_API extern -#define PNG_LINKAGE_CALLBACK extern -#define PNG_LINKAGE_DATA extern -#define PNG_LINKAGE_FUNCTION extern -#define PNG_MAX_GAMMA_8 11 -#define PNG_QUANTIZE_BLUE_BITS 5 -#define PNG_QUANTIZE_GREEN_BITS 5 -#define PNG_QUANTIZE_RED_BITS 5 -#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1) -#define PNG_TEXT_Z_DEFAULT_STRATEGY 0 -#define PNG_USER_CHUNK_CACHE_MAX 1000 -#define PNG_USER_CHUNK_MALLOC_MAX 8000000 -#define PNG_USER_HEIGHT_MAX 1000000 -#define PNG_USER_WIDTH_MAX 1000000 -#define PNG_ZBUF_SIZE 8192 -#define PNG_ZLIB_VERNUM 0 /* unknown */ -#define PNG_Z_DEFAULT_COMPRESSION (-1) -#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0 -#define PNG_Z_DEFAULT_STRATEGY 1 -#define PNG_sCAL_PRECISION 5 -#define PNG_sRGB_PROFILE_CHECKS 2 -/* end of settings */ -#endif /* PNGLCONF_H */ diff --git a/extern/libpng/pngmem.c b/extern/libpng/pngmem.c deleted file mode 100644 index 09ed9c1c9..000000000 --- a/extern/libpng/pngmem.c +++ /dev/null @@ -1,284 +0,0 @@ - -/* pngmem.c - stub functions for memory allocation - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all memory allocation. Users who - * need special memory handling are expected to supply replacement - * functions for png_malloc() and png_free(), and to use - * png_create_read_struct_2() and png_create_write_struct_2() to - * identify the replacement functions. - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -/* Free a png_struct */ -void /* PRIVATE */ -png_destroy_png_struct(png_structrp png_ptr) -{ - if (png_ptr != NULL) - { - /* png_free might call png_error and may certainly call - * png_get_mem_ptr, so fake a temporary png_struct to support this. - */ - png_struct dummy_struct = *png_ptr; - memset(png_ptr, 0, (sizeof *png_ptr)); - png_free(&dummy_struct, png_ptr); - -# ifdef PNG_SETJMP_SUPPORTED - /* We may have a jmp_buf left to deallocate. */ - png_free_jmpbuf(&dummy_struct); -# endif - } -} - -/* Allocate memory. For reasonable files, size should never exceed - * 64K. However, zlib may allocate more than 64K if you don't tell - * it not to. See zconf.h and png.h for more information. zlib does - * need to allocate exactly 64K, so whatever you call here must - * have the ability to do that. - */ -PNG_FUNCTION(png_voidp,PNGAPI -png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -{ - png_voidp ret; - - ret = png_malloc(png_ptr, size); - - if (ret != NULL) - memset(ret, 0, size); - - return ret; -} - -/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of - * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED. - * Checking and error handling must happen outside this routine; it returns NULL - * if the allocation cannot be done (for any reason.) - */ -PNG_FUNCTION(png_voidp /* PRIVATE */, -png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), - PNG_ALLOCATED) -{ - /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS - * allocators have also been removed in 1.6.0, so any 16-bit system now has - * to implement a user memory handler. This checks to be sure it isn't - * called with big numbers. - */ -#ifndef PNG_USER_MEM_SUPPORTED - PNG_UNUSED(png_ptr) -#endif - - /* Some compilers complain that this is always true. However, it - * can be false when integer overflow happens. - */ - if (size > 0 && size <= PNG_SIZE_MAX -# ifdef PNG_MAX_MALLOC_64K - && size <= 65536U -# endif - ) - { -#ifdef PNG_USER_MEM_SUPPORTED - if (png_ptr != NULL && png_ptr->malloc_fn != NULL) - return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size); - - else -#endif - return malloc((size_t)size); /* checked for truncation above */ - } - - else - return NULL; -} - -#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ - defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) -/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7 - * that arises because of the checks in png_realloc_array that are repeated in - * png_malloc_array. - */ -static png_voidp -png_malloc_array_checked(png_const_structrp png_ptr, int nelements, - size_t element_size) -{ - png_alloc_size_t req = (png_alloc_size_t)nelements; /* known to be > 0 */ - - if (req <= PNG_SIZE_MAX/element_size) - return png_malloc_base(png_ptr, req * element_size); - - /* The failure case when the request is too large */ - return NULL; -} - -PNG_FUNCTION(png_voidp /* PRIVATE */, -png_malloc_array,(png_const_structrp png_ptr, int nelements, - size_t element_size),PNG_ALLOCATED) -{ - if (nelements <= 0 || element_size == 0) - png_error(png_ptr, "internal error: array alloc"); - - return png_malloc_array_checked(png_ptr, nelements, element_size); -} - -PNG_FUNCTION(png_voidp /* PRIVATE */, -png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, - int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED) -{ - /* These are internal errors: */ - if (add_elements <= 0 || element_size == 0 || old_elements < 0 || - (old_array == NULL && old_elements > 0)) - png_error(png_ptr, "internal error: array realloc"); - - /* Check for overflow on the elements count (so the caller does not have to - * check.) - */ - if (add_elements <= INT_MAX - old_elements) - { - png_voidp new_array = png_malloc_array_checked(png_ptr, - old_elements+add_elements, element_size); - - if (new_array != NULL) - { - /* Because png_malloc_array worked the size calculations below cannot - * overflow. - */ - if (old_elements > 0) - memcpy(new_array, old_array, element_size*(unsigned)old_elements); - - memset((char*)new_array + element_size*(unsigned)old_elements, 0, - element_size*(unsigned)add_elements); - - return new_array; - } - } - - return NULL; /* error */ -} -#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */ - -/* Various functions that have different error handling are derived from this. - * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate - * function png_malloc_default is also provided. - */ -PNG_FUNCTION(png_voidp,PNGAPI -png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) -{ - png_voidp ret; - - if (png_ptr == NULL) - return NULL; - - ret = png_malloc_base(png_ptr, size); - - if (ret == NULL) - png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */ - - return ret; -} - -#ifdef PNG_USER_MEM_SUPPORTED -PNG_FUNCTION(png_voidp,PNGAPI -png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size), - PNG_ALLOCATED PNG_DEPRECATED) -{ - png_voidp ret; - - if (png_ptr == NULL) - return NULL; - - /* Passing 'NULL' here bypasses the application provided memory handler. */ - ret = png_malloc_base(NULL/*use malloc*/, size); - - if (ret == NULL) - png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */ - - return ret; -} -#endif /* USER_MEM */ - -/* This function was added at libpng version 1.2.3. The png_malloc_warn() - * function will issue a png_warning and return NULL instead of issuing a - * png_error, if it fails to allocate the requested memory. - */ -PNG_FUNCTION(png_voidp,PNGAPI -png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size), - PNG_ALLOCATED) -{ - if (png_ptr != NULL) - { - png_voidp ret = png_malloc_base(png_ptr, size); - - if (ret != NULL) - return ret; - - png_warning(png_ptr, "Out of memory"); - } - - return NULL; -} - -/* Free a pointer allocated by png_malloc(). If ptr is NULL, return - * without taking any action. - */ -void PNGAPI -png_free(png_const_structrp png_ptr, png_voidp ptr) -{ - if (png_ptr == NULL || ptr == NULL) - return; - -#ifdef PNG_USER_MEM_SUPPORTED - if (png_ptr->free_fn != NULL) - png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr); - - else - png_free_default(png_ptr, ptr); -} - -PNG_FUNCTION(void,PNGAPI -png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED) -{ - if (png_ptr == NULL || ptr == NULL) - return; -#endif /* USER_MEM */ - - free(ptr); -} - -#ifdef PNG_USER_MEM_SUPPORTED -/* This function is called when the application wants to use another method - * of allocating and freeing memory. - */ -void PNGAPI -png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr - malloc_fn, png_free_ptr free_fn) -{ - if (png_ptr != NULL) - { - png_ptr->mem_ptr = mem_ptr; - png_ptr->malloc_fn = malloc_fn; - png_ptr->free_fn = free_fn; - } -} - -/* This function returns a pointer to the mem_ptr associated with the user - * functions. The application should free any memory associated with this - * pointer before png_write_destroy and png_read_destroy are called. - */ -png_voidp PNGAPI -png_get_mem_ptr(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return NULL; - - return png_ptr->mem_ptr; -} -#endif /* USER_MEM */ -#endif /* READ || WRITE */ diff --git a/extern/libpng/pngpread.c b/extern/libpng/pngpread.c deleted file mode 100644 index e283627b7..000000000 --- a/extern/libpng/pngpread.c +++ /dev/null @@ -1,1096 +0,0 @@ - -/* pngpread.c - read a png file in push mode - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED - -/* Push model modes */ -#define PNG_READ_SIG_MODE 0 -#define PNG_READ_CHUNK_MODE 1 -#define PNG_READ_IDAT_MODE 2 -#define PNG_READ_tEXt_MODE 4 -#define PNG_READ_zTXt_MODE 5 -#define PNG_READ_DONE_MODE 6 -#define PNG_READ_iTXt_MODE 7 -#define PNG_ERROR_MODE 8 - -#define PNG_PUSH_SAVE_BUFFER_IF_FULL \ -if (png_ptr->push_length + 4 > png_ptr->buffer_size) \ - { png_push_save_buffer(png_ptr); return; } -#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \ -if (png_ptr->buffer_size < N) \ - { png_push_save_buffer(png_ptr); return; } - -void PNGAPI -png_process_data(png_structrp png_ptr, png_inforp info_ptr, - png_bytep buffer, size_t buffer_size) -{ - if (png_ptr == NULL || info_ptr == NULL) - return; - - png_push_restore_buffer(png_ptr, buffer, buffer_size); - - while (png_ptr->buffer_size) - { - png_process_some_data(png_ptr, info_ptr); - } -} - -size_t PNGAPI -png_process_data_pause(png_structrp png_ptr, int save) -{ - if (png_ptr != NULL) - { - /* It's easiest for the caller if we do the save; then the caller doesn't - * have to supply the same data again: - */ - if (save != 0) - png_push_save_buffer(png_ptr); - else - { - /* This includes any pending saved bytes: */ - size_t remaining = png_ptr->buffer_size; - png_ptr->buffer_size = 0; - - /* So subtract the saved buffer size, unless all the data - * is actually 'saved', in which case we just return 0 - */ - if (png_ptr->save_buffer_size < remaining) - return remaining - png_ptr->save_buffer_size; - } - } - - return 0; -} - -png_uint_32 PNGAPI -png_process_data_skip(png_structrp png_ptr) -{ -/* TODO: Deprecate and remove this API. - * Somewhere the implementation of this seems to have been lost, - * or abandoned. It was only to support some internal back-door access - * to png_struct) in libpng-1.4.x. - */ - png_app_warning(png_ptr, -"png_process_data_skip is not implemented in any current version of libpng"); - return 0; -} - -/* What we do with the incoming data depends on what we were previously - * doing before we ran out of data... - */ -void /* PRIVATE */ -png_process_some_data(png_structrp png_ptr, png_inforp info_ptr) -{ - if (png_ptr == NULL) - return; - - switch (png_ptr->process_mode) - { - case PNG_READ_SIG_MODE: - { - png_push_read_sig(png_ptr, info_ptr); - break; - } - - case PNG_READ_CHUNK_MODE: - { - png_push_read_chunk(png_ptr, info_ptr); - break; - } - - case PNG_READ_IDAT_MODE: - { - png_push_read_IDAT(png_ptr); - break; - } - - default: - { - png_ptr->buffer_size = 0; - break; - } - } -} - -/* Read any remaining signature bytes from the stream and compare them with - * the correct PNG signature. It is possible that this routine is called - * with bytes already read from the signature, either because they have been - * checked by the calling application, or because of multiple calls to this - * routine. - */ -void /* PRIVATE */ -png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) -{ - size_t num_checked = png_ptr->sig_bytes; /* SAFE, does not exceed 8 */ - size_t num_to_check = 8 - num_checked; - - if (png_ptr->buffer_size < num_to_check) - { - num_to_check = png_ptr->buffer_size; - } - - png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), - num_to_check); - png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check); - - if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) - { - if (num_checked < 4 && - png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) - png_error(png_ptr, "Not a PNG file"); - - else - png_error(png_ptr, "PNG file corrupted by ASCII conversion"); - } - else - { - if (png_ptr->sig_bytes >= 8) - { - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - } - } -} - -void /* PRIVATE */ -png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) -{ - png_uint_32 chunk_name; -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - int keep; /* unknown handling method */ -#endif - - /* First we make sure we have enough data for the 4-byte chunk name - * and the 4-byte chunk length before proceeding with decoding the - * chunk data. To fully decode each of these chunks, we also make - * sure we have enough data in the buffer for the 4-byte CRC at the - * end of every chunk (except IDAT, which is handled separately). - */ - if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) - { - png_byte chunk_length[4]; - png_byte chunk_tag[4]; - - PNG_PUSH_SAVE_BUFFER_IF_LT(8) - png_push_fill_buffer(png_ptr, chunk_length, 4); - png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); - png_reset_crc(png_ptr); - png_crc_read(png_ptr, chunk_tag, 4); - png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); - png_check_chunk_name(png_ptr, png_ptr->chunk_name); - png_check_chunk_length(png_ptr, png_ptr->push_length); - png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - } - - chunk_name = png_ptr->chunk_name; - - if (chunk_name == png_IDAT) - { - if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; - - /* If we reach an IDAT chunk, this means we have read all of the - * header chunks, and we can start reading the image (or if this - * is called after the image has been read - we have an error). - */ - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_error(png_ptr, "Missing IHDR before IDAT"); - - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - (png_ptr->mode & PNG_HAVE_PLTE) == 0) - png_error(png_ptr, "Missing PLTE before IDAT"); - - png_ptr->process_mode = PNG_READ_IDAT_MODE; - - if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0) - if (png_ptr->push_length == 0) - return; - - png_ptr->mode |= PNG_HAVE_IDAT; - - if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) - png_benign_error(png_ptr, "Too many IDATs found"); - } - - if (chunk_name == png_IHDR) - { - if (png_ptr->push_length != 13) - png_error(png_ptr, "Invalid IHDR length"); - - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); - } - - else if (chunk_name == png_IEND) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); - - png_ptr->process_mode = PNG_READ_DONE_MODE; - png_push_have_end(png_ptr, info_ptr); - } - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep); - - if (chunk_name == png_PLTE) - png_ptr->mode |= PNG_HAVE_PLTE; - } -#endif - - else if (chunk_name == png_PLTE) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); - } - - else if (chunk_name == png_IDAT) - { - png_ptr->idat_size = png_ptr->push_length; - png_ptr->process_mode = PNG_READ_IDAT_MODE; - png_push_have_info(png_ptr, info_ptr); - png_ptr->zstream.avail_out = - (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, - png_ptr->iwidth) + 1; - png_ptr->zstream.next_out = png_ptr->row_buf; - return; - } - -#ifdef PNG_READ_gAMA_SUPPORTED - else if (png_ptr->chunk_name == png_gAMA) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sBIT_SUPPORTED - else if (png_ptr->chunk_name == png_sBIT) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_cHRM_SUPPORTED - else if (png_ptr->chunk_name == png_cHRM) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sRGB_SUPPORTED - else if (chunk_name == png_sRGB) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_iCCP_SUPPORTED - else if (png_ptr->chunk_name == png_iCCP) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sPLT_SUPPORTED - else if (chunk_name == png_sPLT) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_tRNS_SUPPORTED - else if (chunk_name == png_tRNS) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_bKGD_SUPPORTED - else if (chunk_name == png_bKGD) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_hIST_SUPPORTED - else if (chunk_name == png_hIST) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_pHYs_SUPPORTED - else if (chunk_name == png_pHYs) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_oFFs_SUPPORTED - else if (chunk_name == png_oFFs) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); - } -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED - else if (chunk_name == png_pCAL) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_sCAL_SUPPORTED - else if (chunk_name == png_sCAL) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_tIME_SUPPORTED - else if (chunk_name == png_tIME) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_tEXt_SUPPORTED - else if (chunk_name == png_tEXt) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_zTXt_SUPPORTED - else if (chunk_name == png_zTXt) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif -#ifdef PNG_READ_iTXt_SUPPORTED - else if (chunk_name == png_iTXt) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); - } -#endif - - else - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, - PNG_HANDLE_CHUNK_AS_DEFAULT); - } - - png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; -} - -void PNGCBAPI -png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length) -{ - png_bytep ptr; - - if (png_ptr == NULL) - return; - - ptr = buffer; - if (png_ptr->save_buffer_size != 0) - { - size_t save_size; - - if (length < png_ptr->save_buffer_size) - save_size = length; - - else - save_size = png_ptr->save_buffer_size; - - memcpy(ptr, png_ptr->save_buffer_ptr, save_size); - length -= save_size; - ptr += save_size; - png_ptr->buffer_size -= save_size; - png_ptr->save_buffer_size -= save_size; - png_ptr->save_buffer_ptr += save_size; - } - if (length != 0 && png_ptr->current_buffer_size != 0) - { - size_t save_size; - - if (length < png_ptr->current_buffer_size) - save_size = length; - - else - save_size = png_ptr->current_buffer_size; - - memcpy(ptr, png_ptr->current_buffer_ptr, save_size); - png_ptr->buffer_size -= save_size; - png_ptr->current_buffer_size -= save_size; - png_ptr->current_buffer_ptr += save_size; - } -} - -void /* PRIVATE */ -png_push_save_buffer(png_structrp png_ptr) -{ - if (png_ptr->save_buffer_size != 0) - { - if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) - { - size_t i, istop; - png_bytep sp; - png_bytep dp; - - istop = png_ptr->save_buffer_size; - for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; - i < istop; i++, sp++, dp++) - { - *dp = *sp; - } - } - } - if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > - png_ptr->save_buffer_max) - { - size_t new_max; - png_bytep old_buffer; - - if (png_ptr->save_buffer_size > PNG_SIZE_MAX - - (png_ptr->current_buffer_size + 256)) - { - png_error(png_ptr, "Potential overflow of save_buffer"); - } - - new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; - old_buffer = png_ptr->save_buffer; - png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, - (size_t)new_max); - - if (png_ptr->save_buffer == NULL) - { - png_free(png_ptr, old_buffer); - png_error(png_ptr, "Insufficient memory for save_buffer"); - } - - if (old_buffer) - memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); - else if (png_ptr->save_buffer_size) - png_error(png_ptr, "save_buffer error"); - png_free(png_ptr, old_buffer); - png_ptr->save_buffer_max = new_max; - } - if (png_ptr->current_buffer_size) - { - memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, - png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); - png_ptr->save_buffer_size += png_ptr->current_buffer_size; - png_ptr->current_buffer_size = 0; - } - png_ptr->save_buffer_ptr = png_ptr->save_buffer; - png_ptr->buffer_size = 0; -} - -void /* PRIVATE */ -png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer, - size_t buffer_length) -{ - png_ptr->current_buffer = buffer; - png_ptr->current_buffer_size = buffer_length; - png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; - png_ptr->current_buffer_ptr = png_ptr->current_buffer; -} - -void /* PRIVATE */ -png_push_read_IDAT(png_structrp png_ptr) -{ - if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) - { - png_byte chunk_length[4]; - png_byte chunk_tag[4]; - - /* TODO: this code can be commoned up with the same code in push_read */ - PNG_PUSH_SAVE_BUFFER_IF_LT(8) - png_push_fill_buffer(png_ptr, chunk_length, 4); - png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); - png_reset_crc(png_ptr); - png_crc_read(png_ptr, chunk_tag, 4); - png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); - png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - - if (png_ptr->chunk_name != png_IDAT) - { - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) - png_error(png_ptr, "Not enough compressed data"); - - return; - } - - png_ptr->idat_size = png_ptr->push_length; - } - - if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0) - { - size_t save_size = png_ptr->save_buffer_size; - png_uint_32 idat_size = png_ptr->idat_size; - - /* We want the smaller of 'idat_size' and 'current_buffer_size', but they - * are of different types and we don't know which variable has the fewest - * bits. Carefully select the smaller and cast it to the type of the - * larger - this cannot overflow. Do not cast in the following test - it - * will break on either 16-bit or 64-bit platforms. - */ - if (idat_size < save_size) - save_size = (size_t)idat_size; - - else - idat_size = (png_uint_32)save_size; - - png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); - - png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); - - png_ptr->idat_size -= idat_size; - png_ptr->buffer_size -= save_size; - png_ptr->save_buffer_size -= save_size; - png_ptr->save_buffer_ptr += save_size; - } - - if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0) - { - size_t save_size = png_ptr->current_buffer_size; - png_uint_32 idat_size = png_ptr->idat_size; - - /* We want the smaller of 'idat_size' and 'current_buffer_size', but they - * are of different types and we don't know which variable has the fewest - * bits. Carefully select the smaller and cast it to the type of the - * larger - this cannot overflow. - */ - if (idat_size < save_size) - save_size = (size_t)idat_size; - - else - idat_size = (png_uint_32)save_size; - - png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); - - png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); - - png_ptr->idat_size -= idat_size; - png_ptr->buffer_size -= save_size; - png_ptr->current_buffer_size -= save_size; - png_ptr->current_buffer_ptr += save_size; - } - - if (png_ptr->idat_size == 0) - { - PNG_PUSH_SAVE_BUFFER_IF_LT(4) - png_crc_finish(png_ptr, 0); - png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; - png_ptr->mode |= PNG_AFTER_IDAT; - png_ptr->zowner = 0; - } -} - -void /* PRIVATE */ -png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, - size_t buffer_length) -{ - /* The caller checks for a non-zero buffer length. */ - if (!(buffer_length > 0) || buffer == NULL) - png_error(png_ptr, "No IDAT data (internal error)"); - - /* This routine must process all the data it has been given - * before returning, calling the row callback as required to - * handle the uncompressed results. - */ - png_ptr->zstream.next_in = buffer; - /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ - png_ptr->zstream.avail_in = (uInt)buffer_length; - - /* Keep going until the decompressed data is all processed - * or the stream marked as finished. - */ - while (png_ptr->zstream.avail_in > 0 && - (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) - { - int ret; - - /* We have data for zlib, but we must check that zlib - * has someplace to put the results. It doesn't matter - * if we don't expect any results -- it may be the input - * data is just the LZ end code. - */ - if (!(png_ptr->zstream.avail_out > 0)) - { - /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ - png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, - png_ptr->iwidth) + 1); - - png_ptr->zstream.next_out = png_ptr->row_buf; - } - - /* Using Z_SYNC_FLUSH here means that an unterminated - * LZ stream (a stream with a missing end code) can still - * be handled, otherwise (Z_NO_FLUSH) a future zlib - * implementation might defer output and therefore - * change the current behavior (see comments in inflate.c - * for why this doesn't happen at present with zlib 1.2.5). - */ - ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH); - - /* Check for any failure before proceeding. */ - if (ret != Z_OK && ret != Z_STREAM_END) - { - /* Terminate the decompression. */ - png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; - png_ptr->zowner = 0; - - /* This may be a truncated stream (missing or - * damaged end code). Treat that as a warning. - */ - if (png_ptr->row_number >= png_ptr->num_rows || - png_ptr->pass > 6) - png_warning(png_ptr, "Truncated compressed data in IDAT"); - - else - { - if (ret == Z_DATA_ERROR) - png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch"); - else - png_error(png_ptr, "Decompression error in IDAT"); - } - - /* Skip the check on unprocessed input */ - return; - } - - /* Did inflate output any data? */ - if (png_ptr->zstream.next_out != png_ptr->row_buf) - { - /* Is this unexpected data after the last row? - * If it is, artificially terminate the LZ output - * here. - */ - if (png_ptr->row_number >= png_ptr->num_rows || - png_ptr->pass > 6) - { - /* Extra data. */ - png_warning(png_ptr, "Extra compressed data in IDAT"); - png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; - png_ptr->zowner = 0; - - /* Do no more processing; skip the unprocessed - * input check below. - */ - return; - } - - /* Do we have a complete row? */ - if (png_ptr->zstream.avail_out == 0) - png_push_process_row(png_ptr); - } - - /* And check for the end of the stream. */ - if (ret == Z_STREAM_END) - png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; - } - - /* All the data should have been processed, if anything - * is left at this point we have bytes of IDAT data - * after the zlib end code. - */ - if (png_ptr->zstream.avail_in > 0) - png_warning(png_ptr, "Extra compression data in IDAT"); -} - -void /* PRIVATE */ -png_push_process_row(png_structrp png_ptr) -{ - /* 1.5.6: row_info moved out of png_struct to a local here. */ - png_row_info row_info; - - row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ - row_info.color_type = png_ptr->color_type; - row_info.bit_depth = png_ptr->bit_depth; - row_info.channels = png_ptr->channels; - row_info.pixel_depth = png_ptr->pixel_depth; - row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); - - if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) - { - if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) - png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, - png_ptr->prev_row + 1, png_ptr->row_buf[0]); - else - png_error(png_ptr, "bad adaptive filter value"); - } - - /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before - * 1.5.6, while the buffer really is this big in current versions of libpng - * it may not be in the future, so this was changed just to copy the - * interlaced row count: - */ - memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED - if (png_ptr->transformations != 0) - png_do_read_transformations(png_ptr, &row_info); -#endif - - /* The transformed pixel depth should match the depth now in row_info. */ - if (png_ptr->transformed_pixel_depth == 0) - { - png_ptr->transformed_pixel_depth = row_info.pixel_depth; - if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) - png_error(png_ptr, "progressive row overflow"); - } - - else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) - png_error(png_ptr, "internal progressive row size calculation error"); - - -#ifdef PNG_READ_INTERLACING_SUPPORTED - /* Expand interlaced rows to full size */ - if (png_ptr->interlaced != 0 && - (png_ptr->transformations & PNG_INTERLACE) != 0) - { - if (png_ptr->pass < 6) - png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, - png_ptr->transformations); - - switch (png_ptr->pass) - { - case 0: - { - int i; - for (i = 0; i < 8 && png_ptr->pass == 0; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */ - } - - if (png_ptr->pass == 2) /* Pass 1 might be empty */ - { - for (i = 0; i < 4 && png_ptr->pass == 2; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - if (png_ptr->pass == 4 && png_ptr->height <= 4) - { - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - if (png_ptr->pass == 6 && png_ptr->height <= 4) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - break; - } - - case 1: - { - int i; - for (i = 0; i < 8 && png_ptr->pass == 1; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 2) /* Skip top 4 generated rows */ - { - for (i = 0; i < 4 && png_ptr->pass == 2; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - break; - } - - case 2: - { - int i; - - for (i = 0; i < 4 && png_ptr->pass == 2; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - for (i = 0; i < 4 && png_ptr->pass == 2; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 4) /* Pass 3 might be empty */ - { - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - break; - } - - case 3: - { - int i; - - for (i = 0; i < 4 && png_ptr->pass == 3; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 4) /* Skip top two generated rows */ - { - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - - break; - } - - case 4: - { - int i; - - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 6) /* Pass 5 might be empty */ - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - break; - } - - case 5: - { - int i; - - for (i = 0; i < 2 && png_ptr->pass == 5; i++) - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } - - if (png_ptr->pass == 6) /* Skip top generated row */ - { - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - - break; - } - - default: - case 6: - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - - if (png_ptr->pass != 6) - break; - - png_push_have_row(png_ptr, NULL); - png_read_push_finish_row(png_ptr); - } - } - } - else -#endif - { - png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); - } -} - -void /* PRIVATE */ -png_read_push_finish_row(png_structrp png_ptr) -{ -#ifdef PNG_READ_INTERLACING_SUPPORTED - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static const png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static const png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static const png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static const png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; - - /* Height of interlace block. This is not currently used - if you need - * it, uncomment it here and in png.h - static const png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; - */ -#endif - - png_ptr->row_number++; - if (png_ptr->row_number < png_ptr->num_rows) - return; - -#ifdef PNG_READ_INTERLACING_SUPPORTED - if (png_ptr->interlaced != 0) - { - png_ptr->row_number = 0; - memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); - - do - { - png_ptr->pass++; - if ((png_ptr->pass == 1 && png_ptr->width < 5) || - (png_ptr->pass == 3 && png_ptr->width < 3) || - (png_ptr->pass == 5 && png_ptr->width < 2)) - png_ptr->pass++; - - if (png_ptr->pass > 7) - png_ptr->pass--; - - if (png_ptr->pass >= 7) - break; - - png_ptr->iwidth = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - - if ((png_ptr->transformations & PNG_INTERLACE) != 0) - break; - - png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; - - } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); - } -#endif /* READ_INTERLACING */ -} - -void /* PRIVATE */ -png_push_have_info(png_structrp png_ptr, png_inforp info_ptr) -{ - if (png_ptr->info_fn != NULL) - (*(png_ptr->info_fn))(png_ptr, info_ptr); -} - -void /* PRIVATE */ -png_push_have_end(png_structrp png_ptr, png_inforp info_ptr) -{ - if (png_ptr->end_fn != NULL) - (*(png_ptr->end_fn))(png_ptr, info_ptr); -} - -void /* PRIVATE */ -png_push_have_row(png_structrp png_ptr, png_bytep row) -{ - if (png_ptr->row_fn != NULL) - (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, - (int)png_ptr->pass); -} - -#ifdef PNG_READ_INTERLACING_SUPPORTED -void PNGAPI -png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row, - png_const_bytep new_row) -{ - if (png_ptr == NULL) - return; - - /* new_row is a flag here - if it is NULL then the app callback was called - * from an empty row (see the calls to png_struct::row_fn below), otherwise - * it must be png_ptr->row_buf+1 - */ - if (new_row != NULL) - png_combine_row(png_ptr, old_row, 1/*blocky display*/); -} -#endif /* READ_INTERLACING */ - -void PNGAPI -png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr, - png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, - png_progressive_end_ptr end_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->info_fn = info_fn; - png_ptr->row_fn = row_fn; - png_ptr->end_fn = end_fn; - - png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); -} - -png_voidp PNGAPI -png_get_progressive_ptr(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return (NULL); - - return png_ptr->io_ptr; -} -#endif /* PROGRESSIVE_READ */ diff --git a/extern/libpng/pngpriv.h b/extern/libpng/pngpriv.h deleted file mode 100644 index 583c26f9b..000000000 --- a/extern/libpng/pngpriv.h +++ /dev/null @@ -1,2152 +0,0 @@ - -/* pngpriv.h - private declarations for use inside libpng - * - * Copyright (c) 2018-2019 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* The symbols declared in this file (including the functions declared - * as extern) are PRIVATE. They are not part of the libpng public - * interface, and are not recommended for use by regular applications. - * Some of them may become public in the future; others may stay private, - * change in an incompatible way, or even disappear. - * Although the libpng users are not forbidden to include this header, - * they should be well aware of the issues that may arise from doing so. - */ - -#ifndef PNGPRIV_H -#define PNGPRIV_H - -/* Feature Test Macros. The following are defined here to ensure that correctly - * implemented libraries reveal the APIs libpng needs to build and hide those - * that are not needed and potentially damaging to the compilation. - * - * Feature Test Macros must be defined before any system header is included (see - * POSIX 1003.1 2.8.2 "POSIX Symbols." - * - * These macros only have an effect if the operating system supports either - * POSIX 1003.1 or C99, or both. On other operating systems (particularly - * Windows/Visual Studio) there is no effect; the OS specific tests below are - * still required (as of 2011-05-02.) - */ -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ -#endif - -#ifndef PNG_VERSION_INFO_ONLY -/* Standard library headers not required by png.h: */ -# include -# include -#endif - -#define PNGLIB_BUILD /*libpng is being built, not used*/ - -/* If HAVE_CONFIG_H is defined during the build then the build system must - * provide an appropriate "config.h" file on the include path. The header file - * must provide definitions as required below (search for "HAVE_CONFIG_H"); - * see configure.ac for more details of the requirements. The macro - * "PNG_NO_CONFIG_H" is provided for maintainers to test for dependencies on - * 'configure'; define this macro to prevent the configure build including the - * configure generated config.h. Libpng is expected to compile without *any* - * special build system support on a reasonably ANSI-C compliant system. - */ -#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) -# include - - /* Pick up the definition of 'restrict' from config.h if it was read: */ -# define PNG_RESTRICT restrict -#endif - -/* To support symbol prefixing it is necessary to know *before* including png.h - * whether the fixed point (and maybe other) APIs are exported, because if they - * are not internal definitions may be required. This is handled below just - * before png.h is included, but load the configuration now if it is available. - */ -#ifndef PNGLCONF_H -# include "pnglibconf.h" -#endif - -/* Local renames may change non-exported API functions from png.h */ -#if defined(PNG_PREFIX) && !defined(PNGPREFIX_H) -# include "pngprefix.h" -#endif - -#ifdef PNG_USER_CONFIG -# include "pngusr.h" - /* These should have been defined in pngusr.h */ -# ifndef PNG_USER_PRIVATEBUILD -# define PNG_USER_PRIVATEBUILD "Custom libpng build" -# endif -# ifndef PNG_USER_DLLFNAME_POSTFIX -# define PNG_USER_DLLFNAME_POSTFIX "Cb" -# endif -#endif - -/* Compile time options. - * ===================== - * In a multi-arch build the compiler may compile the code several times for the - * same object module, producing different binaries for different architectures. - * When this happens configure-time setting of the target host options cannot be - * done and this interferes with the handling of the ARM NEON optimizations, and - * possibly other similar optimizations. Put additional tests here; in general - * this is needed when the same option can be changed at both compile time and - * run time depending on the target OS (i.e. iOS vs Android.) - * - * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because - * this is not possible with certain compilers (Oracle SUN OS CC), as a result - * it is necessary to ensure that all extern functions that *might* be used - * regardless of $(CFLAGS) get declared in this file. The test on __ARM_NEON__ - * below is one example of this behavior because it is controlled by the - * presence or not of -mfpu=neon on the GCC command line, it is possible to do - * this in $(CC), e.g. "CC=gcc -mfpu=neon", but people who build libpng rarely - * do this. - */ -#ifndef PNG_ARM_NEON_OPT - /* ARM NEON optimizations are being controlled by the compiler settings, - * typically the target FPU. If the FPU has been set to NEON (-mfpu=neon - * with GCC) then the compiler will define __ARM_NEON__ and we can rely - * unconditionally on NEON instructions not crashing, otherwise we must - * disable use of NEON instructions. - * - * NOTE: at present these optimizations depend on 'ALIGNED_MEMORY', so they - * can only be turned on automatically if that is supported too. If - * PNG_ARM_NEON_OPT is set in CPPFLAGS (to >0) then arm/arm_init.c will fail - * to compile with an appropriate #error if ALIGNED_MEMORY has been turned - * off. - * - * Note that gcc-4.9 defines __ARM_NEON instead of the deprecated - * __ARM_NEON__, so we check both variants. - * - * To disable ARM_NEON optimizations entirely, and skip compiling the - * associated assembler code, pass --enable-arm-neon=no to configure - * or put -DPNG_ARM_NEON_OPT=0 in CPPFLAGS. - */ -# if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \ - defined(PNG_ALIGNED_MEMORY_SUPPORTED) -# define PNG_ARM_NEON_OPT 2 -# else -# define PNG_ARM_NEON_OPT 0 -# endif -#endif - -#if PNG_ARM_NEON_OPT > 0 - /* NEON optimizations are to be at least considered by libpng, so enable the - * callbacks to do this. - */ -# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon - - /* By default the 'intrinsics' code in arm/filter_neon_intrinsics.c is used - * if possible - if __ARM_NEON__ is set and the compiler version is not known - * to be broken. This is controlled by PNG_ARM_NEON_IMPLEMENTATION which can - * be: - * - * 1 The intrinsics code (the default with __ARM_NEON__) - * 2 The hand coded assembler (the default without __ARM_NEON__) - * - * It is possible to set PNG_ARM_NEON_IMPLEMENTATION in CPPFLAGS, however - * this is *NOT* supported and may cease to work even after a minor revision - * to libpng. It *is* valid to do this for testing purposes, e.g. speed - * testing or a new compiler, but the results should be communicated to the - * libpng implementation list for incorporation in the next minor release. - */ -# ifndef PNG_ARM_NEON_IMPLEMENTATION -# if defined(__ARM_NEON__) || defined(__ARM_NEON) -# if defined(__clang__) - /* At present it is unknown by the libpng developers which versions - * of clang support the intrinsics, however some or perhaps all - * versions do not work with the assembler so this may be - * irrelevant, so just use the default (do nothing here.) - */ -# elif defined(__GNUC__) - /* GCC 4.5.4 NEON support is known to be broken. 4.6.3 is known to - * work, so if this *is* GCC, or G++, look for a version >4.5 - */ -# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6) -# define PNG_ARM_NEON_IMPLEMENTATION 2 -# endif /* no GNUC support */ -# endif /* __GNUC__ */ -# else /* !defined __ARM_NEON__ */ - /* The 'intrinsics' code simply won't compile without this -mfpu=neon: - */ -# if !defined(__aarch64__) - /* The assembler code currently does not work on ARM64 */ -# define PNG_ARM_NEON_IMPLEMENTATION 2 -# endif /* __aarch64__ */ -# endif /* __ARM_NEON__ */ -# endif /* !PNG_ARM_NEON_IMPLEMENTATION */ - -# ifndef PNG_ARM_NEON_IMPLEMENTATION - /* Use the intrinsics code by default. */ -# define PNG_ARM_NEON_IMPLEMENTATION 1 -# endif -#endif /* PNG_ARM_NEON_OPT > 0 */ - -#ifndef PNG_MIPS_MSA_OPT -# if defined(__mips_msa) && (__mips_isa_rev >= 5) && defined(PNG_ALIGNED_MEMORY_SUPPORTED) -# define PNG_MIPS_MSA_OPT 2 -# else -# define PNG_MIPS_MSA_OPT 0 -# endif -#endif - -#ifndef PNG_POWERPC_VSX_OPT -# if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__) -# define PNG_POWERPC_VSX_OPT 2 -# else -# define PNG_POWERPC_VSX_OPT 0 -# endif -#endif - -#ifndef PNG_INTEL_SSE_OPT -# ifdef PNG_INTEL_SSE - /* Only check for SSE if the build configuration has been modified to - * enable SSE optimizations. This means that these optimizations will - * be off by default. See contrib/intel for more details. - */ -# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \ - defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \ - (defined(_M_IX86_FP) && _M_IX86_FP >= 2) -# define PNG_INTEL_SSE_OPT 1 -# else -# define PNG_INTEL_SSE_OPT 0 -# endif -# else -# define PNG_INTEL_SSE_OPT 0 -# endif -#endif - -#if PNG_INTEL_SSE_OPT > 0 -# ifndef PNG_INTEL_SSE_IMPLEMENTATION -# if defined(__SSE4_1__) || defined(__AVX__) - /* We are not actually using AVX, but checking for AVX is the best - way we can detect SSE4.1 and SSSE3 on MSVC. - */ -# define PNG_INTEL_SSE_IMPLEMENTATION 3 -# elif defined(__SSSE3__) -# define PNG_INTEL_SSE_IMPLEMENTATION 2 -# elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \ - (defined(_M_IX86_FP) && _M_IX86_FP >= 2) -# define PNG_INTEL_SSE_IMPLEMENTATION 1 -# else -# define PNG_INTEL_SSE_IMPLEMENTATION 0 -# endif -# endif - -# if PNG_INTEL_SSE_IMPLEMENTATION > 0 -# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2 -# endif -#else -# define PNG_INTEL_SSE_IMPLEMENTATION 0 -#endif - -#if PNG_MIPS_MSA_OPT > 0 -# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa -# ifndef PNG_MIPS_MSA_IMPLEMENTATION -# if defined(__mips_msa) -# if defined(__clang__) -# elif defined(__GNUC__) -# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) -# define PNG_MIPS_MSA_IMPLEMENTATION 2 -# endif /* no GNUC support */ -# endif /* __GNUC__ */ -# else /* !defined __mips_msa */ -# define PNG_MIPS_MSA_IMPLEMENTATION 2 -# endif /* __mips_msa */ -# endif /* !PNG_MIPS_MSA_IMPLEMENTATION */ - -# ifndef PNG_MIPS_MSA_IMPLEMENTATION -# define PNG_MIPS_MSA_IMPLEMENTATION 1 -# endif -#endif /* PNG_MIPS_MSA_OPT > 0 */ - -#if PNG_POWERPC_VSX_OPT > 0 -# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx -# define PNG_POWERPC_VSX_IMPLEMENTATION 1 -#endif - - -/* Is this a build of a DLL where compilation of the object modules requires - * different preprocessor settings to those required for a simple library? If - * so PNG_BUILD_DLL must be set. - * - * If libpng is used inside a DLL but that DLL does not export the libpng APIs - * PNG_BUILD_DLL must not be set. To avoid the code below kicking in build a - * static library of libpng then link the DLL against that. - */ -#ifndef PNG_BUILD_DLL -# ifdef DLL_EXPORT - /* This is set by libtool when files are compiled for a DLL; libtool - * always compiles twice, even on systems where it isn't necessary. Set - * PNG_BUILD_DLL in case it is necessary: - */ -# define PNG_BUILD_DLL -# else -# ifdef _WINDLL - /* This is set by the Microsoft Visual Studio IDE in projects that - * build a DLL. It can't easily be removed from those projects (it - * isn't visible in the Visual Studio UI) so it is a fairly reliable - * indication that PNG_IMPEXP needs to be set to the DLL export - * attributes. - */ -# define PNG_BUILD_DLL -# else -# ifdef __DLL__ - /* This is set by the Borland C system when compiling for a DLL - * (as above.) - */ -# define PNG_BUILD_DLL -# else - /* Add additional compiler cases here. */ -# endif -# endif -# endif -#endif /* Setting PNG_BUILD_DLL if required */ - -/* See pngconf.h for more details: the builder of the library may set this on - * the command line to the right thing for the specific compilation system or it - * may be automagically set above (at present we know of no system where it does - * need to be set on the command line.) - * - * PNG_IMPEXP must be set here when building the library to prevent pngconf.h - * setting it to the "import" setting for a DLL build. - */ -#ifndef PNG_IMPEXP -# ifdef PNG_BUILD_DLL -# define PNG_IMPEXP PNG_DLL_EXPORT -# else - /* Not building a DLL, or the DLL doesn't require specific export - * definitions. - */ -# define PNG_IMPEXP -# endif -#endif - -/* No warnings for private or deprecated functions in the build: */ -#ifndef PNG_DEPRECATED -# define PNG_DEPRECATED -#endif -#ifndef PNG_PRIVATE -# define PNG_PRIVATE -#endif - -/* Symbol preprocessing support. - * - * To enable listing global, but internal, symbols the following macros should - * always be used to declare an extern data or function object in this file. - */ -#ifndef PNG_INTERNAL_DATA -# define PNG_INTERNAL_DATA(type, name, array) PNG_LINKAGE_DATA type name array -#endif - -#ifndef PNG_INTERNAL_FUNCTION -# define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\ - PNG_LINKAGE_FUNCTION PNG_FUNCTION(type, name, args, PNG_EMPTY attributes) -#endif - -#ifndef PNG_INTERNAL_CALLBACK -# define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\ - PNG_LINKAGE_CALLBACK PNG_FUNCTION(type, (PNGCBAPI name), args,\ - PNG_EMPTY attributes) -#endif - -/* If floating or fixed point APIs are disabled they may still be compiled - * internally. To handle this make sure they are declared as the appropriate - * internal extern function (otherwise the symbol prefixing stuff won't work and - * the functions will be used without definitions.) - * - * NOTE: although all the API functions are declared here they are not all - * actually built! Because the declarations are still made it is necessary to - * fake out types that they depend on. - */ -#ifndef PNG_FP_EXPORT -# ifndef PNG_FLOATING_POINT_SUPPORTED -# define PNG_FP_EXPORT(ordinal, type, name, args)\ - PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY); -# ifndef PNG_VERSION_INFO_ONLY - typedef struct png_incomplete png_double; - typedef png_double* png_doublep; - typedef const png_double* png_const_doublep; - typedef png_double** png_doublepp; -# endif -# endif -#endif -#ifndef PNG_FIXED_EXPORT -# ifndef PNG_FIXED_POINT_SUPPORTED -# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ - PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY); -# endif -#endif - -#include "png.h" - -/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */ -#ifndef PNG_DLL_EXPORT -# define PNG_DLL_EXPORT -#endif - -/* This is a global switch to set the compilation for an installed system - * (a release build). It can be set for testing debug builds to ensure that - * they will compile when the build type is switched to RC or STABLE, the - * default is just to use PNG_LIBPNG_BUILD_BASE_TYPE. Set this in CPPFLAGS - * with either: - * - * -DPNG_RELEASE_BUILD Turns on the release compile path - * -DPNG_RELEASE_BUILD=0 Turns it off - * or in your pngusr.h with - * #define PNG_RELEASE_BUILD=1 Turns on the release compile path - * #define PNG_RELEASE_BUILD=0 Turns it off - */ -#ifndef PNG_RELEASE_BUILD -# define PNG_RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC) -#endif - -/* SECURITY and SAFETY: - * - * libpng is built with support for internal limits on image dimensions and - * memory usage. These are documented in scripts/pnglibconf.dfa of the - * source and recorded in the machine generated header file pnglibconf.h. - */ - -/* If you are running on a machine where you cannot allocate more - * than 64K of memory at once, uncomment this. While libpng will not - * normally need that much memory in a chunk (unless you load up a very - * large file), zlib needs to know how big of a chunk it can use, and - * libpng thus makes sure to check any memory allocation to verify it - * will fit into memory. - * - * zlib provides 'MAXSEG_64K' which, if defined, indicates the - * same limit and pngconf.h (already included) sets the limit - * if certain operating systems are detected. - */ -#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) -# define PNG_MAX_MALLOC_64K -#endif - -#ifndef PNG_UNUSED -/* Unused formal parameter warnings are silenced using the following macro - * which is expected to have no bad effects on performance (optimizing - * compilers will probably remove it entirely). Note that if you replace - * it with something other than whitespace, you must include the terminating - * semicolon. - */ -# define PNG_UNUSED(param) (void)param; -#endif - -/* Just a little check that someone hasn't tried to define something - * contradictory. - */ -#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) -# undef PNG_ZBUF_SIZE -# define PNG_ZBUF_SIZE 65536L -#endif - -/* If warnings or errors are turned off the code is disabled or redirected here. - * From 1.5.4 functions have been added to allow very limited formatting of - * error and warning messages - this code will also be disabled here. - */ -#ifdef PNG_WARNINGS_SUPPORTED -# define PNG_WARNING_PARAMETERS(p) png_warning_parameters p; -#else -# define png_warning_parameter(p,number,string) ((void)0) -# define png_warning_parameter_unsigned(p,number,format,value) ((void)0) -# define png_warning_parameter_signed(p,number,format,value) ((void)0) -# define png_formatted_warning(pp,p,message) ((void)(pp)) -# define PNG_WARNING_PARAMETERS(p) -#endif -#ifndef PNG_ERROR_TEXT_SUPPORTED -# define png_fixed_error(s1,s2) png_err(s1) -#endif - -/* Some fixed point APIs are still required even if not exported because - * they get used by the corresponding floating point APIs. This magic - * deals with this: - */ -#ifdef PNG_FIXED_POINT_SUPPORTED -# define PNGFAPI PNGAPI -#else -# define PNGFAPI /* PRIVATE */ -#endif - -#ifndef PNG_VERSION_INFO_ONLY -/* Other defines specific to compilers can go here. Try to keep - * them inside an appropriate ifdef/endif pair for portability. - */ - -/* C allows up-casts from (void*) to any pointer and (const void*) to any - * pointer to a const object. C++ regards this as a type error and requires an - * explicit, static, cast and provides the static_cast<> rune to ensure that - * const is not cast away. - */ -#ifdef __cplusplus -# define png_voidcast(type, value) static_cast(value) -# define png_constcast(type, value) const_cast(value) -# define png_aligncast(type, value) \ - static_cast(static_cast(value)) -# define png_aligncastconst(type, value) \ - static_cast(static_cast(value)) -#else -# define png_voidcast(type, value) (value) -# ifdef _WIN64 -# ifdef __GNUC__ - typedef unsigned long long png_ptruint; -# else - typedef unsigned __int64 png_ptruint; -# endif -# else - typedef unsigned long png_ptruint; -# endif -# define png_constcast(type, value) ((type)(png_ptruint)(const void*)(value)) -# define png_aligncast(type, value) ((void*)(value)) -# define png_aligncastconst(type, value) ((const void*)(value)) -#endif /* __cplusplus */ - -#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\ - defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) - /* png.c requires the following ANSI-C constants if the conversion of - * floating point to ASCII is implemented therein: - * - * DBL_DIG Maximum number of decimal digits (can be set to any constant) - * DBL_MIN Smallest normalized fp number (can be set to an arbitrary value) - * DBL_MAX Maximum floating point number (can be set to an arbitrary value) - */ -# include - -# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ - defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) - /* We need to check that hasn't already been included earlier - * as it seems it doesn't agree with , yet we should really use - * if possible. - */ -# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) -# include -# endif -# else -# include -# endif -# if defined(_AMIGA) && defined(__SASC) && defined(_M68881) - /* Amiga SAS/C: We must include builtin FPU functions when compiling using - * MATH=68881 - */ -# include -# endif -#endif - -/* This provides the non-ANSI (far) memory allocation routines. */ -#if defined(__TURBOC__) && defined(__MSDOS__) -# include -# include -#endif - -#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \ - defined(_WIN32) || defined(__WIN32__) -# include /* defines _WINDOWS_ macro */ -#endif -#endif /* PNG_VERSION_INFO_ONLY */ - -/* Moved here around 1.5.0beta36 from pngconf.h */ -/* Users may want to use these so they are not private. Any library - * functions that are passed far data must be model-independent. - */ - -/* Memory model/platform independent fns */ -#ifndef PNG_ABORT -# ifdef _WINDOWS_ -# define PNG_ABORT() ExitProcess(0) -# else -# define PNG_ABORT() abort() -# endif -#endif - -/* These macros may need to be architecture dependent. */ -#define PNG_ALIGN_NONE 0 /* do not use data alignment */ -#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */ -#ifdef offsetof -# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */ -#else -# define PNG_ALIGN_OFFSET -1 /* prevent the use of this */ -#endif -#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */ - -#ifndef PNG_ALIGN_TYPE - /* Default to using aligned access optimizations and requiring alignment to a - * multiple of the data type size. Override in a compiler specific fashion - * if necessary by inserting tests here: - */ -# define PNG_ALIGN_TYPE PNG_ALIGN_SIZE -#endif - -#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE - /* This is used because in some compiler implementations non-aligned - * structure members are supported, so the offsetof approach below fails. - * Set PNG_ALIGN_SIZE=0 for compiler combinations where unaligned access - * is good for performance. Do not do this unless you have tested the result - * and understand it. - */ -# define png_alignof(type) (sizeof (type)) -#else -# if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET -# define png_alignof(type) offsetof(struct{char c; type t;}, t) -# else -# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS -# define png_alignof(type) (1) -# endif - /* Else leave png_alignof undefined to prevent use thereof */ -# endif -#endif - -/* This implicitly assumes alignment is always to a power of 2. */ -#ifdef png_alignof -# define png_isaligned(ptr, type)\ - (((type)((const char*)ptr-(const char*)0) & \ - (type)(png_alignof(type)-1)) == 0) -#else -# define png_isaligned(ptr, type) 0 -#endif - -/* End of memory model/platform independent support */ -/* End of 1.5.0beta36 move from pngconf.h */ - -/* CONSTANTS and UTILITY MACROS - * These are used internally by libpng and not exposed in the API - */ - -/* Various modes of operation. Note that after an init, mode is set to - * zero automatically when the structure is created. Three of these - * are defined in png.h because they need to be visible to applications - * that call png_set_unknown_chunk(). - */ -/* #define PNG_HAVE_IHDR 0x01U (defined in png.h) */ -/* #define PNG_HAVE_PLTE 0x02U (defined in png.h) */ -#define PNG_HAVE_IDAT 0x04U -/* #define PNG_AFTER_IDAT 0x08U (defined in png.h) */ -#define PNG_HAVE_IEND 0x10U - /* 0x20U (unused) */ - /* 0x40U (unused) */ - /* 0x80U (unused) */ -#define PNG_HAVE_CHUNK_HEADER 0x100U -#define PNG_WROTE_tIME 0x200U -#define PNG_WROTE_INFO_BEFORE_PLTE 0x400U -#define PNG_BACKGROUND_IS_GRAY 0x800U -#define PNG_HAVE_PNG_SIGNATURE 0x1000U -#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */ - /* 0x4000U (unused) */ -#define PNG_IS_READ_STRUCT 0x8000U /* Else is a write struct */ - -/* Flags for the transformations the PNG library does on the image data */ -#define PNG_BGR 0x0001U -#define PNG_INTERLACE 0x0002U -#define PNG_PACK 0x0004U -#define PNG_SHIFT 0x0008U -#define PNG_SWAP_BYTES 0x0010U -#define PNG_INVERT_MONO 0x0020U -#define PNG_QUANTIZE 0x0040U -#define PNG_COMPOSE 0x0080U /* Was PNG_BACKGROUND */ -#define PNG_BACKGROUND_EXPAND 0x0100U -#define PNG_EXPAND_16 0x0200U /* Added to libpng 1.5.2 */ -#define PNG_16_TO_8 0x0400U /* Becomes 'chop' in 1.5.4 */ -#define PNG_RGBA 0x0800U -#define PNG_EXPAND 0x1000U -#define PNG_GAMMA 0x2000U -#define PNG_GRAY_TO_RGB 0x4000U -#define PNG_FILLER 0x8000U -#define PNG_PACKSWAP 0x10000U -#define PNG_SWAP_ALPHA 0x20000U -#define PNG_STRIP_ALPHA 0x40000U -#define PNG_INVERT_ALPHA 0x80000U -#define PNG_USER_TRANSFORM 0x100000U -#define PNG_RGB_TO_GRAY_ERR 0x200000U -#define PNG_RGB_TO_GRAY_WARN 0x400000U -#define PNG_RGB_TO_GRAY 0x600000U /* two bits, RGB_TO_GRAY_ERR|WARN */ -#define PNG_ENCODE_ALPHA 0x800000U /* Added to libpng-1.5.4 */ -#define PNG_ADD_ALPHA 0x1000000U /* Added to libpng-1.2.7 */ -#define PNG_EXPAND_tRNS 0x2000000U /* Added to libpng-1.2.9 */ -#define PNG_SCALE_16_TO_8 0x4000000U /* Added to libpng-1.5.4 */ - /* 0x8000000U unused */ - /* 0x10000000U unused */ - /* 0x20000000U unused */ - /* 0x40000000U unused */ -/* Flags for png_create_struct */ -#define PNG_STRUCT_PNG 0x0001U -#define PNG_STRUCT_INFO 0x0002U - -/* Flags for the png_ptr->flags rather than declaring a byte for each one */ -#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001U -#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002U /* Added to libpng-1.6.0 */ - /* 0x0004U unused */ -#define PNG_FLAG_ZSTREAM_ENDED 0x0008U /* Added to libpng-1.6.0 */ - /* 0x0010U unused */ - /* 0x0020U unused */ -#define PNG_FLAG_ROW_INIT 0x0040U -#define PNG_FLAG_FILLER_AFTER 0x0080U -#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100U -#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200U -#define PNG_FLAG_CRC_CRITICAL_USE 0x0400U -#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800U -#define PNG_FLAG_ASSUME_sRGB 0x1000U /* Added to libpng-1.5.4 */ -#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000U /* Added to libpng-1.5.4 */ -#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000U /* Added to libpng-1.5.4 */ -/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000U */ -/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000U */ -#define PNG_FLAG_LIBRARY_MISMATCH 0x20000U -#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000U -#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000U -#define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000U /* Added to libpng-1.4.0 */ -#define PNG_FLAG_APP_WARNINGS_WARN 0x200000U /* Added to libpng-1.6.0 */ -#define PNG_FLAG_APP_ERRORS_WARN 0x400000U /* Added to libpng-1.6.0 */ - /* 0x800000U unused */ - /* 0x1000000U unused */ - /* 0x2000000U unused */ - /* 0x4000000U unused */ - /* 0x8000000U unused */ - /* 0x10000000U unused */ - /* 0x20000000U unused */ - /* 0x40000000U unused */ - -#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ - PNG_FLAG_CRC_ANCILLARY_NOWARN) - -#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \ - PNG_FLAG_CRC_CRITICAL_IGNORE) - -#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ - PNG_FLAG_CRC_CRITICAL_MASK) - -/* Save typing and make code easier to understand */ - -#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ - abs((int)((c1).green) - (int)((c2).green)) + \ - abs((int)((c1).blue) - (int)((c2).blue))) - -/* Added to libpng-1.6.0: scale a 16-bit value in the range 0..65535 to 0..255 - * by dividing by 257 *with rounding*. This macro is exact for the given range. - * See the discourse in pngrtran.c png_do_scale_16_to_8. The values in the - * macro were established by experiment (modifying the added value). The macro - * has a second variant that takes a value already scaled by 255 and divides by - * 65535 - this has a maximum error of .502. Over the range 0..65535*65535 it - * only gives off-by-one errors and only for 0.5% (1 in 200) of the values. - */ -#define PNG_DIV65535(v24) (((v24) + 32895) >> 16) -#define PNG_DIV257(v16) PNG_DIV65535((png_uint_32)(v16) * 255) - -/* Added to libpng-1.2.6 JB */ -#define PNG_ROWBYTES(pixel_bits, width) \ - ((pixel_bits) >= 8 ? \ - ((size_t)(width) * (((size_t)(pixel_bits)) >> 3)) : \ - (( ((size_t)(width) * ((size_t)(pixel_bits))) + 7) >> 3) ) - -/* This returns the number of trailing bits in the last byte of a row, 0 if the - * last byte is completely full of pixels. It is, in principle, (pixel_bits x - * width) % 8, but that would overflow for large 'width'. The second macro is - * the same except that it returns the number of unused bits in the last byte; - * (8-TRAILBITS), but 0 when TRAILBITS is 0. - * - * NOTE: these macros are intended to be self-evidently correct and never - * overflow on the assumption that pixel_bits is in the range 0..255. The - * arguments are evaluated only once and they can be signed (e.g. as a result of - * the integral promotions). The result of the expression always has type - * (png_uint_32), however the compiler always knows it is in the range 0..7. - */ -#define PNG_TRAILBITS(pixel_bits, width) \ - (((pixel_bits) * ((width) % (png_uint_32)8)) % 8) - -#define PNG_PADBITS(pixel_bits, width) \ - ((8 - PNG_TRAILBITS(pixel_bits, width)) % 8) - -/* PNG_OUT_OF_RANGE returns true if value is outside the range - * ideal-delta..ideal+delta. Each argument is evaluated twice. - * "ideal" and "delta" should be constants, normally simple - * integers, "value" a variable. Added to libpng-1.2.6 JB - */ -#define PNG_OUT_OF_RANGE(value, ideal, delta) \ - ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) - -/* Conversions between fixed and floating point, only defined if - * required (to make sure the code doesn't accidentally use float - * when it is supposedly disabled.) - */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -/* The floating point conversion can't overflow, though it can and - * does lose accuracy relative to the original fixed point value. - * In practice this doesn't matter because png_fixed_point only - * stores numbers with very low precision. The png_ptr and s - * arguments are unused by default but are there in case error - * checking becomes a requirement. - */ -#define png_float(png_ptr, fixed, s) (.00001 * (fixed)) - -/* The fixed point conversion performs range checking and evaluates - * its argument multiple times, so must be used with care. The - * range checking uses the PNG specification values for a signed - * 32-bit fixed point value except that the values are deliberately - * rounded-to-zero to an integral value - 21474 (21474.83 is roughly - * (2^31-1) * 100000). 's' is a string that describes the value being - * converted. - * - * NOTE: this macro will raise a png_error if the range check fails, - * therefore it is normally only appropriate to use this on values - * that come from API calls or other sources where an out of range - * error indicates a programming error, not a data error! - * - * NOTE: by default this is off - the macro is not used - because the - * function call saves a lot of code. - */ -#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED -#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\ - ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0)) -#endif -/* else the corresponding function is defined below, inside the scope of the - * cplusplus test. - */ -#endif - -/* Constants for known chunk types. If you need to add a chunk, define the name - * here. For historical reasons these constants have the form png_; i.e. - * the prefix is lower case. Please use decimal values as the parameters to - * match the ISO PNG specification and to avoid relying on the C locale - * interpretation of character values. - * - * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values - * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string - * to be generated if required. - * - * PNG_32b correctly produces a value shifted by up to 24 bits, even on - * architectures where (int) is only 16 bits. - */ -#define PNG_32b(b,s) ((png_uint_32)(b) << (s)) -#define PNG_U32(b1,b2,b3,b4) \ - (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0)) - -/* Constants for known chunk types. - * - * MAINTAINERS: If you need to add a chunk, define the name here. - * For historical reasons these constants have the form png_; i.e. - * the prefix is lower case. Please use decimal values as the parameters to - * match the ISO PNG specification and to avoid relying on the C locale - * interpretation of character values. Please keep the list sorted. - * - * Notice that PNG_U32 is used to define a 32-bit value for the 4 byte chunk - * type. In fact the specification does not express chunk types this way, - * however using a 32-bit value means that the chunk type can be read from the - * stream using exactly the same code as used for a 32-bit unsigned value and - * can be examined far more efficiently (using one arithmetic compare). - * - * Prior to 1.5.6 the chunk type constants were expressed as C strings. The - * libpng API still uses strings for 'unknown' chunks and a macro, - * PNG_STRING_FROM_CHUNK, allows a string to be generated if required. Notice - * that for portable code numeric values must still be used; the string "IHDR" - * is not portable and neither is PNG_U32('I', 'H', 'D', 'R'). - * - * In 1.7.0 the definitions will be made public in png.h to avoid having to - * duplicate the same definitions in application code. - */ -#define png_IDAT PNG_U32( 73, 68, 65, 84) -#define png_IEND PNG_U32( 73, 69, 78, 68) -#define png_IHDR PNG_U32( 73, 72, 68, 82) -#define png_PLTE PNG_U32( 80, 76, 84, 69) -#define png_bKGD PNG_U32( 98, 75, 71, 68) -#define png_cHRM PNG_U32( 99, 72, 82, 77) -#define png_eXIf PNG_U32(101, 88, 73, 102) /* registered July 2017 */ -#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */ -#define png_gAMA PNG_U32(103, 65, 77, 65) -#define png_gIFg PNG_U32(103, 73, 70, 103) -#define png_gIFt PNG_U32(103, 73, 70, 116) /* deprecated */ -#define png_gIFx PNG_U32(103, 73, 70, 120) -#define png_hIST PNG_U32(104, 73, 83, 84) -#define png_iCCP PNG_U32(105, 67, 67, 80) -#define png_iTXt PNG_U32(105, 84, 88, 116) -#define png_oFFs PNG_U32(111, 70, 70, 115) -#define png_pCAL PNG_U32(112, 67, 65, 76) -#define png_pHYs PNG_U32(112, 72, 89, 115) -#define png_sBIT PNG_U32(115, 66, 73, 84) -#define png_sCAL PNG_U32(115, 67, 65, 76) -#define png_sPLT PNG_U32(115, 80, 76, 84) -#define png_sRGB PNG_U32(115, 82, 71, 66) -#define png_sTER PNG_U32(115, 84, 69, 82) -#define png_tEXt PNG_U32(116, 69, 88, 116) -#define png_tIME PNG_U32(116, 73, 77, 69) -#define png_tRNS PNG_U32(116, 82, 78, 83) -#define png_zTXt PNG_U32(122, 84, 88, 116) - -/* The following will work on (signed char*) strings, whereas the get_uint_32 - * macro will fail on top-bit-set values because of the sign extension. - */ -#define PNG_CHUNK_FROM_STRING(s)\ - PNG_U32(0xff & (s)[0], 0xff & (s)[1], 0xff & (s)[2], 0xff & (s)[3]) - -/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is - * signed and the argument is a (char[]) This macro will fail miserably on - * systems where (char) is more than 8 bits. - */ -#define PNG_STRING_FROM_CHUNK(s,c)\ - (void)(((char*)(s))[0]=(char)(((c)>>24) & 0xff), \ - ((char*)(s))[1]=(char)(((c)>>16) & 0xff),\ - ((char*)(s))[2]=(char)(((c)>>8) & 0xff), \ - ((char*)(s))[3]=(char)((c & 0xff))) - -/* Do the same but terminate with a null character. */ -#define PNG_CSTRING_FROM_CHUNK(s,c)\ - (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0) - -/* Test on flag values as defined in the spec (section 5.4): */ -#define PNG_CHUNK_ANCILLARY(c) (1 & ((c) >> 29)) -#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLARY(c)) -#define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21)) -#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13)) -#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5)) - -/* Gamma values (new at libpng-1.5.4): */ -#define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */ -#define PNG_GAMMA_MAC_INVERSE 65909 -#define PNG_GAMMA_sRGB_INVERSE 45455 - -/* Almost everything below is C specific; the #defines above can be used in - * non-C code (so long as it is C-preprocessed) the rest of this stuff cannot. - */ -#ifndef PNG_VERSION_INFO_ONLY - -#include "pngstruct.h" -#include "pnginfo.h" - -/* Validate the include paths - the include path used to generate pnglibconf.h - * must match that used in the build, or we must be using pnglibconf.h.prebuilt: - */ -#if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM -# error ZLIB_VERNUM != PNG_ZLIB_VERNUM \ - "-I (include path) error: see the notes in pngpriv.h" - /* This means that when pnglibconf.h was built the copy of zlib.h that it - * used is not the same as the one being used here. Because the build of - * libpng makes decisions to use inflateInit2 and inflateReset2 based on the - * zlib version number and because this affects handling of certain broken - * PNG files the -I directives must match. - * - * The most likely explanation is that you passed a -I in CFLAGS. This will - * not work; all the preprocessor directives and in particular all the -I - * directives must be in CPPFLAGS. - */ -#endif - -/* This is used for 16-bit gamma tables -- only the top level pointers are - * const; this could be changed: - */ -typedef const png_uint_16p * png_const_uint_16pp; - -/* Added to libpng-1.5.7: sRGB conversion tables */ -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_table, [256]); - /* Convert from an sRGB encoded value 0..255 to a 16-bit linear value, - * 0..65535. This table gives the closest 16-bit answers (no errors). - */ -#endif - -PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_base, [512]); -PNG_INTERNAL_DATA(const png_byte, png_sRGB_delta, [512]); - -#define PNG_sRGB_FROM_LINEAR(linear) \ - ((png_byte)(0xff & ((png_sRGB_base[(linear)>>15] \ - + ((((linear) & 0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8))) - /* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB - * encoded value with maximum error 0.646365. Note that the input is not a - * 16-bit value; it has been multiplied by 255! */ -#endif /* SIMPLIFIED_READ/WRITE */ - - -/* Inhibit C++ name-mangling for libpng functions but not for system calls. */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Internal functions; these are not exported from a DLL however because they - * are used within several of the C source files they have to be C extern. - * - * All of these functions must be declared with PNG_INTERNAL_FUNCTION. - */ - -/* Zlib support */ -#define PNG_UNEXPECTED_ZLIB_RETURN (-7) -PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret), - PNG_EMPTY); - /* Used by the zlib handling functions to ensure that z_stream::msg is always - * set before they return. - */ - -#ifdef PNG_WRITE_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr, - png_compression_bufferp *list),PNG_EMPTY); - /* Free the buffer list used by the compressed write code. */ -#endif - -#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ - !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \ - (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \ - defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \ - (defined(PNG_sCAL_SUPPORTED) && \ - defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)) -PNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr, - double fp, png_const_charp text),PNG_EMPTY); -#endif - -/* Check the user version string for compatibility, returns false if the version - * numbers aren't compatible. - */ -PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr, - png_const_charp user_png_ver),PNG_EMPTY); - -/* Internal base allocator - no messages, NULL on failure to allocate. This - * does, however, call the application provided allocator and that could call - * png_error (although that would be a bug in the application implementation.) - */ -PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_base,(png_const_structrp png_ptr, - png_alloc_size_t size),PNG_ALLOCATED); - -#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\ - defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) -/* Internal array allocator, outputs no error or warning messages on failure, - * just returns NULL. - */ -PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_array,(png_const_structrp png_ptr, - int nelements, size_t element_size),PNG_ALLOCATED); - -/* The same but an existing array is extended by add_elements. This function - * also memsets the new elements to 0 and copies the old elements. The old - * array is not freed or altered. - */ -PNG_INTERNAL_FUNCTION(png_voidp,png_realloc_array,(png_const_structrp png_ptr, - png_const_voidp array, int old_elements, int add_elements, - size_t element_size),PNG_ALLOCATED); -#endif /* text, sPLT or unknown chunks */ - -/* Magic to create a struct when there is no struct to call the user supplied - * memory allocators. Because error handling has not been set up the memory - * handlers can't safely call png_error, but this is an obscure and undocumented - * restriction so libpng has to assume that the 'free' handler, at least, might - * call png_error. - */ -PNG_INTERNAL_FUNCTION(png_structp,png_create_png_struct, - (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, - png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn, - png_free_ptr free_fn),PNG_ALLOCATED); - -/* Free memory from internal libpng struct */ -PNG_INTERNAL_FUNCTION(void,png_destroy_png_struct,(png_structrp png_ptr), - PNG_EMPTY); - -/* Free an allocated jmp_buf (always succeeds) */ -PNG_INTERNAL_FUNCTION(void,png_free_jmpbuf,(png_structrp png_ptr),PNG_EMPTY); - -/* Function to allocate memory for zlib. PNGAPI is disallowed. */ -PNG_INTERNAL_FUNCTION(voidpf,png_zalloc,(voidpf png_ptr, uInt items, uInt size), - PNG_ALLOCATED); - -/* Function to free memory for zlib. PNGAPI is disallowed. */ -PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY); - -/* Next four functions are used internally as callbacks. PNGCBAPI is required - * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3, changed to - * PNGCBAPI at 1.5.0 - */ - -PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr, - png_bytep data, size_t length),PNG_EMPTY); - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr, - png_bytep buffer, size_t length),PNG_EMPTY); -#endif - -PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr, - png_bytep data, size_t length),PNG_EMPTY); - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -# ifdef PNG_STDIO_SUPPORTED -PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_flush,(png_structp png_ptr), - PNG_EMPTY); -# endif -#endif - -/* Reset the CRC variable */ -PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY); - -/* Write the "data" buffer to whatever output you are using */ -PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr, - png_const_bytep data, size_t length),PNG_EMPTY); - -/* Read and check the PNG file signature */ -PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); - -/* Read the chunk header (length + type name) */ -PNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr), - PNG_EMPTY); - -/* Read data from whatever input you are using into the "data" buffer */ -PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data, - size_t length),PNG_EMPTY); - -/* Read bytes into buf, and update png_ptr->crc */ -PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf, - png_uint_32 length),PNG_EMPTY); - -/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ -PNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr, - png_uint_32 skip),PNG_EMPTY); - -/* Read the CRC from the file and compare it to the libpng calculated CRC */ -PNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY); - -/* Calculate the CRC over a section of data. Note that we are only - * passing a maximum of 64K on systems that have this as a memory limit, - * since this is the maximum buffer size we can specify. - */ -PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr, - png_const_bytep ptr, size_t length),PNG_EMPTY); - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY); -#endif - -/* Write various chunks */ - -/* Write the IHDR chunk, and update the png_struct with the necessary - * information. - */ -PNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp png_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, - int compression_method, int filter_method, int interlace_method),PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr, - png_const_colorp palette, png_uint_32 num_pal),PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_compress_IDAT,(png_structrp png_ptr, - png_const_bytep row_data, png_alloc_size_t row_data_length, int flush), - PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY); - -#ifdef PNG_WRITE_gAMA_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_gAMA_fixed,(png_structrp png_ptr, - png_fixed_point file_gamma),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_sBIT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr, - png_const_color_8p sbit, int color_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_cHRM_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr, - const png_xy *xy), PNG_EMPTY); - /* The xy value must have been previously validated */ -#endif - -#ifdef PNG_WRITE_sRGB_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr, - int intent),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_eXIf_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_eXIf,(png_structrp png_ptr, - png_bytep exif, int num_exif),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_iCCP_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr, - png_const_charp name, png_const_bytep profile), PNG_EMPTY); - /* The profile must have been previously validated for correctness, the - * length comes from the first four bytes. Only the base, deflate, - * compression is supported. - */ -#endif - -#ifdef PNG_WRITE_sPLT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr, - png_const_sPLT_tp palette),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_tRNS_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_tRNS,(png_structrp png_ptr, - png_const_bytep trans, png_const_color_16p values, int number, - int color_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_bKGD_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_bKGD,(png_structrp png_ptr, - png_const_color_16p values, int color_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_hIST_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr, - png_const_uint_16p hist, int num_hist),PNG_EMPTY); -#endif - -/* Chunks that have keywords */ -#ifdef PNG_WRITE_tEXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr, - png_const_charp key, png_const_charp text, size_t text_len),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_zTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_zTXt,(png_structrp png_ptr, png_const_charp - key, png_const_charp text, int compression),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_iTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_iTXt,(png_structrp png_ptr, - int compression, png_const_charp key, png_const_charp lang, - png_const_charp lang_key, png_const_charp text),PNG_EMPTY); -#endif - -#ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */ -PNG_INTERNAL_FUNCTION(int,png_set_text_2,(png_const_structrp png_ptr, - png_inforp info_ptr, png_const_textp text_ptr, int num_text),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_oFFs_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_oFFs,(png_structrp png_ptr, - png_int_32 x_offset, png_int_32 y_offset, int unit_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_pCAL_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_pCAL,(png_structrp png_ptr, - png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, - png_const_charp units, png_charpp params),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_pHYs_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_pHYs,(png_structrp png_ptr, - png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, - int unit_type),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_tIME_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_tIME,(png_structrp png_ptr, - png_const_timep mod_time),PNG_EMPTY); -#endif - -#ifdef PNG_WRITE_sCAL_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_sCAL_s,(png_structrp png_ptr, - int unit, png_const_charp width, png_const_charp height),PNG_EMPTY); -#endif - -/* Called when finished processing a row of data */ -PNG_INTERNAL_FUNCTION(void,png_write_finish_row,(png_structrp png_ptr), - PNG_EMPTY); - -/* Internal use only. Called before first row of data */ -PNG_INTERNAL_FUNCTION(void,png_write_start_row,(png_structrp png_ptr), - PNG_EMPTY); - -/* Combine a row of data, dealing with alpha, etc. if requested. 'row' is an - * array of png_ptr->width pixels. If the image is not interlaced or this - * is the final pass this just does a memcpy, otherwise the "display" flag - * is used to determine whether to copy pixels that are not in the current pass. - * - * Because 'png_do_read_interlace' (below) replicates pixels this allows this - * function to achieve the documented 'blocky' appearance during interlaced read - * if display is 1 and the 'sparkle' appearance, where existing pixels in 'row' - * are not changed if they are not in the current pass, when display is 0. - * - * 'display' must be 0 or 1, otherwise the memcpy will be done regardless. - * - * The API always reads from the png_struct row buffer and always assumes that - * it is full width (png_do_read_interlace has already been called.) - * - * This function is only ever used to write to row buffers provided by the - * caller of the relevant libpng API and the row must have already been - * transformed by the read transformations. - * - * The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed - * bitmasks for use within the code, otherwise runtime generated masks are used. - * The default is compile time masks. - */ -#ifndef PNG_USE_COMPILE_TIME_MASKS -# define PNG_USE_COMPILE_TIME_MASKS 1 -#endif -PNG_INTERNAL_FUNCTION(void,png_combine_row,(png_const_structrp png_ptr, - png_bytep row, int display),PNG_EMPTY); - -#ifdef PNG_READ_INTERLACING_SUPPORTED -/* Expand an interlaced row: the 'row_info' describes the pass data that has - * been read in and must correspond to the pixels in 'row', the pixels are - * expanded (moved apart) in 'row' to match the final layout, when doing this - * the pixels are *replicated* to the intervening space. This is essential for - * the correct operation of png_combine_row, above. - */ -PNG_INTERNAL_FUNCTION(void,png_do_read_interlace,(png_row_infop row_info, - png_bytep row, int pass, png_uint_32 transformations),PNG_EMPTY); -#endif - -/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED -/* Grab pixels out of a row for an interlaced pass */ -PNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info, - png_bytep row, int pass),PNG_EMPTY); -#endif - -/* Unfilter a row: check the filter value before calling this, there is no point - * calling it for PNG_FILTER_VALUE_NONE. - */ -PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop - row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY); - -#if PNG_ARM_NEON_OPT > 0 -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info, - png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_neon,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_neon,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -#endif - -#if PNG_MIPS_MSA_OPT > 0 -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info, - png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_msa,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_msa,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_msa,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_msa,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -#endif - -#if PNG_POWERPC_VSX_OPT > 0 -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info, - png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_vsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_vsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_vsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_vsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_vsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_vsx,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -#endif - -#if PNG_INTEL_SSE_IMPLEMENTATION > 0 -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_sse2,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_sse2,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_sse2,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_sse2,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_sse2,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop - row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); -#endif - -/* Choose the best filter to use and filter the row data */ -PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr, - png_row_infop row_info),PNG_EMPTY); - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr, - png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY); - /* Read 'avail_out' bytes of data from the IDAT stream. If the output buffer - * is NULL the function checks, instead, for the end of the stream. In this - * case a benign error will be issued if the stream end is not found or if - * extra data has to be consumed. - */ -PNG_INTERNAL_FUNCTION(void,png_read_finish_IDAT,(png_structrp png_ptr), - PNG_EMPTY); - /* This cleans up when the IDAT LZ stream does not end when the last image - * byte is read; there is still some pending input. - */ - -PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr), - PNG_EMPTY); - /* Finish a row while reading, dealing with interlacing passes, etc. */ -#endif /* SEQUENTIAL_READ */ - -/* Initialize the row buffers, etc. */ -PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY); - -#if ZLIB_VERNUM >= 0x1240 -PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush), - PNG_EMPTY); -# define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush) -#else /* Zlib < 1.2.4 */ -# define PNG_INFLATE(pp, flush) inflate(&(pp)->zstream, flush) -#endif /* Zlib < 1.2.4 */ - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -/* Optional call to update the users info structure */ -PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -#endif - -/* Shared transform functions, defined in pngtran.c */ -#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ - defined(PNG_READ_STRIP_ALPHA_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_strip_channel,(png_row_infop row_info, - png_bytep row, int at_start),PNG_EMPTY); -#endif - -#ifdef PNG_16BIT_SUPPORTED -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_swap,(png_row_infop row_info, - png_bytep row),PNG_EMPTY); -#endif -#endif - -#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ - defined(PNG_WRITE_PACKSWAP_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_packswap,(png_row_infop row_info, - png_bytep row),PNG_EMPTY); -#endif - -#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_invert,(png_row_infop row_info, - png_bytep row),PNG_EMPTY); -#endif - -#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info, - png_bytep row),PNG_EMPTY); -#endif - -/* The following decodes the appropriate chunks, and does error correction, - * then calls the appropriate callback for the chunk if it is valid. - */ - -/* Decode the IHDR chunk */ -PNG_INTERNAL_FUNCTION(void,png_handle_IHDR,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_handle_PLTE,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_handle_IEND,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); - -#ifdef PNG_READ_bKGD_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_bKGD,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_eXIf_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_eXIf,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_gAMA_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_hIST_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_hIST,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_iCCP_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_iCCP,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif /* READ_iCCP */ - -#ifdef PNG_READ_iTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_iTXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_oFFs,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_pCAL,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_pHYs,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_sBIT,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_sCAL,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_sPLT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_sPLT,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif /* READ_sPLT */ - -#ifdef PNG_READ_sRGB_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_sRGB,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_tEXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_tIME_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_tIME,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_tRNS_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_tRNS,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -#endif - -PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr, - png_uint_32 chunk_name),PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr, - png_uint_32 chunk_length),PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY); - /* This is the function that gets called for unknown chunks. The 'keep' - * argument is either non-zero for a known chunk that has been set to be - * handled as unknown or zero for an unknown chunk. By default the function - * just skips the chunk or errors out if it is critical. - */ - -#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\ - defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) -PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling, - (png_const_structrp png_ptr, png_uint_32 chunk_name),PNG_EMPTY); - /* Exactly as the API png_handle_as_unknown() except that the argument is a - * 32-bit chunk name, not a string. - */ -#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */ - -/* Handle the transformations for reading and writing */ -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_do_read_transformations,(png_structrp png_ptr, - png_row_infop row_info),PNG_EMPTY); -#endif -#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_do_write_transformations,(png_structrp png_ptr, - png_row_infop row_info),PNG_EMPTY); -#endif - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_init_read_transformations,(png_structrp png_ptr), - PNG_EMPTY); -#endif - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_push_read_chunk,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_sig,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr), - PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr, - png_bytep buffer, size_t buffer_length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr, - png_bytep buffer, size_t buffer_length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr), - PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr, - png_bytep row),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr), - PNG_EMPTY); -# ifdef PNG_READ_tEXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_push_handle_tEXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_tEXt,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -# endif -# ifdef PNG_READ_zTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_push_handle_zTXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_zTXt,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -# endif -# ifdef PNG_READ_iTXt_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_push_handle_iTXt,(png_structrp png_ptr, - png_inforp info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_push_read_iTXt,(png_structrp png_ptr, - png_inforp info_ptr),PNG_EMPTY); -# endif - -#endif /* PROGRESSIVE_READ */ - -/* Added at libpng version 1.6.0 */ -#ifdef PNG_GAMMA_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_fixed_point gAMA), PNG_EMPTY); - /* Set the colorspace gamma with a value provided by the application or by - * the gAMA chunk on read. The value will override anything set by an ICC - * profile. - */ - -PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr, - png_inforp info_ptr), PNG_EMPTY); - /* Synchronize the info 'valid' flags with the colorspace */ - -PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr, - png_inforp info_ptr), PNG_EMPTY); - /* Copy the png_struct colorspace to the info_struct and call the above to - * synchronize the flags. Checks for NULL info_ptr and does nothing. - */ -#endif - -/* Added at libpng version 1.4.0 */ -#ifdef PNG_COLORSPACE_SUPPORTED -/* These internal functions are for maintaining the colorspace structure within - * a png_info or png_struct (or, indeed, both). - */ -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_chromaticities, - (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_xy *xy, - int preferred), PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_endpoints, - (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_XYZ *XYZ, - int preferred), PNG_EMPTY); - -#ifdef PNG_sRGB_SUPPORTED -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_sRGB,(png_const_structrp png_ptr, - png_colorspacerp colorspace, int intent), PNG_EMPTY); - /* This does set the colorspace gAMA and cHRM values too, but doesn't set the - * flags to write them, if it returns false there was a problem and an error - * message has already been output (but the colorspace may still need to be - * synced to record the invalid flag). - */ -#endif /* sRGB */ - -#ifdef PNG_iCCP_SUPPORTED -PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length, png_const_bytep profile, int color_type), - PNG_EMPTY); - /* The 'name' is used for information only */ - -/* Routines for checking parts of an ICC profile. */ -#ifdef PNG_READ_iCCP_SUPPORTED -PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length), PNG_EMPTY); -#endif /* READ_iCCP */ -PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length, - png_const_bytep profile /* first 132 bytes only */, int color_type), - PNG_EMPTY); -PNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr, - png_colorspacerp colorspace, png_const_charp name, - png_uint_32 profile_length, - png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY); -#ifdef PNG_sRGB_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_icc_set_sRGB,( - png_const_structrp png_ptr, png_colorspacerp colorspace, - png_const_bytep profile, uLong adler), PNG_EMPTY); - /* 'adler' is the Adler32 checksum of the uncompressed profile data. It may - * be zero to indicate that it is not available. It is used, if provided, - * as a fast check on the profile when checking to see if it is sRGB. - */ -#endif -#endif /* iCCP */ - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_colorspace_set_rgb_coefficients, - (png_structrp png_ptr), PNG_EMPTY); - /* Set the rgb_to_gray coefficients from the colorspace Y values */ -#endif /* READ_RGB_TO_GRAY */ -#endif /* COLORSPACE */ - -/* Added at libpng version 1.4.0 */ -PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type),PNG_EMPTY); - -/* Added at libpng version 1.5.10 */ -#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ - defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_do_check_palette_indexes, - (png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY); -#endif - -#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) -PNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp png_ptr, - png_const_charp name),PNG_NORETURN); -#endif - -/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite - * the end. Always leaves the buffer nul terminated. Never errors out (and - * there is no error code.) - */ -PNG_INTERNAL_FUNCTION(size_t,png_safecat,(png_charp buffer, size_t bufsize, - size_t pos, png_const_charp string),PNG_EMPTY); - -/* Various internal functions to handle formatted warning messages, currently - * only implemented for warnings. - */ -#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED) -/* Utility to dump an unsigned value into a buffer, given a start pointer and - * and end pointer (which should point just *beyond* the end of the buffer!) - * Returns the pointer to the start of the formatted string. This utility only - * does unsigned values. - */ -PNG_INTERNAL_FUNCTION(png_charp,png_format_number,(png_const_charp start, - png_charp end, int format, png_alloc_size_t number),PNG_EMPTY); - -/* Convenience macro that takes an array: */ -#define PNG_FORMAT_NUMBER(buffer,format,number) \ - png_format_number(buffer, buffer + (sizeof buffer), format, number) - -/* Suggested size for a number buffer (enough for 64 bits and a sign!) */ -#define PNG_NUMBER_BUFFER_SIZE 24 - -/* These are the integer formats currently supported, the name is formed from - * the standard printf(3) format string. - */ -#define PNG_NUMBER_FORMAT_u 1 /* chose unsigned API! */ -#define PNG_NUMBER_FORMAT_02u 2 -#define PNG_NUMBER_FORMAT_d 1 /* chose signed API! */ -#define PNG_NUMBER_FORMAT_02d 2 -#define PNG_NUMBER_FORMAT_x 3 -#define PNG_NUMBER_FORMAT_02x 4 -#define PNG_NUMBER_FORMAT_fixed 5 /* choose the signed API */ -#endif - -#ifdef PNG_WARNINGS_SUPPORTED -/* New defines and members adding in libpng-1.5.4 */ -# define PNG_WARNING_PARAMETER_SIZE 32 -# define PNG_WARNING_PARAMETER_COUNT 8 /* Maximum 9; see pngerror.c */ - -/* An l-value of this type has to be passed to the APIs below to cache the - * values of the parameters to a formatted warning message. - */ -typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][ - PNG_WARNING_PARAMETER_SIZE]; - -PNG_INTERNAL_FUNCTION(void,png_warning_parameter,(png_warning_parameters p, - int number, png_const_charp string),PNG_EMPTY); - /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters, - * including the trailing '\0'. - */ -PNG_INTERNAL_FUNCTION(void,png_warning_parameter_unsigned, - (png_warning_parameters p, int number, int format, png_alloc_size_t value), - PNG_EMPTY); - /* Use png_alloc_size_t because it is an unsigned type as big as any we - * need to output. Use the following for a signed value. - */ -PNG_INTERNAL_FUNCTION(void,png_warning_parameter_signed, - (png_warning_parameters p, int number, int format, png_int_32 value), - PNG_EMPTY); - -PNG_INTERNAL_FUNCTION(void,png_formatted_warning,(png_const_structrp png_ptr, - png_warning_parameters p, png_const_charp message),PNG_EMPTY); - /* 'message' follows the X/Open approach of using @1, @2 to insert - * parameters previously supplied using the above functions. Errors in - * specifying the parameters will simply result in garbage substitutions. - */ -#endif - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -/* Application errors (new in 1.6); use these functions (declared below) for - * errors in the parameters or order of API function calls on read. The - * 'warning' should be used for an error that can be handled completely; the - * 'error' for one which can be handled safely but which may lose application - * information or settings. - * - * By default these both result in a png_error call prior to release, while in a - * released version the 'warning' is just a warning. However if the application - * explicitly disables benign errors (explicitly permitting the code to lose - * information) they both turn into warnings. - * - * If benign errors aren't supported they end up as the corresponding base call - * (png_warning or png_error.) - */ -PNG_INTERNAL_FUNCTION(void,png_app_warning,(png_const_structrp png_ptr, - png_const_charp message),PNG_EMPTY); - /* The application provided invalid parameters to an API function or called - * an API function at the wrong time, libpng can completely recover. - */ - -PNG_INTERNAL_FUNCTION(void,png_app_error,(png_const_structrp png_ptr, - png_const_charp message),PNG_EMPTY); - /* As above but libpng will ignore the call, or attempt some other partial - * recovery from the error. - */ -#else -# define png_app_warning(pp,s) png_warning(pp,s) -# define png_app_error(pp,s) png_error(pp,s) -#endif - -PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr, - png_const_charp message, int error),PNG_EMPTY); - /* Report a recoverable issue in chunk data. On read this is used to report - * a problem found while reading a particular chunk and the - * png_chunk_benign_error or png_chunk_warning function is used as - * appropriate. On write this is used to report an error that comes from - * data set via an application call to a png_set_ API and png_app_error or - * png_app_warning is used as appropriate. - * - * The 'error' parameter must have one of the following values: - */ -#define PNG_CHUNK_WARNING 0 /* never an error */ -#define PNG_CHUNK_WRITE_ERROR 1 /* an error only on write */ -#define PNG_CHUNK_ERROR 2 /* always an error */ - -/* ASCII to FP interfaces, currently only implemented if sCAL - * support is required. - */ -#if defined(PNG_sCAL_SUPPORTED) -/* MAX_DIGITS is actually the maximum number of characters in an sCAL - * width or height, derived from the precision (number of significant - * digits - a build time settable option) and assumptions about the - * maximum ridiculous exponent. - */ -#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/) - -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr, - png_charp ascii, size_t size, double fp, unsigned int precision), - PNG_EMPTY); -#endif /* FLOATING_POINT */ - -#ifdef PNG_FIXED_POINT_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr, - png_charp ascii, size_t size, png_fixed_point fp),PNG_EMPTY); -#endif /* FIXED_POINT */ -#endif /* sCAL */ - -#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) -/* An internal API to validate the format of a floating point number. - * The result is the index of the next character. If the number is - * not valid it will be the index of a character in the supposed number. - * - * The format of a number is defined in the PNG extensions specification - * and this API is strictly conformant to that spec, not anyone elses! - * - * The format as a regular expression is: - * - * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)? - * - * or: - * - * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)? - * - * The complexity is that either integer or fraction must be present and the - * fraction is permitted to have no digits only if the integer is present. - * - * NOTE: The dangling E problem. - * There is a PNG valid floating point number in the following: - * - * PNG floating point numbers are not greedy. - * - * Working this out requires *TWO* character lookahead (because of the - * sign), the parser does not do this - it will fail at the 'r' - this - * doesn't matter for PNG sCAL chunk values, but it requires more care - * if the value were ever to be embedded in something more complex. Use - * ANSI-C strtod if you need the lookahead. - */ -/* State table for the parser. */ -#define PNG_FP_INTEGER 0 /* before or in integer */ -#define PNG_FP_FRACTION 1 /* before or in fraction */ -#define PNG_FP_EXPONENT 2 /* before or in exponent */ -#define PNG_FP_STATE 3 /* mask for the above */ -#define PNG_FP_SAW_SIGN 4 /* Saw +/- in current state */ -#define PNG_FP_SAW_DIGIT 8 /* Saw a digit in current state */ -#define PNG_FP_SAW_DOT 16 /* Saw a dot in current state */ -#define PNG_FP_SAW_E 32 /* Saw an E (or e) in current state */ -#define PNG_FP_SAW_ANY 60 /* Saw any of the above 4 */ - -/* These three values don't affect the parser. They are set but not used. - */ -#define PNG_FP_WAS_VALID 64 /* Preceding substring is a valid fp number */ -#define PNG_FP_NEGATIVE 128 /* A negative number, including "-0" */ -#define PNG_FP_NONZERO 256 /* A non-zero value */ -#define PNG_FP_STICKY 448 /* The above three flags */ - -/* This is available for the caller to store in 'state' if required. Do not - * call the parser after setting it (the parser sometimes clears it.) - */ -#define PNG_FP_INVALID 512 /* Available for callers as a distinct value */ - -/* Result codes for the parser (boolean - true meants ok, false means - * not ok yet.) - */ -#define PNG_FP_MAYBE 0 /* The number may be valid in the future */ -#define PNG_FP_OK 1 /* The number is valid */ - -/* Tests on the sticky non-zero and negative flags. To pass these checks - * the state must also indicate that the whole number is valid - this is - * achieved by testing PNG_FP_SAW_DIGIT (see the implementation for why this - * is equivalent to PNG_FP_OK above.) - */ -#define PNG_FP_NZ_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NEGATIVE | PNG_FP_NONZERO) - /* NZ_MASK: the string is valid and a non-zero negative value */ -#define PNG_FP_Z_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NONZERO) - /* Z MASK: the string is valid and a non-zero value. */ - /* PNG_FP_SAW_DIGIT: the string is valid. */ -#define PNG_FP_IS_ZERO(state) (((state) & PNG_FP_Z_MASK) == PNG_FP_SAW_DIGIT) -#define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK) -#define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK) - -/* The actual parser. This can be called repeatedly. It updates - * the index into the string and the state variable (which must - * be initialized to 0). It returns a result code, as above. There - * is no point calling the parser any more if it fails to advance to - * the end of the string - it is stuck on an invalid character (or - * terminated by '\0'). - * - * Note that the pointer will consume an E or even an E+ and then leave - * a 'maybe' state even though a preceding integer.fraction is valid. - * The PNG_FP_WAS_VALID flag indicates that a preceding substring was - * a valid number. It's possible to recover from this by calling - * the parser again (from the start, with state 0) but with a string - * that omits the last character (i.e. set the size to the index of - * the problem character.) This has not been tested within libpng. - */ -PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string, - size_t size, int *statep, png_size_tp whereami),PNG_EMPTY); - -/* This is the same but it checks a complete string and returns true - * only if it just contains a floating point number. As of 1.5.4 this - * function also returns the state at the end of parsing the number if - * it was valid (otherwise it returns 0.) This can be used for testing - * for negative or zero values using the sticky flag. - */ -PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string, - size_t size),PNG_EMPTY); -#endif /* pCAL || sCAL */ - -#if defined(PNG_GAMMA_SUPPORTED) ||\ - defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) -/* Added at libpng version 1.5.0 */ -/* This is a utility to provide a*times/div (rounded) and indicate - * if there is an overflow. The result is a boolean - false (0) - * for overflow, true (1) if no overflow, in which case *res - * holds the result. - */ -PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a, - png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY); -#endif - -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) -/* Same deal, but issue a warning on overflow and return 0. */ -PNG_INTERNAL_FUNCTION(png_fixed_point,png_muldiv_warn, - (png_const_structrp png_ptr, png_fixed_point a, png_int_32 multiplied_by, - png_int_32 divided_by),PNG_EMPTY); -#endif - -#ifdef PNG_GAMMA_SUPPORTED -/* Calculate a reciprocal - used for gamma values. This returns - * 0 if the argument is 0 in order to maintain an undefined value; - * there are no warnings. - */ -PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a), - PNG_EMPTY); - -#ifdef PNG_READ_GAMMA_SUPPORTED -/* The same but gives a reciprocal of the product of two fixed point - * values. Accuracy is suitable for gamma calculations but this is - * not exact - use png_muldiv for that. Only required at present on read. - */ -PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal2,(png_fixed_point a, - png_fixed_point b),PNG_EMPTY); -#endif - -/* Return true if the gamma value is significantly different from 1.0 */ -PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value), - PNG_EMPTY); -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED -/* Internal fixed point gamma correction. These APIs are called as - * required to convert single values - they don't need to be fast, - * they are not used when processing image pixel values. - * - * While the input is an 'unsigned' value it must actually be the - * correct bit value - 0..255 or 0..65535 as required. - */ -PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_correct,(png_structrp png_ptr, - unsigned int value, png_fixed_point gamma_value),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,(unsigned int value, - png_fixed_point gamma_value),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(unsigned int value, - png_fixed_point gamma_value),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr), - PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_build_gamma_table,(png_structrp png_ptr, - int bit_depth),PNG_EMPTY); -#endif - -/* SIMPLIFIED READ/WRITE SUPPORT */ -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ - defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) -/* The internal structure that png_image::opaque points to. */ -typedef struct png_control -{ - png_structp png_ptr; - png_infop info_ptr; - png_voidp error_buf; /* Always a jmp_buf at present. */ - - png_const_bytep memory; /* Memory buffer. */ - size_t size; /* Size of the memory buffer. */ - - unsigned int for_write :1; /* Otherwise it is a read structure */ - unsigned int owned_file :1; /* We own the file in io_ptr */ -} png_control; - -/* Return the pointer to the jmp_buf from a png_control: necessary because C - * does not reveal the type of the elements of jmp_buf. - */ -#ifdef __cplusplus -# define png_control_jmp_buf(pc) (((jmp_buf*)((pc)->error_buf))[0]) -#else -# define png_control_jmp_buf(pc) ((pc)->error_buf) -#endif - -/* Utility to safely execute a piece of libpng code catching and logging any - * errors that might occur. Returns true on success, false on failure (either - * of the function or as a result of a png_error.) - */ -PNG_INTERNAL_CALLBACK(void,png_safe_error,(png_structp png_ptr, - png_const_charp error_message),PNG_NORETURN); - -#ifdef PNG_WARNINGS_SUPPORTED -PNG_INTERNAL_CALLBACK(void,png_safe_warning,(png_structp png_ptr, - png_const_charp warning_message),PNG_EMPTY); -#else -# define png_safe_warning 0/*dummy argument*/ -#endif - -PNG_INTERNAL_FUNCTION(int,png_safe_execute,(png_imagep image, - int (*function)(png_voidp), png_voidp arg),PNG_EMPTY); - -/* Utility to log an error; this also cleans up the png_image; the function - * always returns 0 (false). - */ -PNG_INTERNAL_FUNCTION(int,png_image_error,(png_imagep image, - png_const_charp error_message),PNG_EMPTY); - -#ifndef PNG_SIMPLIFIED_READ_SUPPORTED -/* png_image_free is used by the write code but not exported */ -PNG_INTERNAL_FUNCTION(void, png_image_free, (png_imagep image), PNG_EMPTY); -#endif /* !SIMPLIFIED_READ */ - -#endif /* SIMPLIFIED READ/WRITE */ - -/* These are initialization functions for hardware specific PNG filter - * optimizations; list these here then select the appropriate one at compile - * time using the macro PNG_FILTER_OPTIMIZATIONS. If the macro is not defined - * the generic code is used. - */ -#ifdef PNG_FILTER_OPTIMIZATIONS -PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr, - unsigned int bpp), PNG_EMPTY); - /* Just declare the optimization that will be used */ -#else - /* List *all* the possible optimizations here - this branch is required if - * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in - * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing. - */ -# if PNG_ARM_NEON_OPT > 0 -PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon, - (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); -#endif - -#if PNG_MIPS_MSA_OPT > 0 -PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa, - (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); -#endif - -# if PNG_INTEL_SSE_IMPLEMENTATION > 0 -PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2, - (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); -# endif -#endif - -PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr, - png_const_charp key, png_bytep new_key), PNG_EMPTY); - -#if PNG_ARM_NEON_IMPLEMENTATION == 1 -PNG_INTERNAL_FUNCTION(void, - png_riffle_palette_neon, - (png_structrp), - PNG_EMPTY); -PNG_INTERNAL_FUNCTION(int, - png_do_expand_palette_rgba8_neon, - (png_structrp, - png_row_infop, - png_const_bytep, - const png_bytepp, - const png_bytepp), - PNG_EMPTY); -PNG_INTERNAL_FUNCTION(int, - png_do_expand_palette_rgb8_neon, - (png_structrp, - png_row_infop, - png_const_bytep, - const png_bytepp, - const png_bytepp), - PNG_EMPTY); -#endif - -/* Maintainer: Put new private prototypes here ^ */ - -#include "pngdebug.h" - -#ifdef __cplusplus -} -#endif - -#endif /* PNG_VERSION_INFO_ONLY */ -#endif /* PNGPRIV_H */ diff --git a/extern/libpng/pngread.c b/extern/libpng/pngread.c deleted file mode 100644 index 8fa7d9f16..000000000 --- a/extern/libpng/pngread.c +++ /dev/null @@ -1,4225 +0,0 @@ - -/* pngread.c - read a PNG file - * - * Copyright (c) 2018-2019 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file contains routines that an application calls directly to - * read a PNG file or stream. - */ - -#include "pngpriv.h" -#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) -# include -#endif - -#ifdef PNG_READ_SUPPORTED - -/* Create a PNG structure for reading, and allocate any memory needed. */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) -{ -#ifndef PNG_USER_MEM_SUPPORTED - png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, NULL, NULL, NULL); -#else - return png_create_read_struct_2(user_png_ver, error_ptr, error_fn, - warn_fn, NULL, NULL, NULL); -} - -/* Alternate create PNG structure for reading, and allocate any memory - * needed. - */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) -{ - png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); -#endif /* USER_MEM */ - - if (png_ptr != NULL) - { - png_ptr->mode = PNG_IS_READ_STRUCT; - - /* Added in libpng-1.6.0; this can be used to detect a read structure if - * required (it will be zero in a write structure.) - */ -# ifdef PNG_SEQUENTIAL_READ_SUPPORTED - png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE; -# endif - -# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED - png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; - - /* In stable builds only warn if an application error can be completely - * handled. - */ -# if PNG_RELEASE_BUILD - png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; -# endif -# endif - - /* TODO: delay this, it can be done in png_init_io (if the app doesn't - * do it itself) avoiding setting the default function if it is not - * required. - */ - png_set_read_fn(png_ptr, NULL, NULL); - } - - return png_ptr; -} - - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the information before the actual image data. This has been - * changed in v0.90 to allow reading a file that already has the magic - * bytes read from the stream. You can tell libpng how many bytes have - * been read from the beginning of the stream (up to the maximum of 8) - * via png_set_sig_bytes(), and we will only check the remaining bytes - * here. The application can then have access to the signature bytes we - * read if it is determined that this isn't a valid PNG file. - */ -void PNGAPI -png_read_info(png_structrp png_ptr, png_inforp info_ptr) -{ -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - int keep; -#endif - - png_debug(1, "in png_read_info"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* Read and check the PNG file signature. */ - png_read_sig(png_ptr, info_ptr); - - for (;;) - { - png_uint_32 length = png_read_chunk_header(png_ptr); - png_uint_32 chunk_name = png_ptr->chunk_name; - - /* IDAT logic needs to happen here to simplify getting the two flags - * right. - */ - if (chunk_name == png_IDAT) - { - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "Missing IHDR before IDAT"); - - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - (png_ptr->mode & PNG_HAVE_PLTE) == 0) - png_chunk_error(png_ptr, "Missing PLTE before IDAT"); - - else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) - png_chunk_benign_error(png_ptr, "Too many IDATs found"); - - png_ptr->mode |= PNG_HAVE_IDAT; - } - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; - png_ptr->mode |= PNG_AFTER_IDAT; - } - - /* This should be a binary subdivision search or a hash for - * matching the chunk name rather than a linear search. - */ - if (chunk_name == png_IHDR) - png_handle_IHDR(png_ptr, info_ptr, length); - - else if (chunk_name == png_IEND) - png_handle_IEND(png_ptr, info_ptr, length); - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) - { - png_handle_unknown(png_ptr, info_ptr, length, keep); - - if (chunk_name == png_PLTE) - png_ptr->mode |= PNG_HAVE_PLTE; - - else if (chunk_name == png_IDAT) - { - png_ptr->idat_size = 0; /* It has been consumed */ - break; - } - } -#endif - else if (chunk_name == png_PLTE) - png_handle_PLTE(png_ptr, info_ptr, length); - - else if (chunk_name == png_IDAT) - { - png_ptr->idat_size = length; - break; - } - -#ifdef PNG_READ_bKGD_SUPPORTED - else if (chunk_name == png_bKGD) - png_handle_bKGD(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED - else if (chunk_name == png_cHRM) - png_handle_cHRM(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_eXIf_SUPPORTED - else if (chunk_name == png_eXIf) - png_handle_eXIf(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_gAMA_SUPPORTED - else if (chunk_name == png_gAMA) - png_handle_gAMA(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_hIST_SUPPORTED - else if (chunk_name == png_hIST) - png_handle_hIST(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED - else if (chunk_name == png_oFFs) - png_handle_oFFs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED - else if (chunk_name == png_pCAL) - png_handle_pCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED - else if (chunk_name == png_sCAL) - png_handle_sCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED - else if (chunk_name == png_pHYs) - png_handle_pHYs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED - else if (chunk_name == png_sBIT) - png_handle_sBIT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sRGB_SUPPORTED - else if (chunk_name == png_sRGB) - png_handle_sRGB(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iCCP_SUPPORTED - else if (chunk_name == png_iCCP) - png_handle_iCCP(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sPLT_SUPPORTED - else if (chunk_name == png_sPLT) - png_handle_sPLT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED - else if (chunk_name == png_tEXt) - png_handle_tEXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tIME_SUPPORTED - else if (chunk_name == png_tIME) - png_handle_tIME(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tRNS_SUPPORTED - else if (chunk_name == png_tRNS) - png_handle_tRNS(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED - else if (chunk_name == png_zTXt) - png_handle_zTXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iTXt_SUPPORTED - else if (chunk_name == png_iTXt) - png_handle_iTXt(png_ptr, info_ptr, length); -#endif - - else - png_handle_unknown(png_ptr, info_ptr, length, - PNG_HANDLE_CHUNK_AS_DEFAULT); - } -} -#endif /* SEQUENTIAL_READ */ - -/* Optional call to update the users info_ptr structure */ -void PNGAPI -png_read_update_info(png_structrp png_ptr, png_inforp info_ptr) -{ - png_debug(1, "in png_read_update_info"); - - if (png_ptr != NULL) - { - if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) - { - png_read_start_row(png_ptr); - -# ifdef PNG_READ_TRANSFORMS_SUPPORTED - png_read_transform_info(png_ptr, info_ptr); -# else - PNG_UNUSED(info_ptr) -# endif - } - - /* New in 1.6.0 this avoids the bug of doing the initializations twice */ - else - png_app_error(png_ptr, - "png_read_update_info/png_start_read_image: duplicate call"); - } -} - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Initialize palette, background, etc, after transformations - * are set, but before any reading takes place. This allows - * the user to obtain a gamma-corrected palette, for example. - * If the user doesn't call this, we will do it ourselves. - */ -void PNGAPI -png_start_read_image(png_structrp png_ptr) -{ - png_debug(1, "in png_start_read_image"); - - if (png_ptr != NULL) - { - if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) - png_read_start_row(png_ptr); - - /* New in 1.6.0 this avoids the bug of doing the initializations twice */ - else - png_app_error(png_ptr, - "png_start_read_image/png_read_update_info: duplicate call"); - } -} -#endif /* SEQUENTIAL_READ */ - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -#ifdef PNG_MNG_FEATURES_SUPPORTED -/* Undoes intrapixel differencing, - * NOTE: this is apparently only supported in the 'sequential' reader. - */ -static void -png_do_read_intrapixel(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_read_intrapixel"); - - if ( - (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - int bytes_per_pixel; - png_uint_32 row_width = row_info->width; - - if (row_info->bit_depth == 8) - { - png_bytep rp; - png_uint_32 i; - - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 3; - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 4; - - else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); - *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); - } - } - else if (row_info->bit_depth == 16) - { - png_bytep rp; - png_uint_32 i; - - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 6; - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 8; - - else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1); - png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3); - png_uint_32 s2 = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5); - png_uint_32 red = (s0 + s1 + 65536) & 0xffff; - png_uint_32 blue = (s2 + s1 + 65536) & 0xffff; - *(rp ) = (png_byte)((red >> 8) & 0xff); - *(rp + 1) = (png_byte)(red & 0xff); - *(rp + 4) = (png_byte)((blue >> 8) & 0xff); - *(rp + 5) = (png_byte)(blue & 0xff); - } - } - } -} -#endif /* MNG_FEATURES */ - -void PNGAPI -png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) -{ - png_row_info row_info; - - if (png_ptr == NULL) - return; - - png_debug2(1, "in png_read_row (row %lu, pass %d)", - (unsigned long)png_ptr->row_number, png_ptr->pass); - - /* png_read_start_row sets the information (in particular iwidth) for this - * interlace pass. - */ - if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) - png_read_start_row(png_ptr); - - /* 1.5.6: row_info moved out of png_struct to a local here. */ - row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ - row_info.color_type = png_ptr->color_type; - row_info.bit_depth = png_ptr->bit_depth; - row_info.channels = png_ptr->channels; - row_info.pixel_depth = png_ptr->pixel_depth; - row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); - -#ifdef PNG_WARNINGS_SUPPORTED - if (png_ptr->row_number == 0 && png_ptr->pass == 0) - { - /* Check for transforms that have been set but were defined out */ -#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED) - if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) - png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) - if ((png_ptr->transformations & PNG_FILLER) != 0) - png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ - !defined(PNG_READ_PACKSWAP_SUPPORTED) - if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) - if ((png_ptr->transformations & PNG_PACK) != 0) - png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) - if ((png_ptr->transformations & PNG_SHIFT) != 0) - png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) - if ((png_ptr->transformations & PNG_BGR) != 0) - png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined"); -#endif - -#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) - if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) - png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined"); -#endif - } -#endif /* WARNINGS */ - -#ifdef PNG_READ_INTERLACING_SUPPORTED - /* If interlaced and we do not need a new row, combine row and return. - * Notice that the pixels we have from previous rows have been transformed - * already; we can only combine like with like (transformed or - * untransformed) and, because of the libpng API for interlaced images, this - * means we must transform before de-interlacing. - */ - if (png_ptr->interlaced != 0 && - (png_ptr->transformations & PNG_INTERLACE) != 0) - { - switch (png_ptr->pass) - { - case 0: - if (png_ptr->row_number & 0x07) - { - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - png_read_finish_row(png_ptr); - return; - } - break; - - case 1: - if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) - { - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - - case 2: - if ((png_ptr->row_number & 0x07) != 4) - { - if (dsp_row != NULL && (png_ptr->row_number & 4)) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - - case 3: - if ((png_ptr->row_number & 3) || png_ptr->width < 3) - { - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - - case 4: - if ((png_ptr->row_number & 3) != 2) - { - if (dsp_row != NULL && (png_ptr->row_number & 2)) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - - case 5: - if ((png_ptr->row_number & 1) || png_ptr->width < 2) - { - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - png_read_finish_row(png_ptr); - return; - } - break; - - default: - case 6: - if ((png_ptr->row_number & 1) == 0) - { - png_read_finish_row(png_ptr); - return; - } - break; - } - } -#endif - - if ((png_ptr->mode & PNG_HAVE_IDAT) == 0) - png_error(png_ptr, "Invalid attempt to read row data"); - - /* Fill the row with IDAT data: */ - png_ptr->row_buf[0]=255; /* to force error if no data was found */ - png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1); - - if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) - { - if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) - png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, - png_ptr->prev_row + 1, png_ptr->row_buf[0]); - else - png_error(png_ptr, "bad adaptive filter value"); - } - - /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before - * 1.5.6, while the buffer really is this big in current versions of libpng - * it may not be in the future, so this was changed just to copy the - * interlaced count: - */ - memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); - -#ifdef PNG_MNG_FEATURES_SUPPORTED - if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) - { - /* Intrapixel differencing */ - png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1); - } -#endif - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED - if (png_ptr->transformations) - png_do_read_transformations(png_ptr, &row_info); -#endif - - /* The transformed pixel depth should match the depth now in row_info. */ - if (png_ptr->transformed_pixel_depth == 0) - { - png_ptr->transformed_pixel_depth = row_info.pixel_depth; - if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) - png_error(png_ptr, "sequential row overflow"); - } - - else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) - png_error(png_ptr, "internal sequential row size calculation error"); - -#ifdef PNG_READ_INTERLACING_SUPPORTED - /* Expand interlaced rows to full size */ - if (png_ptr->interlaced != 0 && - (png_ptr->transformations & PNG_INTERLACE) != 0) - { - if (png_ptr->pass < 6) - png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, - png_ptr->transformations); - - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, 1/*display*/); - - if (row != NULL) - png_combine_row(png_ptr, row, 0/*row*/); - } - - else -#endif - { - if (row != NULL) - png_combine_row(png_ptr, row, -1/*ignored*/); - - if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, -1/*ignored*/); - } - png_read_finish_row(png_ptr); - - if (png_ptr->read_row_fn != NULL) - (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); - -} -#endif /* SEQUENTIAL_READ */ - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read one or more rows of image data. If the image is interlaced, - * and png_set_interlace_handling() has been called, the rows need to - * contain the contents of the rows from the previous pass. If the - * image has alpha or transparency, and png_handle_alpha()[*] has been - * called, the rows contents must be initialized to the contents of the - * screen. - * - * "row" holds the actual image, and pixels are placed in it - * as they arrive. If the image is displayed after each pass, it will - * appear to "sparkle" in. "display_row" can be used to display a - * "chunky" progressive image, with finer detail added as it becomes - * available. If you do not want this "chunky" display, you may pass - * NULL for display_row. If you do not want the sparkle display, and - * you have not called png_handle_alpha(), you may pass NULL for rows. - * If you have called png_handle_alpha(), and the image has either an - * alpha channel or a transparency chunk, you must provide a buffer for - * rows. In this case, you do not have to provide a display_row buffer - * also, but you may. If the image is not interlaced, or if you have - * not called png_set_interlace_handling(), the display_row buffer will - * be ignored, so pass NULL to it. - * - * [*] png_handle_alpha() does not exist yet, as of this version of libpng - */ - -void PNGAPI -png_read_rows(png_structrp png_ptr, png_bytepp row, - png_bytepp display_row, png_uint_32 num_rows) -{ - png_uint_32 i; - png_bytepp rp; - png_bytepp dp; - - png_debug(1, "in png_read_rows"); - - if (png_ptr == NULL) - return; - - rp = row; - dp = display_row; - if (rp != NULL && dp != NULL) - for (i = 0; i < num_rows; i++) - { - png_bytep rptr = *rp++; - png_bytep dptr = *dp++; - - png_read_row(png_ptr, rptr, dptr); - } - - else if (rp != NULL) - for (i = 0; i < num_rows; i++) - { - png_bytep rptr = *rp; - png_read_row(png_ptr, rptr, NULL); - rp++; - } - - else if (dp != NULL) - for (i = 0; i < num_rows; i++) - { - png_bytep dptr = *dp; - png_read_row(png_ptr, NULL, dptr); - dp++; - } -} -#endif /* SEQUENTIAL_READ */ - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the entire image. If the image has an alpha channel or a tRNS - * chunk, and you have called png_handle_alpha()[*], you will need to - * initialize the image to the current image that PNG will be overlaying. - * We set the num_rows again here, in case it was incorrectly set in - * png_read_start_row() by a call to png_read_update_info() or - * png_start_read_image() if png_set_interlace_handling() wasn't called - * prior to either of these functions like it should have been. You can - * only call this function once. If you desire to have an image for - * each pass of a interlaced image, use png_read_rows() instead. - * - * [*] png_handle_alpha() does not exist yet, as of this version of libpng - */ -void PNGAPI -png_read_image(png_structrp png_ptr, png_bytepp image) -{ - png_uint_32 i, image_height; - int pass, j; - png_bytepp rp; - - png_debug(1, "in png_read_image"); - - if (png_ptr == NULL) - return; - -#ifdef PNG_READ_INTERLACING_SUPPORTED - if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) - { - pass = png_set_interlace_handling(png_ptr); - /* And make sure transforms are initialized. */ - png_start_read_image(png_ptr); - } - else - { - if (png_ptr->interlaced != 0 && - (png_ptr->transformations & PNG_INTERLACE) == 0) - { - /* Caller called png_start_read_image or png_read_update_info without - * first turning on the PNG_INTERLACE transform. We can fix this here, - * but the caller should do it! - */ - png_warning(png_ptr, "Interlace handling should be turned on when " - "using png_read_image"); - /* Make sure this is set correctly */ - png_ptr->num_rows = png_ptr->height; - } - - /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in - * the above error case. - */ - pass = png_set_interlace_handling(png_ptr); - } -#else - if (png_ptr->interlaced) - png_error(png_ptr, - "Cannot read interlaced image -- interlace handler disabled"); - - pass = 1; -#endif - - image_height=png_ptr->height; - - for (j = 0; j < pass; j++) - { - rp = image; - for (i = 0; i < image_height; i++) - { - png_read_row(png_ptr, *rp, NULL); - rp++; - } - } -} -#endif /* SEQUENTIAL_READ */ - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -/* Read the end of the PNG file. Will not read past the end of the - * file, will verify the end is accurate, and will read any comments - * or time information at the end of the file, if info is not NULL. - */ -void PNGAPI -png_read_end(png_structrp png_ptr, png_inforp info_ptr) -{ -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - int keep; -#endif - - png_debug(1, "in png_read_end"); - - if (png_ptr == NULL) - return; - - /* If png_read_end is called in the middle of reading the rows there may - * still be pending IDAT data and an owned zstream. Deal with this here. - */ -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (png_chunk_unknown_handling(png_ptr, png_IDAT) == 0) -#endif - png_read_finish_IDAT(png_ptr); - -#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED - /* Report invalid palette index; added at libng-1.5.10 */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - png_ptr->num_palette_max > png_ptr->num_palette) - png_benign_error(png_ptr, "Read palette index exceeding num_palette"); -#endif - - do - { - png_uint_32 length = png_read_chunk_header(png_ptr); - png_uint_32 chunk_name = png_ptr->chunk_name; - - if (chunk_name != png_IDAT) - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; - - if (chunk_name == png_IEND) - png_handle_IEND(png_ptr, info_ptr, length); - - else if (chunk_name == png_IHDR) - png_handle_IHDR(png_ptr, info_ptr, length); - - else if (info_ptr == NULL) - png_crc_finish(png_ptr, length); - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) - { - if (chunk_name == png_IDAT) - { - if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) - || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) - png_benign_error(png_ptr, ".Too many IDATs found"); - } - png_handle_unknown(png_ptr, info_ptr, length, keep); - if (chunk_name == png_PLTE) - png_ptr->mode |= PNG_HAVE_PLTE; - } -#endif - - else if (chunk_name == png_IDAT) - { - /* Zero length IDATs are legal after the last IDAT has been - * read, but not after other chunks have been read. 1.6 does not - * always read all the deflate data; specifically it cannot be relied - * upon to read the Adler32 at the end. If it doesn't ignore IDAT - * chunks which are longer than zero as well: - */ - if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) - || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0) - png_benign_error(png_ptr, "..Too many IDATs found"); - - png_crc_finish(png_ptr, length); - } - else if (chunk_name == png_PLTE) - png_handle_PLTE(png_ptr, info_ptr, length); - -#ifdef PNG_READ_bKGD_SUPPORTED - else if (chunk_name == png_bKGD) - png_handle_bKGD(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED - else if (chunk_name == png_cHRM) - png_handle_cHRM(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_eXIf_SUPPORTED - else if (chunk_name == png_eXIf) - png_handle_eXIf(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_gAMA_SUPPORTED - else if (chunk_name == png_gAMA) - png_handle_gAMA(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_hIST_SUPPORTED - else if (chunk_name == png_hIST) - png_handle_hIST(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED - else if (chunk_name == png_oFFs) - png_handle_oFFs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED - else if (chunk_name == png_pCAL) - png_handle_pCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED - else if (chunk_name == png_sCAL) - png_handle_sCAL(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED - else if (chunk_name == png_pHYs) - png_handle_pHYs(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED - else if (chunk_name == png_sBIT) - png_handle_sBIT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sRGB_SUPPORTED - else if (chunk_name == png_sRGB) - png_handle_sRGB(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iCCP_SUPPORTED - else if (chunk_name == png_iCCP) - png_handle_iCCP(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_sPLT_SUPPORTED - else if (chunk_name == png_sPLT) - png_handle_sPLT(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED - else if (chunk_name == png_tEXt) - png_handle_tEXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tIME_SUPPORTED - else if (chunk_name == png_tIME) - png_handle_tIME(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_tRNS_SUPPORTED - else if (chunk_name == png_tRNS) - png_handle_tRNS(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED - else if (chunk_name == png_zTXt) - png_handle_zTXt(png_ptr, info_ptr, length); -#endif - -#ifdef PNG_READ_iTXt_SUPPORTED - else if (chunk_name == png_iTXt) - png_handle_iTXt(png_ptr, info_ptr, length); -#endif - - else - png_handle_unknown(png_ptr, info_ptr, length, - PNG_HANDLE_CHUNK_AS_DEFAULT); - } while ((png_ptr->mode & PNG_HAVE_IEND) == 0); -} -#endif /* SEQUENTIAL_READ */ - -/* Free all memory used in the read struct */ -static void -png_read_destroy(png_structrp png_ptr) -{ - png_debug(1, "in png_read_destroy"); - -#ifdef PNG_READ_GAMMA_SUPPORTED - png_destroy_gamma_table(png_ptr); -#endif - - png_free(png_ptr, png_ptr->big_row_buf); - png_ptr->big_row_buf = NULL; - png_free(png_ptr, png_ptr->big_prev_row); - png_ptr->big_prev_row = NULL; - png_free(png_ptr, png_ptr->read_buffer); - png_ptr->read_buffer = NULL; - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - png_free(png_ptr, png_ptr->palette_lookup); - png_ptr->palette_lookup = NULL; - png_free(png_ptr, png_ptr->quantize_index); - png_ptr->quantize_index = NULL; -#endif - - if ((png_ptr->free_me & PNG_FREE_PLTE) != 0) - { - png_zfree(png_ptr, png_ptr->palette); - png_ptr->palette = NULL; - } - png_ptr->free_me &= ~PNG_FREE_PLTE; - -#if defined(PNG_tRNS_SUPPORTED) || \ - defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - if ((png_ptr->free_me & PNG_FREE_TRNS) != 0) - { - png_free(png_ptr, png_ptr->trans_alpha); - png_ptr->trans_alpha = NULL; - } - png_ptr->free_me &= ~PNG_FREE_TRNS; -#endif - - inflateEnd(&png_ptr->zstream); - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED - png_free(png_ptr, png_ptr->save_buffer); - png_ptr->save_buffer = NULL; -#endif - -#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) && \ - defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) - png_free(png_ptr, png_ptr->unknown_chunk.data); - png_ptr->unknown_chunk.data = NULL; -#endif - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->chunk_list = NULL; -#endif - -#if defined(PNG_READ_EXPAND_SUPPORTED) && \ - defined(PNG_ARM_NEON_IMPLEMENTATION) - png_free(png_ptr, png_ptr->riffled_palette); - png_ptr->riffled_palette = NULL; -#endif - - /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error - * callbacks are still set at this point. They are required to complete the - * destruction of the png_struct itself. - */ -} - -/* Free all memory used by the read */ -void PNGAPI -png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, - png_infopp end_info_ptr_ptr) -{ - png_structrp png_ptr = NULL; - - png_debug(1, "in png_destroy_read_struct"); - - if (png_ptr_ptr != NULL) - png_ptr = *png_ptr_ptr; - - if (png_ptr == NULL) - return; - - /* libpng 1.6.0: use the API to destroy info structs to ensure consistent - * behavior. Prior to 1.6.0 libpng did extra 'info' destruction in this API. - * The extra was, apparently, unnecessary yet this hides memory leak bugs. - */ - png_destroy_info_struct(png_ptr, end_info_ptr_ptr); - png_destroy_info_struct(png_ptr, info_ptr_ptr); - - *png_ptr_ptr = NULL; - png_read_destroy(png_ptr); - png_destroy_png_struct(png_ptr); -} - -void PNGAPI -png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->read_row_fn = read_row_fn; -} - - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -#ifdef PNG_INFO_IMAGE_SUPPORTED -void PNGAPI -png_read_png(png_structrp png_ptr, png_inforp info_ptr, - int transforms, voidp params) -{ - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* png_read_info() gives us all of the information from the - * PNG file before the first IDAT (image data chunk). - */ - png_read_info(png_ptr, info_ptr); - if (info_ptr->height > PNG_UINT_32_MAX/(sizeof (png_bytep))) - png_error(png_ptr, "Image is too high to process with png_read_png()"); - - /* -------------- image transformations start here ------------------- */ - /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM - * is not implemented. This will only happen in de-configured (non-default) - * libpng builds. The results can be unexpected - png_read_png may return - * short or mal-formed rows because the transform is skipped. - */ - - /* Tell libpng to strip 16-bit/color files down to 8 bits per color. - */ - if ((transforms & PNG_TRANSFORM_SCALE_16) != 0) - /* Added at libpng-1.5.4. "strip_16" produces the same result that it - * did in earlier versions, while "scale_16" is now more accurate. - */ -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - png_set_scale_16(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported"); -#endif - - /* If both SCALE and STRIP are required pngrtran will effectively cancel the - * latter by doing SCALE first. This is ok and allows apps not to check for - * which is supported to get the right answer. - */ - if ((transforms & PNG_TRANSFORM_STRIP_16) != 0) -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - png_set_strip_16(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported"); -#endif - - /* Strip alpha bytes from the input data without combining with - * the background (not recommended). - */ - if ((transforms & PNG_TRANSFORM_STRIP_ALPHA) != 0) -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - png_set_strip_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported"); -#endif - - /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single - * byte into separate bytes (useful for paletted and grayscale images). - */ - if ((transforms & PNG_TRANSFORM_PACKING) != 0) -#ifdef PNG_READ_PACK_SUPPORTED - png_set_packing(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); -#endif - - /* Change the order of packed pixels to least significant bit first - * (not useful if you are using png_set_packing). - */ - if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) -#ifdef PNG_READ_PACKSWAP_SUPPORTED - png_set_packswap(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); -#endif - - /* Expand paletted colors into true RGB triplets - * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel - * Expand paletted or RGB images with transparency to full alpha - * channels so the data will be available as RGBA quartets. - */ - if ((transforms & PNG_TRANSFORM_EXPAND) != 0) -#ifdef PNG_READ_EXPAND_SUPPORTED - png_set_expand(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported"); -#endif - - /* We don't handle background color or gamma transformation or quantizing. - */ - - /* Invert monochrome files to have 0 as white and 1 as black - */ - if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0) -#ifdef PNG_READ_INVERT_SUPPORTED - png_set_invert_mono(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); -#endif - - /* If you want to shift the pixel values from the range [0,255] or - * [0,65535] to the original [0,7] or [0,31], or whatever range the - * colors were originally in: - */ - if ((transforms & PNG_TRANSFORM_SHIFT) != 0) -#ifdef PNG_READ_SHIFT_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sBIT) != 0) - png_set_shift(png_ptr, &info_ptr->sig_bit); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); -#endif - - /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ - if ((transforms & PNG_TRANSFORM_BGR) != 0) -#ifdef PNG_READ_BGR_SUPPORTED - png_set_bgr(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); -#endif - - /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ - if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0) -#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED - png_set_swap_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); -#endif - - /* Swap bytes of 16-bit files to least significant byte first */ - if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0) -#ifdef PNG_READ_SWAP_SUPPORTED - png_set_swap(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); -#endif - -/* Added at libpng-1.2.41 */ - /* Invert the alpha channel from opacity to transparency */ - if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0) -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - png_set_invert_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); -#endif - -/* Added at libpng-1.2.41 */ - /* Expand grayscale image to RGB */ - if ((transforms & PNG_TRANSFORM_GRAY_TO_RGB) != 0) -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - png_set_gray_to_rgb(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported"); -#endif - -/* Added at libpng-1.5.4 */ - if ((transforms & PNG_TRANSFORM_EXPAND_16) != 0) -#ifdef PNG_READ_EXPAND_16_SUPPORTED - png_set_expand_16(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported"); -#endif - - /* We don't handle adding filler bytes */ - - /* We use png_read_image and rely on that for interlace handling, but we also - * call png_read_update_info therefore must turn on interlace handling now: - */ - (void)png_set_interlace_handling(png_ptr); - - /* Optional call to gamma correct and add the background to the palette - * and update info structure. REQUIRED if you are expecting libpng to - * update the palette for you (i.e., you selected such a transform above). - */ - png_read_update_info(png_ptr, info_ptr); - - /* -------------- image transformations end here ------------------- */ - - png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); - if (info_ptr->row_pointers == NULL) - { - png_uint_32 iptr; - - info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr, - info_ptr->height * (sizeof (png_bytep)))); - - for (iptr=0; iptrheight; iptr++) - info_ptr->row_pointers[iptr] = NULL; - - info_ptr->free_me |= PNG_FREE_ROWS; - - for (iptr = 0; iptr < info_ptr->height; iptr++) - info_ptr->row_pointers[iptr] = png_voidcast(png_bytep, - png_malloc(png_ptr, info_ptr->rowbytes)); - } - - png_read_image(png_ptr, info_ptr->row_pointers); - info_ptr->valid |= PNG_INFO_IDAT; - - /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ - png_read_end(png_ptr, info_ptr); - - PNG_UNUSED(params) -} -#endif /* INFO_IMAGE */ -#endif /* SEQUENTIAL_READ */ - -#ifdef PNG_SIMPLIFIED_READ_SUPPORTED -/* SIMPLIFIED READ - * - * This code currently relies on the sequential reader, though it could easily - * be made to work with the progressive one. - */ -/* Arguments to png_image_finish_read: */ - -/* Encoding of PNG data (used by the color-map code) */ -# define P_NOTSET 0 /* File encoding not yet known */ -# define P_sRGB 1 /* 8-bit encoded to sRGB gamma */ -# define P_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */ -# define P_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */ -# define P_LINEAR8 4 /* 8-bit linear: only from a file value */ - -/* Color-map processing: after libpng has run on the PNG image further - * processing may be needed to convert the data to color-map indices. - */ -#define PNG_CMAP_NONE 0 -#define PNG_CMAP_GA 1 /* Process GA data to a color-map with alpha */ -#define PNG_CMAP_TRANS 2 /* Process GA data to a background index */ -#define PNG_CMAP_RGB 3 /* Process RGB data */ -#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */ - -/* The following document where the background is for each processing case. */ -#define PNG_CMAP_NONE_BACKGROUND 256 -#define PNG_CMAP_GA_BACKGROUND 231 -#define PNG_CMAP_TRANS_BACKGROUND 254 -#define PNG_CMAP_RGB_BACKGROUND 256 -#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216 - -typedef struct -{ - /* Arguments: */ - png_imagep image; - png_voidp buffer; - png_int_32 row_stride; - png_voidp colormap; - png_const_colorp background; - /* Local variables: */ - png_voidp local_row; - png_voidp first_row; - ptrdiff_t row_bytes; /* step between rows */ - int file_encoding; /* E_ values above */ - png_fixed_point gamma_to_linear; /* For P_FILE, reciprocal of gamma */ - int colormap_processing; /* PNG_CMAP_ values above */ -} png_image_read_control; - -/* Do all the *safe* initialization - 'safe' means that png_error won't be - * called, so setting up the jmp_buf is not required. This means that anything - * called from here must *not* call png_malloc - it has to call png_malloc_warn - * instead so that control is returned safely back to this routine. - */ -static int -png_image_read_init(png_imagep image) -{ - if (image->opaque == NULL) - { - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image, - png_safe_error, png_safe_warning); - - /* And set the rest of the structure to NULL to ensure that the various - * fields are consistent. - */ - memset(image, 0, (sizeof *image)); - image->version = PNG_IMAGE_VERSION; - - if (png_ptr != NULL) - { - png_infop info_ptr = png_create_info_struct(png_ptr); - - if (info_ptr != NULL) - { - png_controlp control = png_voidcast(png_controlp, - png_malloc_warn(png_ptr, (sizeof *control))); - - if (control != NULL) - { - memset(control, 0, (sizeof *control)); - - control->png_ptr = png_ptr; - control->info_ptr = info_ptr; - control->for_write = 0; - - image->opaque = control; - return 1; - } - - /* Error clean up */ - png_destroy_info_struct(png_ptr, &info_ptr); - } - - png_destroy_read_struct(&png_ptr, NULL, NULL); - } - - return png_image_error(image, "png_image_read: out of memory"); - } - - return png_image_error(image, "png_image_read: opaque pointer not NULL"); -} - -/* Utility to find the base format of a PNG file from a png_struct. */ -static png_uint_32 -png_image_format(png_structrp png_ptr) -{ - png_uint_32 format = 0; - - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - format |= PNG_FORMAT_FLAG_COLOR; - - if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) - format |= PNG_FORMAT_FLAG_ALPHA; - - /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS - * sets the png_struct fields; that's all we are interested in here. The - * precise interaction with an app call to png_set_tRNS and PNG file reading - * is unclear. - */ - else if (png_ptr->num_trans > 0) - format |= PNG_FORMAT_FLAG_ALPHA; - - if (png_ptr->bit_depth == 16) - format |= PNG_FORMAT_FLAG_LINEAR; - - if ((png_ptr->color_type & PNG_COLOR_MASK_PALETTE) != 0) - format |= PNG_FORMAT_FLAG_COLORMAP; - - return format; -} - -/* Is the given gamma significantly different from sRGB? The test is the same - * one used in pngrtran.c when deciding whether to do gamma correction. The - * arithmetic optimizes the division by using the fact that the inverse of the - * file sRGB gamma is 2.2 - */ -static int -png_gamma_not_sRGB(png_fixed_point g) -{ - if (g < PNG_FP_1) - { - /* An uninitialized gamma is assumed to be sRGB for the simplified API. */ - if (g == 0) - return 0; - - return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */); - } - - return 1; -} - -/* Do the main body of a 'png_image_begin_read' function; read the PNG file - * header and fill in all the information. This is executed in a safe context, - * unlike the init routine above. - */ -static int -png_image_read_header(png_voidp argument) -{ - png_imagep image = png_voidcast(png_imagep, argument); - png_structrp png_ptr = image->opaque->png_ptr; - png_inforp info_ptr = image->opaque->info_ptr; - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED - png_set_benign_errors(png_ptr, 1/*warn*/); -#endif - png_read_info(png_ptr, info_ptr); - - /* Do this the fast way; just read directly out of png_struct. */ - image->width = png_ptr->width; - image->height = png_ptr->height; - - { - png_uint_32 format = png_image_format(png_ptr); - - image->format = format; - -#ifdef PNG_COLORSPACE_SUPPORTED - /* Does the colorspace match sRGB? If there is no color endpoint - * (colorant) information assume yes, otherwise require the - * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set. If the - * colorspace has been determined to be invalid ignore it. - */ - if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags - & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB| - PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS)) - image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB; -#endif - } - - /* We need the maximum number of entries regardless of the format the - * application sets here. - */ - { - png_uint_32 cmap_entries; - - switch (png_ptr->color_type) - { - case PNG_COLOR_TYPE_GRAY: - cmap_entries = 1U << png_ptr->bit_depth; - break; - - case PNG_COLOR_TYPE_PALETTE: - cmap_entries = (png_uint_32)png_ptr->num_palette; - break; - - default: - cmap_entries = 256; - break; - } - - if (cmap_entries > 256) - cmap_entries = 256; - - image->colormap_entries = cmap_entries; - } - - return 1; -} - -#ifdef PNG_STDIO_SUPPORTED -int PNGAPI -png_image_begin_read_from_stdio(png_imagep image, FILE* file) -{ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (file != NULL) - { - if (png_image_read_init(image) != 0) - { - /* This is slightly evil, but png_init_io doesn't do anything other - * than this and we haven't changed the standard IO functions so - * this saves a 'safe' function. - */ - image->opaque->png_ptr->io_ptr = file; - return png_safe_execute(image, png_image_read_header, image); - } - } - - else - return png_image_error(image, - "png_image_begin_read_from_stdio: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION"); - - return 0; -} - -int PNGAPI -png_image_begin_read_from_file(png_imagep image, const char *file_name) -{ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (file_name != NULL) - { - FILE *fp = fopen(file_name, "rb"); - - if (fp != NULL) - { - if (png_image_read_init(image) != 0) - { - image->opaque->png_ptr->io_ptr = fp; - image->opaque->owned_file = 1; - return png_safe_execute(image, png_image_read_header, image); - } - - /* Clean up: just the opened file. */ - (void)fclose(fp); - } - - else - return png_image_error(image, strerror(errno)); - } - - else - return png_image_error(image, - "png_image_begin_read_from_file: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION"); - - return 0; -} -#endif /* STDIO */ - -static void PNGCBAPI -png_image_memory_read(png_structp png_ptr, png_bytep out, size_t need) -{ - if (png_ptr != NULL) - { - png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr); - if (image != NULL) - { - png_controlp cp = image->opaque; - if (cp != NULL) - { - png_const_bytep memory = cp->memory; - size_t size = cp->size; - - if (memory != NULL && size >= need) - { - memcpy(out, memory, need); - cp->memory = memory + need; - cp->size = size - need; - return; - } - - png_error(png_ptr, "read beyond end of data"); - } - } - - png_error(png_ptr, "invalid memory read"); - } -} - -int PNGAPI png_image_begin_read_from_memory(png_imagep image, - png_const_voidp memory, size_t size) -{ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (memory != NULL && size > 0) - { - if (png_image_read_init(image) != 0) - { - /* Now set the IO functions to read from the memory buffer and - * store it into io_ptr. Again do this in-place to avoid calling a - * libpng function that requires error handling. - */ - image->opaque->memory = png_voidcast(png_const_bytep, memory); - image->opaque->size = size; - image->opaque->png_ptr->io_ptr = image; - image->opaque->png_ptr->read_data_fn = png_image_memory_read; - - return png_safe_execute(image, png_image_read_header, image); - } - } - - else - return png_image_error(image, - "png_image_begin_read_from_memory: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION"); - - return 0; -} - -/* Utility function to skip chunks that are not used by the simplified image - * read functions and an appropriate macro to call it. - */ -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -static void -png_image_skip_unused_chunks(png_structrp png_ptr) -{ - /* Prepare the reader to ignore all recognized chunks whose data will not - * be used, i.e., all chunks recognized by libpng except for those - * involved in basic image reading: - * - * IHDR, PLTE, IDAT, IEND - * - * Or image data handling: - * - * tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT. - * - * This provides a small performance improvement and eliminates any - * potential vulnerability to security problems in the unused chunks. - * - * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored - * too. This allows the simplified API to be compiled without iCCP support, - * however if the support is there the chunk is still checked to detect - * errors (which are unfortunately quite common.) - */ - { - static const png_byte chunks_to_process[] = { - 98, 75, 71, 68, '\0', /* bKGD */ - 99, 72, 82, 77, '\0', /* cHRM */ - 103, 65, 77, 65, '\0', /* gAMA */ -# ifdef PNG_READ_iCCP_SUPPORTED - 105, 67, 67, 80, '\0', /* iCCP */ -# endif - 115, 66, 73, 84, '\0', /* sBIT */ - 115, 82, 71, 66, '\0', /* sRGB */ - }; - - /* Ignore unknown chunks and all other chunks except for the - * IHDR, PLTE, tRNS, IDAT, and IEND chunks. - */ - png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER, - NULL, -1); - - /* But do not ignore image data handling chunks */ - png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT, - chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5); - } -} - -# define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p) -#else -# define PNG_SKIP_CHUNKS(p) ((void)0) -#endif /* HANDLE_AS_UNKNOWN */ - -/* The following macro gives the exact rounded answer for all values in the - * range 0..255 (it actually divides by 51.2, but the rounding still generates - * the correct numbers 0..5 - */ -#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8) - -/* Utility functions to make particular color-maps */ -static void -set_file_encoding(png_image_read_control *display) -{ - png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma; - if (png_gamma_significant(g) != 0) - { - if (png_gamma_not_sRGB(g) != 0) - { - display->file_encoding = P_FILE; - display->gamma_to_linear = png_reciprocal(g); - } - - else - display->file_encoding = P_sRGB; - } - - else - display->file_encoding = P_LINEAR8; -} - -static unsigned int -decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding) -{ - if (encoding == P_FILE) /* double check */ - encoding = display->file_encoding; - - if (encoding == P_NOTSET) /* must be the file encoding */ - { - set_file_encoding(display); - encoding = display->file_encoding; - } - - switch (encoding) - { - case P_FILE: - value = png_gamma_16bit_correct(value*257, display->gamma_to_linear); - break; - - case P_sRGB: - value = png_sRGB_table[value]; - break; - - case P_LINEAR: - break; - - case P_LINEAR8: - value *= 257; - break; - -#ifdef __GNUC__ - default: - png_error(display->image->opaque->png_ptr, - "unexpected encoding (internal error)"); -#endif - } - - return value; -} - -static png_uint_32 -png_colormap_compose(png_image_read_control *display, - png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha, - png_uint_32 background, int encoding) -{ - /* The file value is composed on the background, the background has the given - * encoding and so does the result, the file is encoded with P_FILE and the - * file and alpha are 8-bit values. The (output) encoding will always be - * P_LINEAR or P_sRGB. - */ - png_uint_32 f = decode_gamma(display, foreground, foreground_encoding); - png_uint_32 b = decode_gamma(display, background, encoding); - - /* The alpha is always an 8-bit value (it comes from the palette), the value - * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires. - */ - f = f * alpha + b * (255-alpha); - - if (encoding == P_LINEAR) - { - /* Scale to 65535; divide by 255, approximately (in fact this is extremely - * accurate, it divides by 255.00000005937181414556, with no overflow.) - */ - f *= 257; /* Now scaled by 65535 */ - f += f >> 16; - f = (f+32768) >> 16; - } - - else /* P_sRGB */ - f = PNG_sRGB_FROM_LINEAR(f); - - return f; -} - -/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must - * be 8-bit. - */ -static void -png_create_colormap_entry(png_image_read_control *display, - png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue, - png_uint_32 alpha, int encoding) -{ - png_imagep image = display->image; - int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ? - P_LINEAR : P_sRGB; - int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && - (red != green || green != blue); - - if (ip > 255) - png_error(image->opaque->png_ptr, "color-map index out of range"); - - /* Update the cache with whether the file gamma is significantly different - * from sRGB. - */ - if (encoding == P_FILE) - { - if (display->file_encoding == P_NOTSET) - set_file_encoding(display); - - /* Note that the cached value may be P_FILE too, but if it is then the - * gamma_to_linear member has been set. - */ - encoding = display->file_encoding; - } - - if (encoding == P_FILE) - { - png_fixed_point g = display->gamma_to_linear; - - red = png_gamma_16bit_correct(red*257, g); - green = png_gamma_16bit_correct(green*257, g); - blue = png_gamma_16bit_correct(blue*257, g); - - if (convert_to_Y != 0 || output_encoding == P_LINEAR) - { - alpha *= 257; - encoding = P_LINEAR; - } - - else - { - red = PNG_sRGB_FROM_LINEAR(red * 255); - green = PNG_sRGB_FROM_LINEAR(green * 255); - blue = PNG_sRGB_FROM_LINEAR(blue * 255); - encoding = P_sRGB; - } - } - - else if (encoding == P_LINEAR8) - { - /* This encoding occurs quite frequently in test cases because PngSuite - * includes a gAMA 1.0 chunk with most images. - */ - red *= 257; - green *= 257; - blue *= 257; - alpha *= 257; - encoding = P_LINEAR; - } - - else if (encoding == P_sRGB && - (convert_to_Y != 0 || output_encoding == P_LINEAR)) - { - /* The values are 8-bit sRGB values, but must be converted to 16-bit - * linear. - */ - red = png_sRGB_table[red]; - green = png_sRGB_table[green]; - blue = png_sRGB_table[blue]; - alpha *= 257; - encoding = P_LINEAR; - } - - /* This is set if the color isn't gray but the output is. */ - if (encoding == P_LINEAR) - { - if (convert_to_Y != 0) - { - /* NOTE: these values are copied from png_do_rgb_to_gray */ - png_uint_32 y = (png_uint_32)6968 * red + (png_uint_32)23434 * green + - (png_uint_32)2366 * blue; - - if (output_encoding == P_LINEAR) - y = (y + 16384) >> 15; - - else - { - /* y is scaled by 32768, we need it scaled by 255: */ - y = (y + 128) >> 8; - y *= 255; - y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7); - alpha = PNG_DIV257(alpha); - encoding = P_sRGB; - } - - blue = red = green = y; - } - - else if (output_encoding == P_sRGB) - { - red = PNG_sRGB_FROM_LINEAR(red * 255); - green = PNG_sRGB_FROM_LINEAR(green * 255); - blue = PNG_sRGB_FROM_LINEAR(blue * 255); - alpha = PNG_DIV257(alpha); - encoding = P_sRGB; - } - } - - if (encoding != output_encoding) - png_error(image->opaque->png_ptr, "bad encoding (internal error)"); - - /* Store the value. */ - { -# ifdef PNG_FORMAT_AFIRST_SUPPORTED - int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 && - (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; -# else -# define afirst 0 -# endif -# ifdef PNG_FORMAT_BGR_SUPPORTED - int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; -# else -# define bgr 0 -# endif - - if (output_encoding == P_LINEAR) - { - png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap); - - entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); - - /* The linear 16-bit values must be pre-multiplied by the alpha channel - * value, if less than 65535 (this is, effectively, composite on black - * if the alpha channel is removed.) - */ - switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) - { - case 4: - entry[afirst ? 0 : 3] = (png_uint_16)alpha; - /* FALLTHROUGH */ - - case 3: - if (alpha < 65535) - { - if (alpha > 0) - { - blue = (blue * alpha + 32767U)/65535U; - green = (green * alpha + 32767U)/65535U; - red = (red * alpha + 32767U)/65535U; - } - - else - red = green = blue = 0; - } - entry[afirst + (2 ^ bgr)] = (png_uint_16)blue; - entry[afirst + 1] = (png_uint_16)green; - entry[afirst + bgr] = (png_uint_16)red; - break; - - case 2: - entry[1 ^ afirst] = (png_uint_16)alpha; - /* FALLTHROUGH */ - - case 1: - if (alpha < 65535) - { - if (alpha > 0) - green = (green * alpha + 32767U)/65535U; - - else - green = 0; - } - entry[afirst] = (png_uint_16)green; - break; - - default: - break; - } - } - - else /* output encoding is P_sRGB */ - { - png_bytep entry = png_voidcast(png_bytep, display->colormap); - - entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format); - - switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format)) - { - case 4: - entry[afirst ? 0 : 3] = (png_byte)alpha; - /* FALLTHROUGH */ - case 3: - entry[afirst + (2 ^ bgr)] = (png_byte)blue; - entry[afirst + 1] = (png_byte)green; - entry[afirst + bgr] = (png_byte)red; - break; - - case 2: - entry[1 ^ afirst] = (png_byte)alpha; - /* FALLTHROUGH */ - case 1: - entry[afirst] = (png_byte)green; - break; - - default: - break; - } - } - -# ifdef afirst -# undef afirst -# endif -# ifdef bgr -# undef bgr -# endif - } -} - -static int -make_gray_file_colormap(png_image_read_control *display) -{ - unsigned int i; - - for (i=0; i<256; ++i) - png_create_colormap_entry(display, i, i, i, i, 255, P_FILE); - - return (int)i; -} - -static int -make_gray_colormap(png_image_read_control *display) -{ - unsigned int i; - - for (i=0; i<256; ++i) - png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB); - - return (int)i; -} -#define PNG_GRAY_COLORMAP_ENTRIES 256 - -static int -make_ga_colormap(png_image_read_control *display) -{ - unsigned int i, a; - - /* Alpha is retained, the output will be a color-map with entries - * selected by six levels of alpha. One transparent entry, 6 gray - * levels for all the intermediate alpha values, leaving 230 entries - * for the opaque grays. The color-map entries are the six values - * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the - * relevant entry. - * - * if (alpha > 229) // opaque - * { - * // The 231 entries are selected to make the math below work: - * base = 0; - * entry = (231 * gray + 128) >> 8; - * } - * else if (alpha < 26) // transparent - * { - * base = 231; - * entry = 0; - * } - * else // partially opaque - * { - * base = 226 + 6 * PNG_DIV51(alpha); - * entry = PNG_DIV51(gray); - * } - */ - i = 0; - while (i < 231) - { - unsigned int gray = (i * 256 + 115) / 231; - png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB); - } - - /* 255 is used here for the component values for consistency with the code - * that undoes premultiplication in pngwrite.c. - */ - png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB); - - for (a=1; a<5; ++a) - { - unsigned int g; - - for (g=0; g<6; ++g) - png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51, - P_sRGB); - } - - return (int)i; -} - -#define PNG_GA_COLORMAP_ENTRIES 256 - -static int -make_rgb_colormap(png_image_read_control *display) -{ - unsigned int i, r; - - /* Build a 6x6x6 opaque RGB cube */ - for (i=r=0; r<6; ++r) - { - unsigned int g; - - for (g=0; g<6; ++g) - { - unsigned int b; - - for (b=0; b<6; ++b) - png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255, - P_sRGB); - } - } - - return (int)i; -} - -#define PNG_RGB_COLORMAP_ENTRIES 216 - -/* Return a palette index to the above palette given three 8-bit sRGB values. */ -#define PNG_RGB_INDEX(r,g,b) \ - ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b))) - -static int -png_image_read_colormap(png_voidp argument) -{ - png_image_read_control *display = - png_voidcast(png_image_read_control*, argument); - png_imagep image = display->image; - - png_structrp png_ptr = image->opaque->png_ptr; - png_uint_32 output_format = image->format; - int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ? - P_LINEAR : P_sRGB; - - unsigned int cmap_entries; - unsigned int output_processing; /* Output processing option */ - unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */ - - /* Background information; the background color and the index of this color - * in the color-map if it exists (else 256). - */ - unsigned int background_index = 256; - png_uint_32 back_r, back_g, back_b; - - /* Flags to accumulate things that need to be done to the input. */ - int expand_tRNS = 0; - - /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is - * very difficult to do, the results look awful, and it is difficult to see - * what possible use it is because the application can't control the - * color-map. - */ - if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 || - png_ptr->num_trans > 0) /* alpha in input */ && - ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */) - { - if (output_encoding == P_LINEAR) /* compose on black */ - back_b = back_g = back_r = 0; - - else if (display->background == NULL /* no way to remove it */) - png_error(png_ptr, - "background color must be supplied to remove alpha/transparency"); - - /* Get a copy of the background color (this avoids repeating the checks - * below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the - * output format. - */ - else - { - back_g = display->background->green; - if ((output_format & PNG_FORMAT_FLAG_COLOR) != 0) - { - back_r = display->background->red; - back_b = display->background->blue; - } - else - back_b = back_r = back_g; - } - } - - else if (output_encoding == P_LINEAR) - back_b = back_r = back_g = 65535; - - else - back_b = back_r = back_g = 255; - - /* Default the input file gamma if required - this is necessary because - * libpng assumes that if no gamma information is present the data is in the - * output format, but the simplified API deduces the gamma from the input - * format. - */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0) - { - /* Do this directly, not using the png_colorspace functions, to ensure - * that it happens even if the colorspace is invalid (though probably if - * it is the setting will be ignored) Note that the same thing can be - * achieved at the application interface with png_set_gAMA. - */ - if (png_ptr->bit_depth == 16 && - (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) - png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR; - - else - png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE; - - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - } - - /* Decide what to do based on the PNG color type of the input data. The - * utility function png_create_colormap_entry deals with most aspects of the - * output transformations; this code works out how to produce bytes of - * color-map entries from the original format. - */ - switch (png_ptr->color_type) - { - case PNG_COLOR_TYPE_GRAY: - if (png_ptr->bit_depth <= 8) - { - /* There at most 256 colors in the output, regardless of - * transparency. - */ - unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0; - - cmap_entries = 1U << png_ptr->bit_depth; - if (cmap_entries > image->colormap_entries) - png_error(png_ptr, "gray[8] color-map: too few entries"); - - step = 255 / (cmap_entries - 1); - output_processing = PNG_CMAP_NONE; - - /* If there is a tRNS chunk then this either selects a transparent - * value or, if the output has no alpha, the background color. - */ - if (png_ptr->num_trans > 0) - { - trans = png_ptr->trans_color.gray; - - if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) - back_alpha = output_encoding == P_LINEAR ? 65535 : 255; - } - - /* png_create_colormap_entry just takes an RGBA and writes the - * corresponding color-map entry using the format from 'image', - * including the required conversion to sRGB or linear as - * appropriate. The input values are always either sRGB (if the - * gamma correction flag is 0) or 0..255 scaled file encoded values - * (if the function must gamma correct them). - */ - for (i=val=0; ibit_depth < 8) - png_set_packing(png_ptr); - } - - else /* bit depth is 16 */ - { - /* The 16-bit input values can be converted directly to 8-bit gamma - * encoded values; however, if a tRNS chunk is present 257 color-map - * entries are required. This means that the extra entry requires - * special processing; add an alpha channel, sacrifice gray level - * 254 and convert transparent (alpha==0) entries to that. - * - * Use libpng to chop the data to 8 bits. Convert it to sRGB at the - * same time to minimize quality loss. If a tRNS chunk is present - * this means libpng must handle it too; otherwise it is impossible - * to do the exact match on the 16-bit value. - * - * If the output has no alpha channel *and* the background color is - * gray then it is possible to let libpng handle the substitution by - * ensuring that the corresponding gray level matches the background - * color exactly. - */ - data_encoding = P_sRGB; - - if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "gray[16] color-map: too few entries"); - - cmap_entries = (unsigned int)make_gray_colormap(display); - - if (png_ptr->num_trans > 0) - { - unsigned int back_alpha; - - if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) - back_alpha = 0; - - else - { - if (back_r == back_g && back_g == back_b) - { - /* Background is gray; no special processing will be - * required. - */ - png_color_16 c; - png_uint_32 gray = back_g; - - if (output_encoding == P_LINEAR) - { - gray = PNG_sRGB_FROM_LINEAR(gray * 255); - - /* And make sure the corresponding palette entry - * matches. - */ - png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 65535, P_LINEAR); - } - - /* The background passed to libpng, however, must be the - * sRGB value. - */ - c.index = 0; /*unused*/ - c.gray = c.red = c.green = c.blue = (png_uint_16)gray; - - /* NOTE: does this work without expanding tRNS to alpha? - * It should be the color->gray case below apparently - * doesn't. - */ - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - - output_processing = PNG_CMAP_NONE; - break; - } -#ifdef __COVERITY__ - /* Coverity claims that output_encoding cannot be 2 (P_LINEAR) - * here. - */ - back_alpha = 255; -#else - back_alpha = output_encoding == P_LINEAR ? 65535 : 255; -#endif - } - - /* output_processing means that the libpng-processed row will be - * 8-bit GA and it has to be processing to single byte color-map - * values. Entry 254 is replaced by either a completely - * transparent entry or by the background color at full - * precision (and the background color is not a simple gray - * level in this case.) - */ - expand_tRNS = 1; - output_processing = PNG_CMAP_TRANS; - background_index = 254; - - /* And set (overwrite) color-map entry 254 to the actual - * background color at full precision. - */ - png_create_colormap_entry(display, 254, back_r, back_g, back_b, - back_alpha, output_encoding); - } - - else - output_processing = PNG_CMAP_NONE; - } - break; - - case PNG_COLOR_TYPE_GRAY_ALPHA: - /* 8-bit or 16-bit PNG with two channels - gray and alpha. A minimum - * of 65536 combinations. If, however, the alpha channel is to be - * removed there are only 256 possibilities if the background is gray. - * (Otherwise there is a subset of the 65536 possibilities defined by - * the triangle between black, white and the background color.) - * - * Reduce 16-bit files to 8-bit and sRGB encode the result. No need to - * worry about tRNS matching - tRNS is ignored if there is an alpha - * channel. - */ - data_encoding = P_sRGB; - - if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "gray+alpha color-map: too few entries"); - - cmap_entries = (unsigned int)make_ga_colormap(display); - - background_index = PNG_CMAP_GA_BACKGROUND; - output_processing = PNG_CMAP_GA; - } - - else /* alpha is removed */ - { - /* Alpha must be removed as the PNG data is processed when the - * background is a color because the G and A channels are - * independent and the vector addition (non-parallel vectors) is a - * 2-D problem. - * - * This can be reduced to the same algorithm as above by making a - * colormap containing gray levels (for the opaque grays), a - * background entry (for a transparent pixel) and a set of four six - * level color values, one set for each intermediate alpha value. - * See the comments in make_ga_colormap for how this works in the - * per-pixel processing. - * - * If the background is gray, however, we only need a 256 entry gray - * level color map. It is sufficient to make the entry generated - * for the background color be exactly the color specified. - */ - if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 || - (back_r == back_g && back_g == back_b)) - { - /* Background is gray; no special processing will be required. */ - png_color_16 c; - png_uint_32 gray = back_g; - - if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "gray-alpha color-map: too few entries"); - - cmap_entries = (unsigned int)make_gray_colormap(display); - - if (output_encoding == P_LINEAR) - { - gray = PNG_sRGB_FROM_LINEAR(gray * 255); - - /* And make sure the corresponding palette entry matches. */ - png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 65535, P_LINEAR); - } - - /* The background passed to libpng, however, must be the sRGB - * value. - */ - c.index = 0; /*unused*/ - c.gray = c.red = c.green = c.blue = (png_uint_16)gray; - - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - - output_processing = PNG_CMAP_NONE; - } - - else - { - png_uint_32 i, a; - - /* This is the same as png_make_ga_colormap, above, except that - * the entries are all opaque. - */ - if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "ga-alpha color-map: too few entries"); - - i = 0; - while (i < 231) - { - png_uint_32 gray = (i * 256 + 115) / 231; - png_create_colormap_entry(display, i++, gray, gray, gray, - 255, P_sRGB); - } - - /* NOTE: this preserves the full precision of the application - * background color. - */ - background_index = i; - png_create_colormap_entry(display, i++, back_r, back_g, back_b, -#ifdef __COVERITY__ - /* Coverity claims that output_encoding - * cannot be 2 (P_LINEAR) here. - */ 255U, -#else - output_encoding == P_LINEAR ? 65535U : 255U, -#endif - output_encoding); - - /* For non-opaque input composite on the sRGB background - this - * requires inverting the encoding for each component. The input - * is still converted to the sRGB encoding because this is a - * reasonable approximate to the logarithmic curve of human - * visual sensitivity, at least over the narrow range which PNG - * represents. Consequently 'G' is always sRGB encoded, while - * 'A' is linear. We need the linear background colors. - */ - if (output_encoding == P_sRGB) /* else already linear */ - { - /* This may produce a value not exactly matching the - * background, but that's ok because these numbers are only - * used when alpha != 0 - */ - back_r = png_sRGB_table[back_r]; - back_g = png_sRGB_table[back_g]; - back_b = png_sRGB_table[back_b]; - } - - for (a=1; a<5; ++a) - { - unsigned int g; - - /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled - * by an 8-bit alpha value (0..255). - */ - png_uint_32 alpha = 51 * a; - png_uint_32 back_rx = (255-alpha) * back_r; - png_uint_32 back_gx = (255-alpha) * back_g; - png_uint_32 back_bx = (255-alpha) * back_b; - - for (g=0; g<6; ++g) - { - png_uint_32 gray = png_sRGB_table[g*51] * alpha; - - png_create_colormap_entry(display, i++, - PNG_sRGB_FROM_LINEAR(gray + back_rx), - PNG_sRGB_FROM_LINEAR(gray + back_gx), - PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB); - } - } - - cmap_entries = i; - output_processing = PNG_CMAP_GA; - } - } - break; - - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - /* Exclude the case where the output is gray; we can always handle this - * with the cases above. - */ - if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0) - { - /* The color-map will be grayscale, so we may as well convert the - * input RGB values to a simple grayscale and use the grayscale - * code above. - * - * NOTE: calling this apparently damages the recognition of the - * transparent color in background color handling; call - * png_set_tRNS_to_alpha before png_set_background_fixed. - */ - png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1, - -1); - data_encoding = P_sRGB; - - /* The output will now be one or two 8-bit gray or gray+alpha - * channels. The more complex case arises when the input has alpha. - */ - if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->num_trans > 0) && - (output_format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - /* Both input and output have an alpha channel, so no background - * processing is required; just map the GA bytes to the right - * color-map entry. - */ - expand_tRNS = 1; - - if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "rgb[ga] color-map: too few entries"); - - cmap_entries = (unsigned int)make_ga_colormap(display); - background_index = PNG_CMAP_GA_BACKGROUND; - output_processing = PNG_CMAP_GA; - } - - else - { - /* Either the input or the output has no alpha channel, so there - * will be no non-opaque pixels in the color-map; it will just be - * grayscale. - */ - if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "rgb[gray] color-map: too few entries"); - - /* Ideally this code would use libpng to do the gamma correction, - * but if an input alpha channel is to be removed we will hit the - * libpng bug in gamma+compose+rgb-to-gray (the double gamma - * correction bug). Fix this by dropping the gamma correction in - * this case and doing it in the palette; this will result in - * duplicate palette entries, but that's better than the - * alternative of double gamma correction. - */ - if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->num_trans > 0) && - png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0) - { - cmap_entries = (unsigned int)make_gray_file_colormap(display); - data_encoding = P_FILE; - } - - else - cmap_entries = (unsigned int)make_gray_colormap(display); - - /* But if the input has alpha or transparency it must be removed - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->num_trans > 0) - { - png_color_16 c; - png_uint_32 gray = back_g; - - /* We need to ensure that the application background exists in - * the colormap and that completely transparent pixels map to - * it. Achieve this simply by ensuring that the entry - * selected for the background really is the background color. - */ - if (data_encoding == P_FILE) /* from the fixup above */ - { - /* The app supplied a gray which is in output_encoding, we - * need to convert it to a value of the input (P_FILE) - * encoding then set this palette entry to the required - * output encoding. - */ - if (output_encoding == P_sRGB) - gray = png_sRGB_table[gray]; /* now P_LINEAR */ - - gray = PNG_DIV257(png_gamma_16bit_correct(gray, - png_ptr->colorspace.gamma)); /* now P_FILE */ - - /* And make sure the corresponding palette entry contains - * exactly the required sRGB value. - */ - png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 0/*unused*/, output_encoding); - } - - else if (output_encoding == P_LINEAR) - { - gray = PNG_sRGB_FROM_LINEAR(gray * 255); - - /* And make sure the corresponding palette entry matches. - */ - png_create_colormap_entry(display, gray, back_g, back_g, - back_g, 0/*unused*/, P_LINEAR); - } - - /* The background passed to libpng, however, must be the - * output (normally sRGB) value. - */ - c.index = 0; /*unused*/ - c.gray = c.red = c.green = c.blue = (png_uint_16)gray; - - /* NOTE: the following is apparently a bug in libpng. Without - * it the transparent color recognition in - * png_set_background_fixed seems to go wrong. - */ - expand_tRNS = 1; - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - } - - output_processing = PNG_CMAP_NONE; - } - } - - else /* output is color */ - { - /* We could use png_quantize here so long as there is no transparent - * color or alpha; png_quantize ignores alpha. Easier overall just - * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube. - * Consequently we always want libpng to produce sRGB data. - */ - data_encoding = P_sRGB; - - /* Is there any transparency or alpha? */ - if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - png_ptr->num_trans > 0) - { - /* Is there alpha in the output too? If so all four channels are - * processed into a special RGB cube with alpha support. - */ - if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - png_uint_32 r; - - if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) - png_error(png_ptr, "rgb+alpha color-map: too few entries"); - - cmap_entries = (unsigned int)make_rgb_colormap(display); - - /* Add a transparent entry. */ - png_create_colormap_entry(display, cmap_entries, 255, 255, - 255, 0, P_sRGB); - - /* This is stored as the background index for the processing - * algorithm. - */ - background_index = cmap_entries++; - - /* Add 27 r,g,b entries each with alpha 0.5. */ - for (r=0; r<256; r = (r << 1) | 0x7f) - { - png_uint_32 g; - - for (g=0; g<256; g = (g << 1) | 0x7f) - { - png_uint_32 b; - - /* This generates components with the values 0, 127 and - * 255 - */ - for (b=0; b<256; b = (b << 1) | 0x7f) - png_create_colormap_entry(display, cmap_entries++, - r, g, b, 128, P_sRGB); - } - } - - expand_tRNS = 1; - output_processing = PNG_CMAP_RGB_ALPHA; - } - - else - { - /* Alpha/transparency must be removed. The background must - * exist in the color map (achieved by setting adding it after - * the 666 color-map). If the standard processing code will - * pick up this entry automatically that's all that is - * required; libpng can be called to do the background - * processing. - */ - unsigned int sample_size = - PNG_IMAGE_SAMPLE_SIZE(output_format); - png_uint_32 r, g, b; /* sRGB background */ - - if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries) - png_error(png_ptr, "rgb-alpha color-map: too few entries"); - - cmap_entries = (unsigned int)make_rgb_colormap(display); - - png_create_colormap_entry(display, cmap_entries, back_r, - back_g, back_b, 0/*unused*/, output_encoding); - - if (output_encoding == P_LINEAR) - { - r = PNG_sRGB_FROM_LINEAR(back_r * 255); - g = PNG_sRGB_FROM_LINEAR(back_g * 255); - b = PNG_sRGB_FROM_LINEAR(back_b * 255); - } - - else - { - r = back_r; - g = back_g; - b = back_g; - } - - /* Compare the newly-created color-map entry with the one the - * PNG_CMAP_RGB algorithm will use. If the two entries don't - * match, add the new one and set this as the background - * index. - */ - if (memcmp((png_const_bytep)display->colormap + - sample_size * cmap_entries, - (png_const_bytep)display->colormap + - sample_size * PNG_RGB_INDEX(r,g,b), - sample_size) != 0) - { - /* The background color must be added. */ - background_index = cmap_entries++; - - /* Add 27 r,g,b entries each with created by composing with - * the background at alpha 0.5. - */ - for (r=0; r<256; r = (r << 1) | 0x7f) - { - for (g=0; g<256; g = (g << 1) | 0x7f) - { - /* This generates components with the values 0, 127 - * and 255 - */ - for (b=0; b<256; b = (b << 1) | 0x7f) - png_create_colormap_entry(display, cmap_entries++, - png_colormap_compose(display, r, P_sRGB, 128, - back_r, output_encoding), - png_colormap_compose(display, g, P_sRGB, 128, - back_g, output_encoding), - png_colormap_compose(display, b, P_sRGB, 128, - back_b, output_encoding), - 0/*unused*/, output_encoding); - } - } - - expand_tRNS = 1; - output_processing = PNG_CMAP_RGB_ALPHA; - } - - else /* background color is in the standard color-map */ - { - png_color_16 c; - - c.index = 0; /*unused*/ - c.red = (png_uint_16)back_r; - c.gray = c.green = (png_uint_16)back_g; - c.blue = (png_uint_16)back_b; - - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - - output_processing = PNG_CMAP_RGB; - } - } - } - - else /* no alpha or transparency in the input */ - { - /* Alpha in the output is irrelevant, simply map the opaque input - * pixels to the 6x6x6 color-map. - */ - if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries) - png_error(png_ptr, "rgb color-map: too few entries"); - - cmap_entries = (unsigned int)make_rgb_colormap(display); - output_processing = PNG_CMAP_RGB; - } - } - break; - - case PNG_COLOR_TYPE_PALETTE: - /* It's already got a color-map. It may be necessary to eliminate the - * tRNS entries though. - */ - { - unsigned int num_trans = png_ptr->num_trans; - png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL; - png_const_colorp colormap = png_ptr->palette; - int do_background = trans != NULL && - (output_format & PNG_FORMAT_FLAG_ALPHA) == 0; - unsigned int i; - - /* Just in case: */ - if (trans == NULL) - num_trans = 0; - - output_processing = PNG_CMAP_NONE; - data_encoding = P_FILE; /* Don't change from color-map indices */ - cmap_entries = (unsigned int)png_ptr->num_palette; - if (cmap_entries > 256) - cmap_entries = 256; - - if (cmap_entries > (unsigned int)image->colormap_entries) - png_error(png_ptr, "palette color-map: too few entries"); - - for (i=0; i < cmap_entries; ++i) - { - if (do_background != 0 && i < num_trans && trans[i] < 255) - { - if (trans[i] == 0) - png_create_colormap_entry(display, i, back_r, back_g, - back_b, 0, output_encoding); - - else - { - /* Must compose the PNG file color in the color-map entry - * on the sRGB color in 'back'. - */ - png_create_colormap_entry(display, i, - png_colormap_compose(display, colormap[i].red, - P_FILE, trans[i], back_r, output_encoding), - png_colormap_compose(display, colormap[i].green, - P_FILE, trans[i], back_g, output_encoding), - png_colormap_compose(display, colormap[i].blue, - P_FILE, trans[i], back_b, output_encoding), - output_encoding == P_LINEAR ? trans[i] * 257U : - trans[i], - output_encoding); - } - } - - else - png_create_colormap_entry(display, i, colormap[i].red, - colormap[i].green, colormap[i].blue, - i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/); - } - - /* The PNG data may have indices packed in fewer than 8 bits, it - * must be expanded if so. - */ - if (png_ptr->bit_depth < 8) - png_set_packing(png_ptr); - } - break; - - default: - png_error(png_ptr, "invalid PNG color type"); - /*NOT REACHED*/ - } - - /* Now deal with the output processing */ - if (expand_tRNS != 0 && png_ptr->num_trans > 0 && - (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0) - png_set_tRNS_to_alpha(png_ptr); - - switch (data_encoding) - { - case P_sRGB: - /* Change to 8-bit sRGB */ - png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB); - /* FALLTHROUGH */ - - case P_FILE: - if (png_ptr->bit_depth > 8) - png_set_scale_16(png_ptr); - break; - -#ifdef __GNUC__ - default: - png_error(png_ptr, "bad data option (internal error)"); -#endif - } - - if (cmap_entries > 256 || cmap_entries > image->colormap_entries) - png_error(png_ptr, "color map overflow (BAD internal error)"); - - image->colormap_entries = cmap_entries; - - /* Double check using the recorded background index */ - switch (output_processing) - { - case PNG_CMAP_NONE: - if (background_index != PNG_CMAP_NONE_BACKGROUND) - goto bad_background; - break; - - case PNG_CMAP_GA: - if (background_index != PNG_CMAP_GA_BACKGROUND) - goto bad_background; - break; - - case PNG_CMAP_TRANS: - if (background_index >= cmap_entries || - background_index != PNG_CMAP_TRANS_BACKGROUND) - goto bad_background; - break; - - case PNG_CMAP_RGB: - if (background_index != PNG_CMAP_RGB_BACKGROUND) - goto bad_background; - break; - - case PNG_CMAP_RGB_ALPHA: - if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND) - goto bad_background; - break; - - default: - png_error(png_ptr, "bad processing option (internal error)"); - - bad_background: - png_error(png_ptr, "bad background index (internal error)"); - } - - display->colormap_processing = (int)output_processing; - - return 1/*ok*/; -} - -/* The final part of the color-map read called from png_image_finish_read. */ -static int -png_image_read_and_map(png_voidp argument) -{ - png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - int passes; - - /* Called when the libpng data must be transformed into the color-mapped - * form. There is a local row buffer in display->local and this routine must - * do the interlace handling. - */ - switch (png_ptr->interlaced) - { - case PNG_INTERLACE_NONE: - passes = 1; - break; - - case PNG_INTERLACE_ADAM7: - passes = PNG_INTERLACE_ADAM7_PASSES; - break; - - default: - png_error(png_ptr, "unknown interlace type"); - } - - { - png_uint_32 height = image->height; - png_uint_32 width = image->width; - int proc = display->colormap_processing; - png_bytep first_row = png_voidcast(png_bytep, display->first_row); - ptrdiff_t step_row = display->row_bytes; - int pass; - - for (pass = 0; pass < passes; ++pass) - { - unsigned int startx, stepx, stepy; - png_uint_32 y; - - if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) - { - /* The row may be empty for a short image: */ - if (PNG_PASS_COLS(width, pass) == 0) - continue; - - startx = PNG_PASS_START_COL(pass); - stepx = PNG_PASS_COL_OFFSET(pass); - y = PNG_PASS_START_ROW(pass); - stepy = PNG_PASS_ROW_OFFSET(pass); - } - - else - { - y = 0; - startx = 0; - stepx = stepy = 1; - } - - for (; ylocal_row); - png_bytep outrow = first_row + y * step_row; - png_const_bytep end_row = outrow + width; - - /* Read read the libpng data into the temporary buffer. */ - png_read_row(png_ptr, inrow, NULL); - - /* Now process the row according to the processing option, note - * that the caller verifies that the format of the libpng output - * data is as required. - */ - outrow += startx; - switch (proc) - { - case PNG_CMAP_GA: - for (; outrow < end_row; outrow += stepx) - { - /* The data is always in the PNG order */ - unsigned int gray = *inrow++; - unsigned int alpha = *inrow++; - unsigned int entry; - - /* NOTE: this code is copied as a comment in - * make_ga_colormap above. Please update the - * comment if you change this code! - */ - if (alpha > 229) /* opaque */ - { - entry = (231 * gray + 128) >> 8; - } - else if (alpha < 26) /* transparent */ - { - entry = 231; - } - else /* partially opaque */ - { - entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray); - } - - *outrow = (png_byte)entry; - } - break; - - case PNG_CMAP_TRANS: - for (; outrow < end_row; outrow += stepx) - { - png_byte gray = *inrow++; - png_byte alpha = *inrow++; - - if (alpha == 0) - *outrow = PNG_CMAP_TRANS_BACKGROUND; - - else if (gray != PNG_CMAP_TRANS_BACKGROUND) - *outrow = gray; - - else - *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1); - } - break; - - case PNG_CMAP_RGB: - for (; outrow < end_row; outrow += stepx) - { - *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]); - inrow += 3; - } - break; - - case PNG_CMAP_RGB_ALPHA: - for (; outrow < end_row; outrow += stepx) - { - unsigned int alpha = inrow[3]; - - /* Because the alpha entries only hold alpha==0.5 values - * split the processing at alpha==0.25 (64) and 0.75 - * (196). - */ - - if (alpha >= 196) - *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], - inrow[2]); - - else if (alpha < 64) - *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND; - - else - { - /* Likewise there are three entries for each of r, g - * and b. We could select the entry by popcount on - * the top two bits on those architectures that - * support it, this is what the code below does, - * crudely. - */ - unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1; - - /* Here are how the values map: - * - * 0x00 .. 0x3f -> 0 - * 0x40 .. 0xbf -> 1 - * 0xc0 .. 0xff -> 2 - * - * So, as above with the explicit alpha checks, the - * breakpoints are at 64 and 196. - */ - if (inrow[0] & 0x80) back_i += 9; /* red */ - if (inrow[0] & 0x40) back_i += 9; - if (inrow[0] & 0x80) back_i += 3; /* green */ - if (inrow[0] & 0x40) back_i += 3; - if (inrow[0] & 0x80) back_i += 1; /* blue */ - if (inrow[0] & 0x40) back_i += 1; - - *outrow = (png_byte)back_i; - } - - inrow += 4; - } - break; - - default: - break; - } - } - } - } - - return 1; -} - -static int -png_image_read_colormapped(png_voidp argument) -{ - png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); - png_imagep image = display->image; - png_controlp control = image->opaque; - png_structrp png_ptr = control->png_ptr; - png_inforp info_ptr = control->info_ptr; - - int passes = 0; /* As a flag */ - - PNG_SKIP_CHUNKS(png_ptr); - - /* Update the 'info' structure and make sure the result is as required; first - * make sure to turn on the interlace handling if it will be required - * (because it can't be turned on *after* the call to png_read_update_info!) - */ - if (display->colormap_processing == PNG_CMAP_NONE) - passes = png_set_interlace_handling(png_ptr); - - png_read_update_info(png_ptr, info_ptr); - - /* The expected output can be deduced from the colormap_processing option. */ - switch (display->colormap_processing) - { - case PNG_CMAP_NONE: - /* Output must be one channel and one byte per pixel, the output - * encoding can be anything. - */ - if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE || - info_ptr->color_type == PNG_COLOR_TYPE_GRAY) && - info_ptr->bit_depth == 8) - break; - - goto bad_output; - - case PNG_CMAP_TRANS: - case PNG_CMAP_GA: - /* Output must be two channels and the 'G' one must be sRGB, the latter - * can be checked with an exact number because it should have been set - * to this number above! - */ - if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && - info_ptr->bit_depth == 8 && - png_ptr->screen_gamma == PNG_GAMMA_sRGB && - image->colormap_entries == 256) - break; - - goto bad_output; - - case PNG_CMAP_RGB: - /* Output must be 8-bit sRGB encoded RGB */ - if (info_ptr->color_type == PNG_COLOR_TYPE_RGB && - info_ptr->bit_depth == 8 && - png_ptr->screen_gamma == PNG_GAMMA_sRGB && - image->colormap_entries == 216) - break; - - goto bad_output; - - case PNG_CMAP_RGB_ALPHA: - /* Output must be 8-bit sRGB encoded RGBA */ - if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA && - info_ptr->bit_depth == 8 && - png_ptr->screen_gamma == PNG_GAMMA_sRGB && - image->colormap_entries == 244 /* 216 + 1 + 27 */) - break; - - goto bad_output; - - default: - bad_output: - png_error(png_ptr, "bad color-map processing (internal error)"); - } - - /* Now read the rows. Do this here if it is possible to read directly into - * the output buffer, otherwise allocate a local row buffer of the maximum - * size libpng requires and call the relevant processing routine safely. - */ - { - png_voidp first_row = display->buffer; - ptrdiff_t row_bytes = display->row_stride; - - /* The following expression is designed to work correctly whether it gives - * a signed or an unsigned result. - */ - if (row_bytes < 0) - { - char *ptr = png_voidcast(char*, first_row); - ptr += (image->height-1) * (-row_bytes); - first_row = png_voidcast(png_voidp, ptr); - } - - display->first_row = first_row; - display->row_bytes = row_bytes; - } - - if (passes == 0) - { - int result; - png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); - - display->local_row = row; - result = png_safe_execute(image, png_image_read_and_map, display); - display->local_row = NULL; - png_free(png_ptr, row); - - return result; - } - - else - { - png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes; - - while (--passes >= 0) - { - png_uint_32 y = image->height; - png_bytep row = png_voidcast(png_bytep, display->first_row); - - for (; y > 0; --y) - { - png_read_row(png_ptr, row, NULL); - row += row_bytes; - } - } - - return 1; - } -} - -/* Just the row reading part of png_image_read. */ -static int -png_image_read_composite(png_voidp argument) -{ - png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - int passes; - - switch (png_ptr->interlaced) - { - case PNG_INTERLACE_NONE: - passes = 1; - break; - - case PNG_INTERLACE_ADAM7: - passes = PNG_INTERLACE_ADAM7_PASSES; - break; - - default: - png_error(png_ptr, "unknown interlace type"); - } - - { - png_uint_32 height = image->height; - png_uint_32 width = image->width; - ptrdiff_t step_row = display->row_bytes; - unsigned int channels = - (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; - int pass; - - for (pass = 0; pass < passes; ++pass) - { - unsigned int startx, stepx, stepy; - png_uint_32 y; - - if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) - { - /* The row may be empty for a short image: */ - if (PNG_PASS_COLS(width, pass) == 0) - continue; - - startx = PNG_PASS_START_COL(pass) * channels; - stepx = PNG_PASS_COL_OFFSET(pass) * channels; - y = PNG_PASS_START_ROW(pass); - stepy = PNG_PASS_ROW_OFFSET(pass); - } - - else - { - y = 0; - startx = 0; - stepx = channels; - stepy = 1; - } - - for (; ylocal_row); - png_bytep outrow; - png_const_bytep end_row; - - /* Read the row, which is packed: */ - png_read_row(png_ptr, inrow, NULL); - - outrow = png_voidcast(png_bytep, display->first_row); - outrow += y * step_row; - end_row = outrow + width * channels; - - /* Now do the composition on each pixel in this row. */ - outrow += startx; - for (; outrow < end_row; outrow += stepx) - { - png_byte alpha = inrow[channels]; - - if (alpha > 0) /* else no change to the output */ - { - unsigned int c; - - for (c=0; cimage; - png_structrp png_ptr = image->opaque->png_ptr; - png_inforp info_ptr = image->opaque->info_ptr; - png_uint_32 height = image->height; - png_uint_32 width = image->width; - int pass, passes; - - /* Double check the convoluted logic below. We expect to get here with - * libpng doing rgb to gray and gamma correction but background processing - * left to the png_image_read_background function. The rows libpng produce - * might be 8 or 16-bit but should always have two channels; gray plus alpha. - */ - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) - png_error(png_ptr, "lost rgb to gray"); - - if ((png_ptr->transformations & PNG_COMPOSE) != 0) - png_error(png_ptr, "unexpected compose"); - - if (png_get_channels(png_ptr, info_ptr) != 2) - png_error(png_ptr, "lost/gained channels"); - - /* Expect the 8-bit case to always remove the alpha channel */ - if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 && - (image->format & PNG_FORMAT_FLAG_ALPHA) != 0) - png_error(png_ptr, "unexpected 8-bit transformation"); - - switch (png_ptr->interlaced) - { - case PNG_INTERLACE_NONE: - passes = 1; - break; - - case PNG_INTERLACE_ADAM7: - passes = PNG_INTERLACE_ADAM7_PASSES; - break; - - default: - png_error(png_ptr, "unknown interlace type"); - } - - /* Use direct access to info_ptr here because otherwise the simplified API - * would require PNG_EASY_ACCESS_SUPPORTED (just for this.) Note this is - * checking the value after libpng expansions, not the original value in the - * PNG. - */ - switch (info_ptr->bit_depth) - { - case 8: - /* 8-bit sRGB gray values with an alpha channel; the alpha channel is - * to be removed by composing on a background: either the row if - * display->background is NULL or display->background->green if not. - * Unlike the code above ALPHA_OPTIMIZED has *not* been done. - */ - { - png_bytep first_row = png_voidcast(png_bytep, display->first_row); - ptrdiff_t step_row = display->row_bytes; - - for (pass = 0; pass < passes; ++pass) - { - png_bytep row = png_voidcast(png_bytep, display->first_row); - unsigned int startx, stepx, stepy; - png_uint_32 y; - - if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) - { - /* The row may be empty for a short image: */ - if (PNG_PASS_COLS(width, pass) == 0) - continue; - - startx = PNG_PASS_START_COL(pass); - stepx = PNG_PASS_COL_OFFSET(pass); - y = PNG_PASS_START_ROW(pass); - stepy = PNG_PASS_ROW_OFFSET(pass); - } - - else - { - y = 0; - startx = 0; - stepx = stepy = 1; - } - - if (display->background == NULL) - { - for (; ylocal_row); - png_bytep outrow = first_row + y * step_row; - png_const_bytep end_row = outrow + width; - - /* Read the row, which is packed: */ - png_read_row(png_ptr, inrow, NULL); - - /* Now do the composition on each pixel in this row. */ - outrow += startx; - for (; outrow < end_row; outrow += stepx) - { - png_byte alpha = inrow[1]; - - if (alpha > 0) /* else no change to the output */ - { - png_uint_32 component = inrow[0]; - - if (alpha < 255) /* else just use component */ - { - /* Since PNG_OPTIMIZED_ALPHA was not set it is - * necessary to invert the sRGB transfer - * function and multiply the alpha out. - */ - component = png_sRGB_table[component] * alpha; - component += png_sRGB_table[outrow[0]] * - (255-alpha); - component = PNG_sRGB_FROM_LINEAR(component); - } - - outrow[0] = (png_byte)component; - } - - inrow += 2; /* gray and alpha channel */ - } - } - } - - else /* constant background value */ - { - png_byte background8 = display->background->green; - png_uint_16 background = png_sRGB_table[background8]; - - for (; ylocal_row); - png_bytep outrow = first_row + y * step_row; - png_const_bytep end_row = outrow + width; - - /* Read the row, which is packed: */ - png_read_row(png_ptr, inrow, NULL); - - /* Now do the composition on each pixel in this row. */ - outrow += startx; - for (; outrow < end_row; outrow += stepx) - { - png_byte alpha = inrow[1]; - - if (alpha > 0) /* else use background */ - { - png_uint_32 component = inrow[0]; - - if (alpha < 255) /* else just use component */ - { - component = png_sRGB_table[component] * alpha; - component += background * (255-alpha); - component = PNG_sRGB_FROM_LINEAR(component); - } - - outrow[0] = (png_byte)component; - } - - else - outrow[0] = background8; - - inrow += 2; /* gray and alpha channel */ - } - - row += display->row_bytes; - } - } - } - } - break; - - case 16: - /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must - * still be done and, maybe, the alpha channel removed. This code also - * handles the alpha-first option. - */ - { - png_uint_16p first_row = png_voidcast(png_uint_16p, - display->first_row); - /* The division by two is safe because the caller passed in a - * stride which was multiplied by 2 (below) to get row_bytes. - */ - ptrdiff_t step_row = display->row_bytes / 2; - unsigned int preserve_alpha = (image->format & - PNG_FORMAT_FLAG_ALPHA) != 0; - unsigned int outchannels = 1U+preserve_alpha; - int swap_alpha = 0; - -# ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED - if (preserve_alpha != 0 && - (image->format & PNG_FORMAT_FLAG_AFIRST) != 0) - swap_alpha = 1; -# endif - - for (pass = 0; pass < passes; ++pass) - { - unsigned int startx, stepx, stepy; - png_uint_32 y; - - /* The 'x' start and step are adjusted to output components here. - */ - if (png_ptr->interlaced == PNG_INTERLACE_ADAM7) - { - /* The row may be empty for a short image: */ - if (PNG_PASS_COLS(width, pass) == 0) - continue; - - startx = PNG_PASS_START_COL(pass) * outchannels; - stepx = PNG_PASS_COL_OFFSET(pass) * outchannels; - y = PNG_PASS_START_ROW(pass); - stepy = PNG_PASS_ROW_OFFSET(pass); - } - - else - { - y = 0; - startx = 0; - stepx = outchannels; - stepy = 1; - } - - for (; ylocal_row), NULL); - inrow = png_voidcast(png_const_uint_16p, display->local_row); - - /* Now do the pre-multiplication on each pixel in this row. - */ - outrow += startx; - for (; outrow < end_row; outrow += stepx) - { - png_uint_32 component = inrow[0]; - png_uint_16 alpha = inrow[1]; - - if (alpha > 0) /* else 0 */ - { - if (alpha < 65535) /* else just use component */ - { - component *= alpha; - component += 32767; - component /= 65535; - } - } - - else - component = 0; - - outrow[swap_alpha] = (png_uint_16)component; - if (preserve_alpha != 0) - outrow[1 ^ swap_alpha] = alpha; - - inrow += 2; /* components and alpha channel */ - } - } - } - } - break; - -#ifdef __GNUC__ - default: - png_error(png_ptr, "unexpected bit depth"); -#endif - } - - return 1; -} - -/* The guts of png_image_finish_read as a png_safe_execute callback. */ -static int -png_image_read_direct(png_voidp argument) -{ - png_image_read_control *display = png_voidcast(png_image_read_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - png_inforp info_ptr = image->opaque->info_ptr; - - png_uint_32 format = image->format; - int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0; - int do_local_compose = 0; - int do_local_background = 0; /* to avoid double gamma correction bug */ - int passes = 0; - - /* Add transforms to ensure the correct output format is produced then check - * that the required implementation support is there. Always expand; always - * need 8 bits minimum, no palette and expanded tRNS. - */ - png_set_expand(png_ptr); - - /* Now check the format to see if it was modified. */ - { - png_uint_32 base_format = png_image_format(png_ptr) & - ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */; - png_uint_32 change = format ^ base_format; - png_fixed_point output_gamma; - int mode; /* alpha mode */ - - /* Do this first so that we have a record if rgb to gray is happening. */ - if ((change & PNG_FORMAT_FLAG_COLOR) != 0) - { - /* gray<->color transformation required. */ - if ((format & PNG_FORMAT_FLAG_COLOR) != 0) - png_set_gray_to_rgb(png_ptr); - - else - { - /* libpng can't do both rgb to gray and - * background/pre-multiplication if there is also significant gamma - * correction, because both operations require linear colors and - * the code only supports one transform doing the gamma correction. - * Handle this by doing the pre-multiplication or background - * operation in this code, if necessary. - * - * TODO: fix this by rewriting pngrtran.c (!) - * - * For the moment (given that fixing this in pngrtran.c is an - * enormous change) 'do_local_background' is used to indicate that - * the problem exists. - */ - if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) - do_local_background = 1/*maybe*/; - - png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, - PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT); - } - - change &= ~PNG_FORMAT_FLAG_COLOR; - } - - /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise. - */ - { - png_fixed_point input_gamma_default; - - if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 && - (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0) - input_gamma_default = PNG_GAMMA_LINEAR; - else - input_gamma_default = PNG_DEFAULT_sRGB; - - /* Call png_set_alpha_mode to set the default for the input gamma; the - * output gamma is set by a second call below. - */ - png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default); - } - - if (linear != 0) - { - /* If there *is* an alpha channel in the input it must be multiplied - * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG. - */ - if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) - mode = PNG_ALPHA_STANDARD; /* associated alpha */ - - else - mode = PNG_ALPHA_PNG; - - output_gamma = PNG_GAMMA_LINEAR; - } - - else - { - mode = PNG_ALPHA_PNG; - output_gamma = PNG_DEFAULT_sRGB; - } - - if ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) - { - mode = PNG_ALPHA_OPTIMIZED; - change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA; - } - - /* If 'do_local_background' is set check for the presence of gamma - * correction; this is part of the work-round for the libpng bug - * described above. - * - * TODO: fix libpng and remove this. - */ - if (do_local_background != 0) - { - png_fixed_point gtest; - - /* This is 'png_gamma_threshold' from pngrtran.c; the test used for - * gamma correction, the screen gamma hasn't been set on png_struct - * yet; it's set below. png_struct::gamma, however, is set to the - * final value. - */ - if (png_muldiv(>est, output_gamma, png_ptr->colorspace.gamma, - PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0) - do_local_background = 0; - - else if (mode == PNG_ALPHA_STANDARD) - { - do_local_background = 2/*required*/; - mode = PNG_ALPHA_PNG; /* prevent libpng doing it */ - } - - /* else leave as 1 for the checks below */ - } - - /* If the bit-depth changes then handle that here. */ - if ((change & PNG_FORMAT_FLAG_LINEAR) != 0) - { - if (linear != 0 /*16-bit output*/) - png_set_expand_16(png_ptr); - - else /* 8-bit output */ - png_set_scale_16(png_ptr); - - change &= ~PNG_FORMAT_FLAG_LINEAR; - } - - /* Now the background/alpha channel changes. */ - if ((change & PNG_FORMAT_FLAG_ALPHA) != 0) - { - /* Removing an alpha channel requires composition for the 8-bit - * formats; for the 16-bit it is already done, above, by the - * pre-multiplication and the channel just needs to be stripped. - */ - if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - /* If RGB->gray is happening the alpha channel must be left and the - * operation completed locally. - * - * TODO: fix libpng and remove this. - */ - if (do_local_background != 0) - do_local_background = 2/*required*/; - - /* 16-bit output: just remove the channel */ - else if (linear != 0) /* compose on black (well, pre-multiply) */ - png_set_strip_alpha(png_ptr); - - /* 8-bit output: do an appropriate compose */ - else if (display->background != NULL) - { - png_color_16 c; - - c.index = 0; /*unused*/ - c.red = display->background->red; - c.green = display->background->green; - c.blue = display->background->blue; - c.gray = display->background->green; - - /* This is always an 8-bit sRGB value, using the 'green' channel - * for gray is much better than calculating the luminance here; - * we can get off-by-one errors in that calculation relative to - * the app expectations and that will show up in transparent - * pixels. - */ - png_set_background_fixed(png_ptr, &c, - PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/, - 0/*gamma: not used*/); - } - - else /* compose on row: implemented below. */ - { - do_local_compose = 1; - /* This leaves the alpha channel in the output, so it has to be - * removed by the code below. Set the encoding to the 'OPTIMIZE' - * one so the code only has to hack on the pixels that require - * composition. - */ - mode = PNG_ALPHA_OPTIMIZED; - } - } - - else /* output needs an alpha channel */ - { - /* This is tricky because it happens before the swap operation has - * been accomplished; however, the swap does *not* swap the added - * alpha channel (weird API), so it must be added in the correct - * place. - */ - png_uint_32 filler; /* opaque filler */ - int where; - - if (linear != 0) - filler = 65535; - - else - filler = 255; - -#ifdef PNG_FORMAT_AFIRST_SUPPORTED - if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - where = PNG_FILLER_BEFORE; - change &= ~PNG_FORMAT_FLAG_AFIRST; - } - - else -#endif - where = PNG_FILLER_AFTER; - - png_set_add_alpha(png_ptr, filler, where); - } - - /* This stops the (irrelevant) call to swap_alpha below. */ - change &= ~PNG_FORMAT_FLAG_ALPHA; - } - - /* Now set the alpha mode correctly; this is always done, even if there is - * no alpha channel in either the input or the output because it correctly - * sets the output gamma. - */ - png_set_alpha_mode_fixed(png_ptr, mode, output_gamma); - -# ifdef PNG_FORMAT_BGR_SUPPORTED - if ((change & PNG_FORMAT_FLAG_BGR) != 0) - { - /* Check only the output format; PNG is never BGR; don't do this if - * the output is gray, but fix up the 'format' value in that case. - */ - if ((format & PNG_FORMAT_FLAG_COLOR) != 0) - png_set_bgr(png_ptr); - - else - format &= ~PNG_FORMAT_FLAG_BGR; - - change &= ~PNG_FORMAT_FLAG_BGR; - } -# endif - -# ifdef PNG_FORMAT_AFIRST_SUPPORTED - if ((change & PNG_FORMAT_FLAG_AFIRST) != 0) - { - /* Only relevant if there is an alpha channel - it's particularly - * important to handle this correctly because do_local_compose may - * be set above and then libpng will keep the alpha channel for this - * code to remove. - */ - if ((format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - /* Disable this if doing a local background, - * TODO: remove this when local background is no longer required. - */ - if (do_local_background != 2) - png_set_swap_alpha(png_ptr); - } - - else - format &= ~PNG_FORMAT_FLAG_AFIRST; - - change &= ~PNG_FORMAT_FLAG_AFIRST; - } -# endif - - /* If the *output* is 16-bit then we need to check for a byte-swap on this - * architecture. - */ - if (linear != 0) - { - png_uint_16 le = 0x0001; - - if ((*(png_const_bytep) & le) != 0) - png_set_swap(png_ptr); - } - - /* If change is not now 0 some transformation is missing - error out. */ - if (change != 0) - png_error(png_ptr, "png_read_image: unsupported transformation"); - } - - PNG_SKIP_CHUNKS(png_ptr); - - /* Update the 'info' structure and make sure the result is as required; first - * make sure to turn on the interlace handling if it will be required - * (because it can't be turned on *after* the call to png_read_update_info!) - * - * TODO: remove the do_local_background fixup below. - */ - if (do_local_compose == 0 && do_local_background != 2) - passes = png_set_interlace_handling(png_ptr); - - png_read_update_info(png_ptr, info_ptr); - - { - png_uint_32 info_format = 0; - - if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - info_format |= PNG_FORMAT_FLAG_COLOR; - - if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - /* do_local_compose removes this channel below. */ - if (do_local_compose == 0) - { - /* do_local_background does the same if required. */ - if (do_local_background != 2 || - (format & PNG_FORMAT_FLAG_ALPHA) != 0) - info_format |= PNG_FORMAT_FLAG_ALPHA; - } - } - - else if (do_local_compose != 0) /* internal error */ - png_error(png_ptr, "png_image_read: alpha channel lost"); - - if ((format & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) { - info_format |= PNG_FORMAT_FLAG_ASSOCIATED_ALPHA; - } - - if (info_ptr->bit_depth == 16) - info_format |= PNG_FORMAT_FLAG_LINEAR; - -#ifdef PNG_FORMAT_BGR_SUPPORTED - if ((png_ptr->transformations & PNG_BGR) != 0) - info_format |= PNG_FORMAT_FLAG_BGR; -#endif - -#ifdef PNG_FORMAT_AFIRST_SUPPORTED - if (do_local_background == 2) - { - if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) - info_format |= PNG_FORMAT_FLAG_AFIRST; - } - - if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 || - ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 && - (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0)) - { - if (do_local_background == 2) - png_error(png_ptr, "unexpected alpha swap transformation"); - - info_format |= PNG_FORMAT_FLAG_AFIRST; - } -# endif - - /* This is actually an internal error. */ - if (info_format != format) - png_error(png_ptr, "png_read_image: invalid transformations"); - } - - /* Now read the rows. If do_local_compose is set then it is necessary to use - * a local row buffer. The output will be GA, RGBA or BGRA and must be - * converted to G, RGB or BGR as appropriate. The 'local_row' member of the - * display acts as a flag. - */ - { - png_voidp first_row = display->buffer; - ptrdiff_t row_bytes = display->row_stride; - - if (linear != 0) - row_bytes *= 2; - - /* The following expression is designed to work correctly whether it gives - * a signed or an unsigned result. - */ - if (row_bytes < 0) - { - char *ptr = png_voidcast(char*, first_row); - ptr += (image->height-1) * (-row_bytes); - first_row = png_voidcast(png_voidp, ptr); - } - - display->first_row = first_row; - display->row_bytes = row_bytes; - } - - if (do_local_compose != 0) - { - int result; - png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); - - display->local_row = row; - result = png_safe_execute(image, png_image_read_composite, display); - display->local_row = NULL; - png_free(png_ptr, row); - - return result; - } - - else if (do_local_background == 2) - { - int result; - png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); - - display->local_row = row; - result = png_safe_execute(image, png_image_read_background, display); - display->local_row = NULL; - png_free(png_ptr, row); - - return result; - } - - else - { - png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes; - - while (--passes >= 0) - { - png_uint_32 y = image->height; - png_bytep row = png_voidcast(png_bytep, display->first_row); - - for (; y > 0; --y) - { - png_read_row(png_ptr, row, NULL); - row += row_bytes; - } - } - - return 1; - } -} - -int PNGAPI -png_image_finish_read(png_imagep image, png_const_colorp background, - void *buffer, png_int_32 row_stride, void *colormap) -{ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - /* Check for row_stride overflow. This check is not performed on the - * original PNG format because it may not occur in the output PNG format - * and libpng deals with the issues of reading the original. - */ - unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); - - /* The following checks just the 'row_stride' calculation to ensure it - * fits in a signed 32-bit value. Because channels/components can be - * either 1 or 2 bytes in size the length of a row can still overflow 32 - * bits; this is just to verify that the 'row_stride' argument can be - * represented. - */ - if (image->width <= 0x7fffffffU/channels) /* no overflow */ - { - png_uint_32 check; - png_uint_32 png_row_stride = image->width * channels; - - if (row_stride == 0) - row_stride = (png_int_32)/*SAFE*/png_row_stride; - - if (row_stride < 0) - check = (png_uint_32)(-row_stride); - - else - check = (png_uint_32)row_stride; - - /* This verifies 'check', the absolute value of the actual stride - * passed in and detects overflow in the application calculation (i.e. - * if the app did actually pass in a non-zero 'row_stride'. - */ - if (image->opaque != NULL && buffer != NULL && check >= png_row_stride) - { - /* Now check for overflow of the image buffer calculation; this - * limits the whole image size to 32 bits for API compatibility with - * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro. - * - * The PNG_IMAGE_BUFFER_SIZE macro is: - * - * (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride)) - * - * And the component size is always 1 or 2, so make sure that the - * number of *bytes* that the application is saying are available - * does actually fit into a 32-bit number. - * - * NOTE: this will be changed in 1.7 because PNG_IMAGE_BUFFER_SIZE - * will be changed to use png_alloc_size_t; bigger images can be - * accommodated on 64-bit systems. - */ - if (image->height <= - 0xffffffffU/PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format)/check) - { - if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 || - (image->colormap_entries > 0 && colormap != NULL)) - { - int result; - png_image_read_control display; - - memset(&display, 0, (sizeof display)); - display.image = image; - display.buffer = buffer; - display.row_stride = row_stride; - display.colormap = colormap; - display.background = background; - display.local_row = NULL; - - /* Choose the correct 'end' routine; for the color-map case - * all the setup has already been done. - */ - if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0) - result = - png_safe_execute(image, - png_image_read_colormap, &display) && - png_safe_execute(image, - png_image_read_colormapped, &display); - - else - result = - png_safe_execute(image, - png_image_read_direct, &display); - - png_image_free(image); - return result; - } - - else - return png_image_error(image, - "png_image_finish_read[color-map]: no color-map"); - } - - else - return png_image_error(image, - "png_image_finish_read: image too large"); - } - - else - return png_image_error(image, - "png_image_finish_read: invalid argument"); - } - - else - return png_image_error(image, - "png_image_finish_read: row_stride too large"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_finish_read: damaged PNG_IMAGE_VERSION"); - - return 0; -} - -#endif /* SIMPLIFIED_READ */ -#endif /* READ */ diff --git a/extern/libpng/pngrio.c b/extern/libpng/pngrio.c deleted file mode 100644 index 794635810..000000000 --- a/extern/libpng/pngrio.c +++ /dev/null @@ -1,120 +0,0 @@ - -/* pngrio.c - functions for data input - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all input. Users who need - * special handling are expected to write a function that has the same - * arguments as this and performs a similar function, but that possibly - * has a different input method. Note that you shouldn't change this - * function, but rather write a replacement function and then make - * libpng use it at run time with png_set_read_fn(...). - */ - -#include "pngpriv.h" - -#ifdef PNG_READ_SUPPORTED - -/* Read the data from whatever input you are using. The default routine - * reads from a file pointer. Note that this routine sometimes gets called - * with very small lengths, so you should implement some kind of simple - * buffering if you are using unbuffered reads. This should never be asked - * to read more than 64K on a 16-bit machine. - */ -void /* PRIVATE */ -png_read_data(png_structrp png_ptr, png_bytep data, size_t length) -{ - png_debug1(4, "reading %d bytes", (int)length); - - if (png_ptr->read_data_fn != NULL) - (*(png_ptr->read_data_fn))(png_ptr, data, length); - - else - png_error(png_ptr, "Call to NULL read function"); -} - -#ifdef PNG_STDIO_SUPPORTED -/* This is the function that does the actual reading of data. If you are - * not reading from a standard C stream, you should create a replacement - * read_data function and use it at run time with png_set_read_fn(), rather - * than changing the library. - */ -void PNGCBAPI -png_default_read_data(png_structp png_ptr, png_bytep data, size_t length) -{ - size_t check; - - if (png_ptr == NULL) - return; - - /* fread() returns 0 on error, so it is OK to store this in a size_t - * instead of an int, which is what fread() actually returns. - */ - check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr)); - - if (check != length) - png_error(png_ptr, "Read Error"); -} -#endif - -/* This function allows the application to supply a new input function - * for libpng if standard C streams aren't being used. - * - * This function takes as its arguments: - * - * png_ptr - pointer to a png input data structure - * - * io_ptr - pointer to user supplied structure containing info about - * the input functions. May be NULL. - * - * read_data_fn - pointer to a new input function that takes as its - * arguments a pointer to a png_struct, a pointer to - * a location where input data can be stored, and a 32-bit - * unsigned int that is the number of bytes to be read. - * To exit and output any fatal error messages the new write - * function should call png_error(png_ptr, "Error msg"). - * May be NULL, in which case libpng's default function will - * be used. - */ -void PNGAPI -png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr read_data_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->io_ptr = io_ptr; - -#ifdef PNG_STDIO_SUPPORTED - if (read_data_fn != NULL) - png_ptr->read_data_fn = read_data_fn; - - else - png_ptr->read_data_fn = png_default_read_data; -#else - png_ptr->read_data_fn = read_data_fn; -#endif - -#ifdef PNG_WRITE_SUPPORTED - /* It is an error to write to a read device */ - if (png_ptr->write_data_fn != NULL) - { - png_ptr->write_data_fn = NULL; - png_warning(png_ptr, - "Can't set both read_data_fn and write_data_fn in the" - " same structure"); - } -#endif - -#ifdef PNG_WRITE_FLUSH_SUPPORTED - png_ptr->output_flush_fn = NULL; -#endif -} -#endif /* READ */ diff --git a/extern/libpng/pngrtran.c b/extern/libpng/pngrtran.c deleted file mode 100644 index 9a8fad9f4..000000000 --- a/extern/libpng/pngrtran.c +++ /dev/null @@ -1,5044 +0,0 @@ - -/* pngrtran.c - transforms the data in a row for PNG readers - * - * Copyright (c) 2018-2019 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file contains functions optionally called by an application - * in order to tell libpng how to handle data when reading a PNG. - * Transformations that are used in both reading and writing are - * in pngtrans.c. - */ - -#include "pngpriv.h" - -#ifdef PNG_ARM_NEON_IMPLEMENTATION -# if PNG_ARM_NEON_IMPLEMENTATION == 1 -# define PNG_ARM_NEON_INTRINSICS_AVAILABLE -# if defined(_MSC_VER) && defined(_M_ARM64) -# include -# else -# include -# endif -# endif -#endif - -#ifdef PNG_READ_SUPPORTED - -/* Set the action on getting a CRC error for an ancillary or critical chunk. */ -void PNGAPI -png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action) -{ - png_debug(1, "in png_set_crc_action"); - - if (png_ptr == NULL) - return; - - /* Tell libpng how we react to CRC errors in critical chunks */ - switch (crit_action) - { - case PNG_CRC_NO_CHANGE: /* Leave setting as is */ - break; - - case PNG_CRC_WARN_USE: /* Warn/use data */ - png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; - png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE; - break; - - case PNG_CRC_QUIET_USE: /* Quiet/use data */ - png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; - png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE | - PNG_FLAG_CRC_CRITICAL_IGNORE; - break; - - case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ - png_warning(png_ptr, - "Can't discard critical data on CRC error"); - /* FALLTHROUGH */ - case PNG_CRC_ERROR_QUIT: /* Error/quit */ - - case PNG_CRC_DEFAULT: - default: - png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; - break; - } - - /* Tell libpng how we react to CRC errors in ancillary chunks */ - switch (ancil_action) - { - case PNG_CRC_NO_CHANGE: /* Leave setting as is */ - break; - - case PNG_CRC_WARN_USE: /* Warn/use data */ - png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; - png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE; - break; - - case PNG_CRC_QUIET_USE: /* Quiet/use data */ - png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; - png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE | - PNG_FLAG_CRC_ANCILLARY_NOWARN; - break; - - case PNG_CRC_ERROR_QUIT: /* Error/quit */ - png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; - png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN; - break; - - case PNG_CRC_WARN_DISCARD: /* Warn/discard data */ - - case PNG_CRC_DEFAULT: - default: - png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; - break; - } -} - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -/* Is it OK to set a transformation now? Only if png_start_read_image or - * png_read_update_info have not been called. It is not necessary for the IHDR - * to have been read in all cases; the need_IHDR parameter allows for this - * check too. - */ -static int -png_rtran_ok(png_structrp png_ptr, int need_IHDR) -{ - if (png_ptr != NULL) - { - if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) - png_app_error(png_ptr, - "invalid after png_start_read_image or png_read_update_info"); - - else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_app_error(png_ptr, "invalid before the PNG header has been read"); - - else - { - /* Turn on failure to initialize correctly for all transforms. */ - png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED; - - return 1; /* Ok */ - } - } - - return 0; /* no png_error possible! */ -} -#endif - -#ifdef PNG_READ_BACKGROUND_SUPPORTED -/* Handle alpha and tRNS via a background color */ -void PNGFAPI -png_set_background_fixed(png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, png_fixed_point background_gamma) -{ - png_debug(1, "in png_set_background_fixed"); - - if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL) - return; - - if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) - { - png_warning(png_ptr, "Application must supply a known background gamma"); - return; - } - - png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA; - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - - png_ptr->background = *background_color; - png_ptr->background_gamma = background_gamma; - png_ptr->background_gamma_type = (png_byte)(background_gamma_code); - if (need_expand != 0) - png_ptr->transformations |= PNG_BACKGROUND_EXPAND; - else - png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_background(png_structrp png_ptr, - png_const_color_16p background_color, int background_gamma_code, - int need_expand, double background_gamma) -{ - png_set_background_fixed(png_ptr, background_color, background_gamma_code, - need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); -} -# endif /* FLOATING_POINT */ -#endif /* READ_BACKGROUND */ - -/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the - * one that pngrtran does first (scale) happens. This is necessary to allow the - * TRANSFORM and API behavior to be somewhat consistent, and it's simpler. - */ -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -void PNGAPI -png_set_scale_16(png_structrp png_ptr) -{ - png_debug(1, "in png_set_scale_16"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_SCALE_16_TO_8; -} -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -/* Chop 16-bit depth files to 8-bit depth */ -void PNGAPI -png_set_strip_16(png_structrp png_ptr) -{ - png_debug(1, "in png_set_strip_16"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_16_TO_8; -} -#endif - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -void PNGAPI -png_set_strip_alpha(png_structrp png_ptr) -{ - png_debug(1, "in png_set_strip_alpha"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_STRIP_ALPHA; -} -#endif - -#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) -static png_fixed_point -translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma, - int is_screen) -{ - /* Check for flag values. The main reason for having the old Mac value as a - * flag is that it is pretty near impossible to work out what the correct - * value is from Apple documentation - a working Mac system is needed to - * discover the value! - */ - if (output_gamma == PNG_DEFAULT_sRGB || - output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB) - { - /* If there is no sRGB support this just sets the gamma to the standard - * sRGB value. (This is a side effect of using this function!) - */ -# ifdef PNG_READ_sRGB_SUPPORTED - png_ptr->flags |= PNG_FLAG_ASSUME_sRGB; -# else - PNG_UNUSED(png_ptr) -# endif - if (is_screen != 0) - output_gamma = PNG_GAMMA_sRGB; - else - output_gamma = PNG_GAMMA_sRGB_INVERSE; - } - - else if (output_gamma == PNG_GAMMA_MAC_18 || - output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18) - { - if (is_screen != 0) - output_gamma = PNG_GAMMA_MAC_OLD; - else - output_gamma = PNG_GAMMA_MAC_INVERSE; - } - - return output_gamma; -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -static png_fixed_point -convert_gamma_value(png_structrp png_ptr, double output_gamma) -{ - /* The following silently ignores cases where fixed point (times 100,000) - * gamma values are passed to the floating point API. This is safe and it - * means the fixed point constants work just fine with the floating point - * API. The alternative would just lead to undetected errors and spurious - * bug reports. Negative values fail inside the _fixed API unless they - * correspond to the flag values. - */ - if (output_gamma > 0 && output_gamma < 128) - output_gamma *= PNG_FP_1; - - /* This preserves -1 and -2 exactly: */ - output_gamma = floor(output_gamma + .5); - - if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN) - png_fixed_error(png_ptr, "gamma value"); - - return (png_fixed_point)output_gamma; -} -# endif -#endif /* READ_ALPHA_MODE || READ_GAMMA */ - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -void PNGFAPI -png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, - png_fixed_point output_gamma) -{ - int compose = 0; - png_fixed_point file_gamma; - - png_debug(1, "in png_set_alpha_mode"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); - - /* Validate the value to ensure it is in a reasonable range. The value - * is expected to be 1 or greater, but this range test allows for some - * viewing correction values. The intent is to weed out users of this API - * who use the inverse of the gamma value accidentally! Since some of these - * values are reasonable this may have to be changed: - * - * 1.6.x: changed from 0.07..3 to 0.01..100 (to accommodate the optimal 16-bit - * gamma of 36, and its reciprocal.) - */ - if (output_gamma < 1000 || output_gamma > 10000000) - png_error(png_ptr, "output gamma out of expected range"); - - /* The default file gamma is the inverse of the output gamma; the output - * gamma may be changed below so get the file value first: - */ - file_gamma = png_reciprocal(output_gamma); - - /* There are really 8 possibilities here, composed of any combination - * of: - * - * premultiply the color channels - * do not encode non-opaque pixels - * encode the alpha as well as the color channels - * - * The differences disappear if the input/output ('screen') gamma is 1.0, - * because then the encoding is a no-op and there is only the choice of - * premultiplying the color channels or not. - * - * png_set_alpha_mode and png_set_background interact because both use - * png_compose to do the work. Calling both is only useful when - * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along - * with a default gamma value. Otherwise PNG_COMPOSE must not be set. - */ - switch (mode) - { - case PNG_ALPHA_PNG: /* default: png standard */ - /* No compose, but it may be set by png_set_background! */ - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - break; - - case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */ - compose = 1; - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - /* The output is linear: */ - output_gamma = PNG_FP_1; - break; - - case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */ - compose = 1; - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA; - /* output_gamma records the encoding of opaque pixels! */ - break; - - case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */ - compose = 1; - png_ptr->transformations |= PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - break; - - default: - png_error(png_ptr, "invalid alpha mode"); - } - - /* Only set the default gamma if the file gamma has not been set (this has - * the side effect that the gamma in a second call to png_set_alpha_mode will - * be ignored.) - */ - if (png_ptr->colorspace.gamma == 0) - { - png_ptr->colorspace.gamma = file_gamma; - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - } - - /* But always set the output gamma: */ - png_ptr->screen_gamma = output_gamma; - - /* Finally, if pre-multiplying, set the background fields to achieve the - * desired result. - */ - if (compose != 0) - { - /* And obtain alpha pre-multiplication by composing on black: */ - memset(&png_ptr->background, 0, (sizeof png_ptr->background)); - png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */ - png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE; - png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND; - - if ((png_ptr->transformations & PNG_COMPOSE) != 0) - png_error(png_ptr, - "conflicting calls to set alpha mode and background"); - - png_ptr->transformations |= PNG_COMPOSE; - } -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma) -{ - png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr, - output_gamma)); -} -# endif -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -/* Dither file to 8-bit. Supply a palette, the current number - * of elements in the palette, the maximum number of elements - * allowed, and a histogram if possible. If the current number - * of colors is greater than the maximum number, the palette will be - * modified to fit in the maximum number. "full_quantize" indicates - * whether we need a quantizing cube set up for RGB images, or if we - * simply are reducing the number of colors in a paletted image. - */ - -typedef struct png_dsort_struct -{ - struct png_dsort_struct * next; - png_byte left; - png_byte right; -} png_dsort; -typedef png_dsort * png_dsortp; -typedef png_dsort * * png_dsortpp; - -void PNGAPI -png_set_quantize(png_structrp png_ptr, png_colorp palette, - int num_palette, int maximum_colors, png_const_uint_16p histogram, - int full_quantize) -{ - png_debug(1, "in png_set_quantize"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_QUANTIZE; - - if (full_quantize == 0) - { - int i; - - png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte)))); - for (i = 0; i < num_palette; i++) - png_ptr->quantize_index[i] = (png_byte)i; - } - - if (num_palette > maximum_colors) - { - if (histogram != NULL) - { - /* This is easy enough, just throw out the least used colors. - * Perhaps not the best solution, but good enough. - */ - - int i; - - /* Initialize an array to sort colors */ - png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte)))); - - /* Initialize the quantize_sort array */ - for (i = 0; i < num_palette; i++) - png_ptr->quantize_sort[i] = (png_byte)i; - - /* Find the least used palette entries by starting a - * bubble sort, and running it until we have sorted - * out enough colors. Note that we don't care about - * sorting all the colors, just finding which are - * least used. - */ - - for (i = num_palette - 1; i >= maximum_colors; i--) - { - int done; /* To stop early if the list is pre-sorted */ - int j; - - done = 1; - for (j = 0; j < i; j++) - { - if (histogram[png_ptr->quantize_sort[j]] - < histogram[png_ptr->quantize_sort[j + 1]]) - { - png_byte t; - - t = png_ptr->quantize_sort[j]; - png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1]; - png_ptr->quantize_sort[j + 1] = t; - done = 0; - } - } - - if (done != 0) - break; - } - - /* Swap the palette around, and set up a table, if necessary */ - if (full_quantize != 0) - { - int j = num_palette; - - /* Put all the useful colors within the max, but don't - * move the others. - */ - for (i = 0; i < maximum_colors; i++) - { - if ((int)png_ptr->quantize_sort[i] >= maximum_colors) - { - do - j--; - while ((int)png_ptr->quantize_sort[j] >= maximum_colors); - - palette[i] = palette[j]; - } - } - } - else - { - int j = num_palette; - - /* Move all the used colors inside the max limit, and - * develop a translation table. - */ - for (i = 0; i < maximum_colors; i++) - { - /* Only move the colors we need to */ - if ((int)png_ptr->quantize_sort[i] >= maximum_colors) - { - png_color tmp_color; - - do - j--; - while ((int)png_ptr->quantize_sort[j] >= maximum_colors); - - tmp_color = palette[j]; - palette[j] = palette[i]; - palette[i] = tmp_color; - /* Indicate where the color went */ - png_ptr->quantize_index[j] = (png_byte)i; - png_ptr->quantize_index[i] = (png_byte)j; - } - } - - /* Find closest color for those colors we are not using */ - for (i = 0; i < num_palette; i++) - { - if ((int)png_ptr->quantize_index[i] >= maximum_colors) - { - int min_d, k, min_k, d_index; - - /* Find the closest color to one we threw out */ - d_index = png_ptr->quantize_index[i]; - min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); - for (k = 1, min_k = 0; k < maximum_colors; k++) - { - int d; - - d = PNG_COLOR_DIST(palette[d_index], palette[k]); - - if (d < min_d) - { - min_d = d; - min_k = k; - } - } - /* Point to closest color */ - png_ptr->quantize_index[i] = (png_byte)min_k; - } - } - } - png_free(png_ptr, png_ptr->quantize_sort); - png_ptr->quantize_sort = NULL; - } - else - { - /* This is much harder to do simply (and quickly). Perhaps - * we need to go through a median cut routine, but those - * don't always behave themselves with only a few colors - * as input. So we will just find the closest two colors, - * and throw out one of them (chosen somewhat randomly). - * [We don't understand this at all, so if someone wants to - * work on improving it, be our guest - AED, GRP] - */ - int i; - int max_d; - int num_new_palette; - png_dsortp t; - png_dsortpp hash; - - t = NULL; - - /* Initialize palette index arrays */ - png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * - (sizeof (png_byte)))); - png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * - (sizeof (png_byte)))); - - /* Initialize the sort array */ - for (i = 0; i < num_palette; i++) - { - png_ptr->index_to_palette[i] = (png_byte)i; - png_ptr->palette_to_index[i] = (png_byte)i; - } - - hash = (png_dsortpp)png_calloc(png_ptr, (png_alloc_size_t)(769 * - (sizeof (png_dsortp)))); - - num_new_palette = num_palette; - - /* Initial wild guess at how far apart the farthest pixel - * pair we will be eliminating will be. Larger - * numbers mean more areas will be allocated, Smaller - * numbers run the risk of not saving enough data, and - * having to do this all over again. - * - * I have not done extensive checking on this number. - */ - max_d = 96; - - while (num_new_palette > maximum_colors) - { - for (i = 0; i < num_new_palette - 1; i++) - { - int j; - - for (j = i + 1; j < num_new_palette; j++) - { - int d; - - d = PNG_COLOR_DIST(palette[i], palette[j]); - - if (d <= max_d) - { - - t = (png_dsortp)png_malloc_warn(png_ptr, - (png_alloc_size_t)(sizeof (png_dsort))); - - if (t == NULL) - break; - - t->next = hash[d]; - t->left = (png_byte)i; - t->right = (png_byte)j; - hash[d] = t; - } - } - if (t == NULL) - break; - } - - if (t != NULL) - for (i = 0; i <= max_d; i++) - { - if (hash[i] != NULL) - { - png_dsortp p; - - for (p = hash[i]; p; p = p->next) - { - if ((int)png_ptr->index_to_palette[p->left] - < num_new_palette && - (int)png_ptr->index_to_palette[p->right] - < num_new_palette) - { - int j, next_j; - - if (num_new_palette & 0x01) - { - j = p->left; - next_j = p->right; - } - else - { - j = p->right; - next_j = p->left; - } - - num_new_palette--; - palette[png_ptr->index_to_palette[j]] - = palette[num_new_palette]; - if (full_quantize == 0) - { - int k; - - for (k = 0; k < num_palette; k++) - { - if (png_ptr->quantize_index[k] == - png_ptr->index_to_palette[j]) - png_ptr->quantize_index[k] = - png_ptr->index_to_palette[next_j]; - - if ((int)png_ptr->quantize_index[k] == - num_new_palette) - png_ptr->quantize_index[k] = - png_ptr->index_to_palette[j]; - } - } - - png_ptr->index_to_palette[png_ptr->palette_to_index - [num_new_palette]] = png_ptr->index_to_palette[j]; - - png_ptr->palette_to_index[png_ptr->index_to_palette[j]] - = png_ptr->palette_to_index[num_new_palette]; - - png_ptr->index_to_palette[j] = - (png_byte)num_new_palette; - - png_ptr->palette_to_index[num_new_palette] = - (png_byte)j; - } - if (num_new_palette <= maximum_colors) - break; - } - if (num_new_palette <= maximum_colors) - break; - } - } - - for (i = 0; i < 769; i++) - { - if (hash[i] != NULL) - { - png_dsortp p = hash[i]; - while (p) - { - t = p->next; - png_free(png_ptr, p); - p = t; - } - } - hash[i] = 0; - } - max_d += 96; - } - png_free(png_ptr, hash); - png_free(png_ptr, png_ptr->palette_to_index); - png_free(png_ptr, png_ptr->index_to_palette); - png_ptr->palette_to_index = NULL; - png_ptr->index_to_palette = NULL; - } - num_palette = maximum_colors; - } - if (png_ptr->palette == NULL) - { - png_ptr->palette = palette; - } - png_ptr->num_palette = (png_uint_16)num_palette; - - if (full_quantize != 0) - { - int i; - png_bytep distance; - int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS + - PNG_QUANTIZE_BLUE_BITS; - int num_red = (1 << PNG_QUANTIZE_RED_BITS); - int num_green = (1 << PNG_QUANTIZE_GREEN_BITS); - int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS); - size_t num_entries = ((size_t)1 << total_bits); - - png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, - (png_alloc_size_t)(num_entries * (sizeof (png_byte)))); - - distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries * - (sizeof (png_byte)))); - - memset(distance, 0xff, num_entries * (sizeof (png_byte))); - - for (i = 0; i < num_palette; i++) - { - int ir, ig, ib; - int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS)); - int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS)); - int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS)); - - for (ir = 0; ir < num_red; ir++) - { - /* int dr = abs(ir - r); */ - int dr = ((ir > r) ? ir - r : r - ir); - int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS + - PNG_QUANTIZE_GREEN_BITS)); - - for (ig = 0; ig < num_green; ig++) - { - /* int dg = abs(ig - g); */ - int dg = ((ig > g) ? ig - g : g - ig); - int dt = dr + dg; - int dm = ((dr > dg) ? dr : dg); - int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS); - - for (ib = 0; ib < num_blue; ib++) - { - int d_index = index_g | ib; - /* int db = abs(ib - b); */ - int db = ((ib > b) ? ib - b : b - ib); - int dmax = ((dm > db) ? dm : db); - int d = dmax + dt + db; - - if (d < (int)distance[d_index]) - { - distance[d_index] = (png_byte)d; - png_ptr->palette_lookup[d_index] = (png_byte)i; - } - } - } - } - } - - png_free(png_ptr, distance); - } -} -#endif /* READ_QUANTIZE */ - -#ifdef PNG_READ_GAMMA_SUPPORTED -void PNGFAPI -png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma, - png_fixed_point file_gamma) -{ - png_debug(1, "in png_set_gamma_fixed"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - /* New in libpng-1.5.4 - reserve particular negative values as flags. */ - scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/); - file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/); - - /* Checking the gamma values for being >0 was added in 1.5.4 along with the - * premultiplied alpha support; this actually hides an undocumented feature - * of the previous implementation which allowed gamma processing to be - * disabled in background handling. There is no evidence (so far) that this - * was being used; however, png_set_background itself accepted and must still - * accept '0' for the gamma value it takes, because it isn't always used. - * - * Since this is an API change (albeit a very minor one that removes an - * undocumented API feature) the following checks were only enabled in - * libpng-1.6.0. - */ - if (file_gamma <= 0) - png_error(png_ptr, "invalid file gamma in png_set_gamma"); - - if (scrn_gamma <= 0) - png_error(png_ptr, "invalid screen gamma in png_set_gamma"); - - /* Set the gamma values unconditionally - this overrides the value in the PNG - * file if a gAMA chunk was present. png_set_alpha_mode provides a - * different, easier, way to default the file gamma. - */ - png_ptr->colorspace.gamma = file_gamma; - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - png_ptr->screen_gamma = scrn_gamma; -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma) -{ - png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma), - convert_gamma_value(png_ptr, file_gamma)); -} -# endif /* FLOATING_POINT */ -#endif /* READ_GAMMA */ - -#ifdef PNG_READ_EXPAND_SUPPORTED -/* Expand paletted images to RGB, expand grayscale images of - * less than 8-bit depth to 8-bit depth, and expand tRNS chunks - * to alpha channels. - */ -void PNGAPI -png_set_expand(png_structrp png_ptr) -{ - png_debug(1, "in png_set_expand"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); -} - -/* GRR 19990627: the following three functions currently are identical - * to png_set_expand(). However, it is entirely reasonable that someone - * might wish to expand an indexed image to RGB but *not* expand a single, - * fully transparent palette entry to a full alpha channel--perhaps instead - * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace - * the transparent color with a particular RGB value, or drop tRNS entirely. - * IOW, a future version of the library may make the transformations flag - * a bit more fine-grained, with separate bits for each of these three - * functions. - * - * More to the point, these functions make it obvious what libpng will be - * doing, whereas "expand" can (and does) mean any number of things. - * - * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified - * to expand only the sample depth but not to expand the tRNS to alpha - * and its name was changed to png_set_expand_gray_1_2_4_to_8(). - */ - -/* Expand paletted images to RGB. */ -void PNGAPI -png_set_palette_to_rgb(png_structrp png_ptr) -{ - png_debug(1, "in png_set_palette_to_rgb"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); -} - -/* Expand grayscale images of less than 8-bit depth to 8 bits. */ -void PNGAPI -png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr) -{ - png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= PNG_EXPAND; -} - -/* Expand tRNS chunks to alpha channels. */ -void PNGAPI -png_set_tRNS_to_alpha(png_structrp png_ptr) -{ - png_debug(1, "in png_set_tRNS_to_alpha"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); -} -#endif /* READ_EXPAND */ - -#ifdef PNG_READ_EXPAND_16_SUPPORTED -/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise - * it may not work correctly.) - */ -void PNGAPI -png_set_expand_16(png_structrp png_ptr) -{ - png_debug(1, "in png_set_expand_16"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS); -} -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -void PNGAPI -png_set_gray_to_rgb(png_structrp png_ptr) -{ - png_debug(1, "in png_set_gray_to_rgb"); - - if (png_rtran_ok(png_ptr, 0) == 0) - return; - - /* Because rgb must be 8 bits or more: */ - png_set_expand_gray_1_2_4_to_8(png_ptr); - png_ptr->transformations |= PNG_GRAY_TO_RGB; -} -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -void PNGFAPI -png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, - png_fixed_point red, png_fixed_point green) -{ - png_debug(1, "in png_set_rgb_to_gray"); - - /* Need the IHDR here because of the check on color_type below. */ - /* TODO: fix this */ - if (png_rtran_ok(png_ptr, 1) == 0) - return; - - switch (error_action) - { - case PNG_ERROR_ACTION_NONE: - png_ptr->transformations |= PNG_RGB_TO_GRAY; - break; - - case PNG_ERROR_ACTION_WARN: - png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; - break; - - case PNG_ERROR_ACTION_ERROR: - png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; - break; - - default: - png_error(png_ptr, "invalid error action to rgb_to_gray"); - } - - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -#ifdef PNG_READ_EXPAND_SUPPORTED - png_ptr->transformations |= PNG_EXPAND; -#else - { - /* Make this an error in 1.6 because otherwise the application may assume - * that it just worked and get a memory overwrite. - */ - png_error(png_ptr, - "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); - - /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */ - } -#endif - { - if (red >= 0 && green >= 0 && red + green <= PNG_FP_1) - { - png_uint_16 red_int, green_int; - - /* NOTE: this calculation does not round, but this behavior is retained - * for consistency; the inaccuracy is very small. The code here always - * overwrites the coefficients, regardless of whether they have been - * defaulted or set already. - */ - red_int = (png_uint_16)(((png_uint_32)red*32768)/100000); - green_int = (png_uint_16)(((png_uint_32)green*32768)/100000); - - png_ptr->rgb_to_gray_red_coeff = red_int; - png_ptr->rgb_to_gray_green_coeff = green_int; - png_ptr->rgb_to_gray_coefficients_set = 1; - } - - else - { - if (red >= 0 && green >= 0) - png_app_warning(png_ptr, - "ignoring out of range rgb_to_gray coefficients"); - - /* Use the defaults, from the cHRM chunk if set, else the historical - * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See - * png_do_rgb_to_gray for more discussion of the values. In this case - * the coefficients are not marked as 'set' and are not overwritten if - * something has already provided a default. - */ - if (png_ptr->rgb_to_gray_red_coeff == 0 && - png_ptr->rgb_to_gray_green_coeff == 0) - { - png_ptr->rgb_to_gray_red_coeff = 6968; - png_ptr->rgb_to_gray_green_coeff = 23434; - /* png_ptr->rgb_to_gray_blue_coeff = 2366; */ - } - } - } -} - -#ifdef PNG_FLOATING_POINT_SUPPORTED -/* Convert a RGB image to a grayscale of the same width. This allows us, - * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. - */ - -void PNGAPI -png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red, - double green) -{ - png_set_rgb_to_gray_fixed(png_ptr, error_action, - png_fixed(png_ptr, red, "rgb to gray red coefficient"), - png_fixed(png_ptr, green, "rgb to gray green coefficient")); -} -#endif /* FLOATING POINT */ - -#endif /* RGB_TO_GRAY */ - -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) -void PNGAPI -png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr - read_user_transform_fn) -{ - png_debug(1, "in png_set_read_user_transform_fn"); - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - png_ptr->transformations |= PNG_USER_TRANSFORM; - png_ptr->read_user_transform_fn = read_user_transform_fn; -#endif -} -#endif - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -#ifdef PNG_READ_GAMMA_SUPPORTED -/* In the case of gamma transformations only do transformations on images where - * the [file] gamma and screen_gamma are not close reciprocals, otherwise it - * slows things down slightly, and also needlessly introduces small errors. - */ -static int /* PRIVATE */ -png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma) -{ - /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma - * correction as a difference of the overall transform from 1.0 - * - * We want to compare the threshold with s*f - 1, if we get - * overflow here it is because of wacky gamma values so we - * turn on processing anyway. - */ - png_fixed_point gtest; - return !png_muldiv(>est, screen_gamma, file_gamma, PNG_FP_1) || - png_gamma_significant(gtest); -} -#endif - -/* Initialize everything needed for the read. This includes modifying - * the palette. - */ - -/* For the moment 'png_init_palette_transformations' and - * 'png_init_rgb_transformations' only do some flag canceling optimizations. - * The intent is that these two routines should have palette or rgb operations - * extracted from 'png_init_read_transformations'. - */ -static void /* PRIVATE */ -png_init_palette_transformations(png_structrp png_ptr) -{ - /* Called to handle the (input) palette case. In png_do_read_transformations - * the first step is to expand the palette if requested, so this code must - * take care to only make changes that are invariant with respect to the - * palette expansion, or only do them if there is no expansion. - * - * STRIP_ALPHA has already been handled in the caller (by setting num_trans - * to 0.) - */ - int input_has_alpha = 0; - int input_has_transparency = 0; - - if (png_ptr->num_trans > 0) - { - int i; - - /* Ignore if all the entries are opaque (unlikely!) */ - for (i=0; inum_trans; ++i) - { - if (png_ptr->trans_alpha[i] == 255) - continue; - else if (png_ptr->trans_alpha[i] == 0) - input_has_transparency = 1; - else - { - input_has_transparency = 1; - input_has_alpha = 1; - break; - } - } - } - - /* If no alpha we can optimize. */ - if (input_has_alpha == 0) - { - /* Any alpha means background and associative alpha processing is - * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA - * and ENCODE_ALPHA are irrelevant. - */ - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - - if (input_has_transparency == 0) - png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); - } - -#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) - /* png_set_background handling - deals with the complexity of whether the - * background color is in the file format or the screen format in the case - * where an 'expand' will happen. - */ - - /* The following code cannot be entered in the alpha pre-multiplication case - * because PNG_BACKGROUND_EXPAND is cancelled below. - */ - if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 && - (png_ptr->transformations & PNG_EXPAND) != 0) - { - { - png_ptr->background.red = - png_ptr->palette[png_ptr->background.index].red; - png_ptr->background.green = - png_ptr->palette[png_ptr->background.index].green; - png_ptr->background.blue = - png_ptr->palette[png_ptr->background.index].blue; - -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) - { - if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) - { - /* Invert the alpha channel (in tRNS) unless the pixels are - * going to be expanded, in which case leave it for later - */ - int i, istop = png_ptr->num_trans; - - for (i = 0; i < istop; i++) - png_ptr->trans_alpha[i] = - (png_byte)(255 - png_ptr->trans_alpha[i]); - } - } -#endif /* READ_INVERT_ALPHA */ - } - } /* background expand and (therefore) no alpha association. */ -#endif /* READ_EXPAND && READ_BACKGROUND */ -} - -static void /* PRIVATE */ -png_init_rgb_transformations(png_structrp png_ptr) -{ - /* Added to libpng-1.5.4: check the color type to determine whether there - * is any alpha or transparency in the image and simply cancel the - * background and alpha mode stuff if there isn't. - */ - int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0; - int input_has_transparency = png_ptr->num_trans > 0; - - /* If no alpha we can optimize. */ - if (input_has_alpha == 0) - { - /* Any alpha means background and associative alpha processing is - * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA - * and ENCODE_ALPHA are irrelevant. - */ -# ifdef PNG_READ_ALPHA_MODE_SUPPORTED - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; -# endif - - if (input_has_transparency == 0) - png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND); - } - -#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) - /* png_set_background handling - deals with the complexity of whether the - * background color is in the file format or the screen format in the case - * where an 'expand' will happen. - */ - - /* The following code cannot be entered in the alpha pre-multiplication case - * because PNG_BACKGROUND_EXPAND is cancelled below. - */ - if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 && - (png_ptr->transformations & PNG_EXPAND) != 0 && - (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) - /* i.e., GRAY or GRAY_ALPHA */ - { - { - /* Expand background and tRNS chunks */ - int gray = png_ptr->background.gray; - int trans_gray = png_ptr->trans_color.gray; - - switch (png_ptr->bit_depth) - { - case 1: - gray *= 0xff; - trans_gray *= 0xff; - break; - - case 2: - gray *= 0x55; - trans_gray *= 0x55; - break; - - case 4: - gray *= 0x11; - trans_gray *= 0x11; - break; - - default: - - case 8: - /* FALLTHROUGH */ /* (Already 8 bits) */ - - case 16: - /* Already a full 16 bits */ - break; - } - - png_ptr->background.red = png_ptr->background.green = - png_ptr->background.blue = (png_uint_16)gray; - - if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) - { - png_ptr->trans_color.red = png_ptr->trans_color.green = - png_ptr->trans_color.blue = (png_uint_16)trans_gray; - } - } - } /* background expand and (therefore) no alpha association. */ -#endif /* READ_EXPAND && READ_BACKGROUND */ -} - -void /* PRIVATE */ -png_init_read_transformations(png_structrp png_ptr) -{ - png_debug(1, "in png_init_read_transformations"); - - /* This internal function is called from png_read_start_row in pngrutil.c - * and it is called before the 'rowbytes' calculation is done, so the code - * in here can change or update the transformations flags. - * - * First do updates that do not depend on the details of the PNG image data - * being processed. - */ - -#ifdef PNG_READ_GAMMA_SUPPORTED - /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds - * png_set_alpha_mode and this is another source for a default file gamma so - * the test needs to be performed later - here. In addition prior to 1.5.4 - * the tests were repeated for the PALETTE color type here - this is no - * longer necessary (and doesn't seem to have been necessary before.) - */ - { - /* The following temporary indicates if overall gamma correction is - * required. - */ - int gamma_correction = 0; - - if (png_ptr->colorspace.gamma != 0) /* has been set */ - { - if (png_ptr->screen_gamma != 0) /* screen set too */ - gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma, - png_ptr->screen_gamma); - - else - /* Assume the output matches the input; a long time default behavior - * of libpng, although the standard has nothing to say about this. - */ - png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma); - } - - else if (png_ptr->screen_gamma != 0) - /* The converse - assume the file matches the screen, note that this - * perhaps undesirable default can (from 1.5.4) be changed by calling - * png_set_alpha_mode (even if the alpha handling mode isn't required - * or isn't changed from the default.) - */ - png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma); - - else /* neither are set */ - /* Just in case the following prevents any processing - file and screen - * are both assumed to be linear and there is no way to introduce a - * third gamma value other than png_set_background with 'UNIQUE', and, - * prior to 1.5.4 - */ - png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1; - - /* We have a gamma value now. */ - png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA; - - /* Now turn the gamma transformation on or off as appropriate. Notice - * that PNG_GAMMA just refers to the file->screen correction. Alpha - * composition may independently cause gamma correction because it needs - * linear data (e.g. if the file has a gAMA chunk but the screen gamma - * hasn't been specified.) In any case this flag may get turned off in - * the code immediately below if the transform can be handled outside the - * row loop. - */ - if (gamma_correction != 0) - png_ptr->transformations |= PNG_GAMMA; - - else - png_ptr->transformations &= ~PNG_GAMMA; - } -#endif - - /* Certain transformations have the effect of preventing other - * transformations that happen afterward in png_do_read_transformations; - * resolve the interdependencies here. From the code of - * png_do_read_transformations the order is: - * - * 1) PNG_EXPAND (including PNG_EXPAND_tRNS) - * 2) PNG_STRIP_ALPHA (if no compose) - * 3) PNG_RGB_TO_GRAY - * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY - * 5) PNG_COMPOSE - * 6) PNG_GAMMA - * 7) PNG_STRIP_ALPHA (if compose) - * 8) PNG_ENCODE_ALPHA - * 9) PNG_SCALE_16_TO_8 - * 10) PNG_16_TO_8 - * 11) PNG_QUANTIZE (converts to palette) - * 12) PNG_EXPAND_16 - * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY - * 14) PNG_INVERT_MONO - * 15) PNG_INVERT_ALPHA - * 16) PNG_SHIFT - * 17) PNG_PACK - * 18) PNG_BGR - * 19) PNG_PACKSWAP - * 20) PNG_FILLER (includes PNG_ADD_ALPHA) - * 21) PNG_SWAP_ALPHA - * 22) PNG_SWAP_BYTES - * 23) PNG_USER_TRANSFORM [must be last] - */ -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && - (png_ptr->transformations & PNG_COMPOSE) == 0) - { - /* Stripping the alpha channel happens immediately after the 'expand' - * transformations, before all other transformation, so it cancels out - * the alpha handling. It has the side effect negating the effect of - * PNG_EXPAND_tRNS too: - */ - png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA | - PNG_EXPAND_tRNS); - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - - /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen - * so transparency information would remain just so long as it wasn't - * expanded. This produces unexpected API changes if the set of things - * that do PNG_EXPAND_tRNS changes (perfectly possible given the - * documentation - which says ask for what you want, accept what you - * get.) This makes the behavior consistent from 1.5.4: - */ - png_ptr->num_trans = 0; - } -#endif /* STRIP_ALPHA supported, no COMPOSE */ - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED - /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA - * settings will have no effect. - */ - if (png_gamma_significant(png_ptr->screen_gamma) == 0) - { - png_ptr->transformations &= ~PNG_ENCODE_ALPHA; - png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; - } -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - /* Make sure the coefficients for the rgb to gray conversion are set - * appropriately. - */ - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) - png_colorspace_set_rgb_coefficients(png_ptr); -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) - /* Detect gray background and attempt to enable optimization for - * gray --> RGB case. - * - * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or - * RGB_ALPHA (in which case need_expand is superfluous anyway), the - * background color might actually be gray yet not be flagged as such. - * This is not a problem for the current code, which uses - * PNG_BACKGROUND_IS_GRAY only to decide when to do the - * png_do_gray_to_rgb() transformation. - * - * TODO: this code needs to be revised to avoid the complexity and - * interdependencies. The color type of the background should be recorded in - * png_set_background, along with the bit depth, then the code has a record - * of exactly what color space the background is currently in. - */ - if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0) - { - /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if - * the file was grayscale the background value is gray. - */ - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) - png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; - } - - else if ((png_ptr->transformations & PNG_COMPOSE) != 0) - { - /* PNG_COMPOSE: png_set_background was called with need_expand false, - * so the color is in the color space of the output or png_set_alpha_mode - * was called and the color is black. Ignore RGB_TO_GRAY because that - * happens before GRAY_TO_RGB. - */ - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) - { - if (png_ptr->background.red == png_ptr->background.green && - png_ptr->background.red == png_ptr->background.blue) - { - png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; - png_ptr->background.gray = png_ptr->background.red; - } - } - } -#endif /* READ_EXPAND && READ_BACKGROUND */ -#endif /* READ_GRAY_TO_RGB */ - - /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations - * can be performed directly on the palette, and some (such as rgb to gray) - * can be optimized inside the palette. This is particularly true of the - * composite (background and alpha) stuff, which can be pretty much all done - * in the palette even if the result is expanded to RGB or gray afterward. - * - * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and - * earlier and the palette stuff is actually handled on the first row. This - * leads to the reported bug that the palette returned by png_get_PLTE is not - * updated. - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - png_init_palette_transformations(png_ptr); - - else - png_init_rgb_transformations(png_ptr); - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ - defined(PNG_READ_EXPAND_16_SUPPORTED) - if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && - (png_ptr->transformations & PNG_COMPOSE) != 0 && - (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && - png_ptr->bit_depth != 16) - { - /* TODO: fix this. Because the expand_16 operation is after the compose - * handling the background color must be 8, not 16, bits deep, but the - * application will supply a 16-bit value so reduce it here. - * - * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at - * present, so that case is ok (until do_expand_16 is moved.) - * - * NOTE: this discards the low 16 bits of the user supplied background - * color, but until expand_16 works properly there is no choice! - */ -# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x)) - CHOP(png_ptr->background.red); - CHOP(png_ptr->background.green); - CHOP(png_ptr->background.blue); - CHOP(png_ptr->background.gray); -# undef CHOP - } -#endif /* READ_BACKGROUND && READ_EXPAND_16 */ - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ - (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \ - defined(PNG_READ_STRIP_16_TO_8_SUPPORTED)) - if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 && - (png_ptr->transformations & PNG_COMPOSE) != 0 && - (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 && - png_ptr->bit_depth == 16) - { - /* On the other hand, if a 16-bit file is to be reduced to 8-bits per - * component this will also happen after PNG_COMPOSE and so the background - * color must be pre-expanded here. - * - * TODO: fix this too. - */ - png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257); - png_ptr->background.green = - (png_uint_16)(png_ptr->background.green * 257); - png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257); - png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257); - } -#endif - - /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the - * background support (see the comments in scripts/pnglibconf.dfa), this - * allows pre-multiplication of the alpha channel to be implemented as - * compositing on black. This is probably sub-optimal and has been done in - * 1.5.4 betas simply to enable external critique and testing (i.e. to - * implement the new API quickly, without lots of internal changes.) - */ - -#ifdef PNG_READ_GAMMA_SUPPORTED -# ifdef PNG_READ_BACKGROUND_SUPPORTED - /* Includes ALPHA_MODE */ - png_ptr->background_1 = png_ptr->background; -# endif - - /* This needs to change - in the palette image case a whole set of tables are - * built when it would be quicker to just calculate the correct value for - * each palette entry directly. Also, the test is too tricky - why check - * PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that - * PNG_GAMMA is cancelled even if the gamma is known? The test excludes the - * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction - * the gamma tables will not be built even if composition is required on a - * gamma encoded value. - * - * In 1.5.4 this is addressed below by an additional check on the individual - * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the - * tables. - */ - if ((png_ptr->transformations & PNG_GAMMA) != 0 || - ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 && - (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || - png_gamma_significant(png_ptr->screen_gamma) != 0)) || - ((png_ptr->transformations & PNG_COMPOSE) != 0 && - (png_gamma_significant(png_ptr->colorspace.gamma) != 0 || - png_gamma_significant(png_ptr->screen_gamma) != 0 -# ifdef PNG_READ_BACKGROUND_SUPPORTED - || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE && - png_gamma_significant(png_ptr->background_gamma) != 0) -# endif - )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && - png_gamma_significant(png_ptr->screen_gamma) != 0)) - { - png_build_gamma_table(png_ptr, png_ptr->bit_depth); - -#ifdef PNG_READ_BACKGROUND_SUPPORTED - if ((png_ptr->transformations & PNG_COMPOSE) != 0) - { - /* Issue a warning about this combination: because RGB_TO_GRAY is - * optimized to do the gamma transform if present yet do_background has - * to do the same thing if both options are set a - * double-gamma-correction happens. This is true in all versions of - * libpng to date. - */ - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) - png_warning(png_ptr, - "libpng does not support gamma+background+rgb_to_gray"); - - if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0) - { - /* We don't get to here unless there is a tRNS chunk with non-opaque - * entries - see the checking code at the start of this function. - */ - png_color back, back_1; - png_colorp palette = png_ptr->palette; - int num_palette = png_ptr->num_palette; - int i; - if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) - { - - back.red = png_ptr->gamma_table[png_ptr->background.red]; - back.green = png_ptr->gamma_table[png_ptr->background.green]; - back.blue = png_ptr->gamma_table[png_ptr->background.blue]; - - back_1.red = png_ptr->gamma_to_1[png_ptr->background.red]; - back_1.green = png_ptr->gamma_to_1[png_ptr->background.green]; - back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue]; - } - else - { - png_fixed_point g, gs; - - switch (png_ptr->background_gamma_type) - { - case PNG_BACKGROUND_GAMMA_SCREEN: - g = (png_ptr->screen_gamma); - gs = PNG_FP_1; - break; - - case PNG_BACKGROUND_GAMMA_FILE: - g = png_reciprocal(png_ptr->colorspace.gamma); - gs = png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma); - break; - - case PNG_BACKGROUND_GAMMA_UNIQUE: - g = png_reciprocal(png_ptr->background_gamma); - gs = png_reciprocal2(png_ptr->background_gamma, - png_ptr->screen_gamma); - break; - default: - g = PNG_FP_1; /* back_1 */ - gs = PNG_FP_1; /* back */ - break; - } - - if (png_gamma_significant(gs) != 0) - { - back.red = png_gamma_8bit_correct(png_ptr->background.red, - gs); - back.green = png_gamma_8bit_correct(png_ptr->background.green, - gs); - back.blue = png_gamma_8bit_correct(png_ptr->background.blue, - gs); - } - - else - { - back.red = (png_byte)png_ptr->background.red; - back.green = (png_byte)png_ptr->background.green; - back.blue = (png_byte)png_ptr->background.blue; - } - - if (png_gamma_significant(g) != 0) - { - back_1.red = png_gamma_8bit_correct(png_ptr->background.red, - g); - back_1.green = png_gamma_8bit_correct( - png_ptr->background.green, g); - back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue, - g); - } - - else - { - back_1.red = (png_byte)png_ptr->background.red; - back_1.green = (png_byte)png_ptr->background.green; - back_1.blue = (png_byte)png_ptr->background.blue; - } - } - - for (i = 0; i < num_palette; i++) - { - if (i < (int)png_ptr->num_trans && - png_ptr->trans_alpha[i] != 0xff) - { - if (png_ptr->trans_alpha[i] == 0) - { - palette[i] = back; - } - else /* if (png_ptr->trans_alpha[i] != 0xff) */ - { - png_byte v, w; - - v = png_ptr->gamma_to_1[palette[i].red]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.red); - palette[i].red = png_ptr->gamma_from_1[w]; - - v = png_ptr->gamma_to_1[palette[i].green]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.green); - palette[i].green = png_ptr->gamma_from_1[w]; - - v = png_ptr->gamma_to_1[palette[i].blue]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue); - palette[i].blue = png_ptr->gamma_from_1[w]; - } - } - else - { - palette[i].red = png_ptr->gamma_table[palette[i].red]; - palette[i].green = png_ptr->gamma_table[palette[i].green]; - palette[i].blue = png_ptr->gamma_table[palette[i].blue]; - } - } - - /* Prevent the transformations being done again. - * - * NOTE: this is highly dubious; it removes the transformations in - * place. This seems inconsistent with the general treatment of the - * transformations elsewhere. - */ - png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA); - } /* color_type == PNG_COLOR_TYPE_PALETTE */ - - /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ - else /* color_type != PNG_COLOR_TYPE_PALETTE */ - { - int gs_sig, g_sig; - png_fixed_point g = PNG_FP_1; /* Correction to linear */ - png_fixed_point gs = PNG_FP_1; /* Correction to screen */ - - switch (png_ptr->background_gamma_type) - { - case PNG_BACKGROUND_GAMMA_SCREEN: - g = png_ptr->screen_gamma; - /* gs = PNG_FP_1; */ - break; - - case PNG_BACKGROUND_GAMMA_FILE: - g = png_reciprocal(png_ptr->colorspace.gamma); - gs = png_reciprocal2(png_ptr->colorspace.gamma, - png_ptr->screen_gamma); - break; - - case PNG_BACKGROUND_GAMMA_UNIQUE: - g = png_reciprocal(png_ptr->background_gamma); - gs = png_reciprocal2(png_ptr->background_gamma, - png_ptr->screen_gamma); - break; - - default: - png_error(png_ptr, "invalid background gamma type"); - } - - g_sig = png_gamma_significant(g); - gs_sig = png_gamma_significant(gs); - - if (g_sig != 0) - png_ptr->background_1.gray = png_gamma_correct(png_ptr, - png_ptr->background.gray, g); - - if (gs_sig != 0) - png_ptr->background.gray = png_gamma_correct(png_ptr, - png_ptr->background.gray, gs); - - if ((png_ptr->background.red != png_ptr->background.green) || - (png_ptr->background.red != png_ptr->background.blue) || - (png_ptr->background.red != png_ptr->background.gray)) - { - /* RGB or RGBA with color background */ - if (g_sig != 0) - { - png_ptr->background_1.red = png_gamma_correct(png_ptr, - png_ptr->background.red, g); - - png_ptr->background_1.green = png_gamma_correct(png_ptr, - png_ptr->background.green, g); - - png_ptr->background_1.blue = png_gamma_correct(png_ptr, - png_ptr->background.blue, g); - } - - if (gs_sig != 0) - { - png_ptr->background.red = png_gamma_correct(png_ptr, - png_ptr->background.red, gs); - - png_ptr->background.green = png_gamma_correct(png_ptr, - png_ptr->background.green, gs); - - png_ptr->background.blue = png_gamma_correct(png_ptr, - png_ptr->background.blue, gs); - } - } - - else - { - /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ - png_ptr->background_1.red = png_ptr->background_1.green - = png_ptr->background_1.blue = png_ptr->background_1.gray; - - png_ptr->background.red = png_ptr->background.green - = png_ptr->background.blue = png_ptr->background.gray; - } - - /* The background is now in screen gamma: */ - png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN; - } /* color_type != PNG_COLOR_TYPE_PALETTE */ - }/* png_ptr->transformations & PNG_BACKGROUND */ - - else - /* Transformation does not include PNG_BACKGROUND */ -#endif /* READ_BACKGROUND */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - /* RGB_TO_GRAY needs to have non-gamma-corrected values! */ - && ((png_ptr->transformations & PNG_EXPAND) == 0 || - (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0) -#endif - ) - { - png_colorp palette = png_ptr->palette; - int num_palette = png_ptr->num_palette; - int i; - - /* NOTE: there are other transformations that should probably be in - * here too. - */ - for (i = 0; i < num_palette; i++) - { - palette[i].red = png_ptr->gamma_table[palette[i].red]; - palette[i].green = png_ptr->gamma_table[palette[i].green]; - palette[i].blue = png_ptr->gamma_table[palette[i].blue]; - } - - /* Done the gamma correction. */ - png_ptr->transformations &= ~PNG_GAMMA; - } /* color_type == PALETTE && !PNG_BACKGROUND transformation */ - } -#ifdef PNG_READ_BACKGROUND_SUPPORTED - else -#endif -#endif /* READ_GAMMA */ - -#ifdef PNG_READ_BACKGROUND_SUPPORTED - /* No GAMMA transformation (see the hanging else 4 lines above) */ - if ((png_ptr->transformations & PNG_COMPOSE) != 0 && - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) - { - int i; - int istop = (int)png_ptr->num_trans; - png_color back; - png_colorp palette = png_ptr->palette; - - back.red = (png_byte)png_ptr->background.red; - back.green = (png_byte)png_ptr->background.green; - back.blue = (png_byte)png_ptr->background.blue; - - for (i = 0; i < istop; i++) - { - if (png_ptr->trans_alpha[i] == 0) - { - palette[i] = back; - } - - else if (png_ptr->trans_alpha[i] != 0xff) - { - /* The png_composite() macro is defined in png.h */ - png_composite(palette[i].red, palette[i].red, - png_ptr->trans_alpha[i], back.red); - - png_composite(palette[i].green, palette[i].green, - png_ptr->trans_alpha[i], back.green); - - png_composite(palette[i].blue, palette[i].blue, - png_ptr->trans_alpha[i], back.blue); - } - } - - png_ptr->transformations &= ~PNG_COMPOSE; - } -#endif /* READ_BACKGROUND */ - -#ifdef PNG_READ_SHIFT_SUPPORTED - if ((png_ptr->transformations & PNG_SHIFT) != 0 && - (png_ptr->transformations & PNG_EXPAND) == 0 && - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) - { - int i; - int istop = png_ptr->num_palette; - int shift = 8 - png_ptr->sig_bit.red; - - png_ptr->transformations &= ~PNG_SHIFT; - - /* significant bits can be in the range 1 to 7 for a meaningful result, if - * the number of significant bits is 0 then no shift is done (this is an - * error condition which is silently ignored.) - */ - if (shift > 0 && shift < 8) - for (i=0; ipalette[i].red; - - component >>= shift; - png_ptr->palette[i].red = (png_byte)component; - } - - shift = 8 - png_ptr->sig_bit.green; - if (shift > 0 && shift < 8) - for (i=0; ipalette[i].green; - - component >>= shift; - png_ptr->palette[i].green = (png_byte)component; - } - - shift = 8 - png_ptr->sig_bit.blue; - if (shift > 0 && shift < 8) - for (i=0; ipalette[i].blue; - - component >>= shift; - png_ptr->palette[i].blue = (png_byte)component; - } - } -#endif /* READ_SHIFT */ -} - -/* Modify the info structure to reflect the transformations. The - * info should be updated so a PNG file could be written with it, - * assuming the transformations result in valid PNG data. - */ -void /* PRIVATE */ -png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr) -{ - png_debug(1, "in png_read_transform_info"); - -#ifdef PNG_READ_EXPAND_SUPPORTED - if ((png_ptr->transformations & PNG_EXPAND) != 0) - { - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - /* This check must match what actually happens in - * png_do_expand_palette; if it ever checks the tRNS chunk to see if - * it is all opaque we must do the same (at present it does not.) - */ - if (png_ptr->num_trans > 0) - info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; - - else - info_ptr->color_type = PNG_COLOR_TYPE_RGB; - - info_ptr->bit_depth = 8; - info_ptr->num_trans = 0; - - if (png_ptr->palette == NULL) - png_error (png_ptr, "Palette is NULL in indexed image"); - } - else - { - if (png_ptr->num_trans != 0) - { - if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0) - info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; - } - if (info_ptr->bit_depth < 8) - info_ptr->bit_depth = 8; - - info_ptr->num_trans = 0; - } - } -#endif - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) - /* The following is almost certainly wrong unless the background value is in - * the screen space! - */ - if ((png_ptr->transformations & PNG_COMPOSE) != 0) - info_ptr->background = png_ptr->background; -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED - /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4), - * however it seems that the code in png_init_read_transformations, which has - * been called before this from png_read_update_info->png_read_start_row - * sometimes does the gamma transform and cancels the flag. - * - * TODO: this looks wrong; the info_ptr should end up with a gamma equal to - * the screen_gamma value. The following probably results in weirdness if - * the info_ptr is used by the app after the rows have been read. - */ - info_ptr->colorspace.gamma = png_ptr->colorspace.gamma; -#endif - - if (info_ptr->bit_depth == 16) - { -# ifdef PNG_READ_16BIT_SUPPORTED -# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) - info_ptr->bit_depth = 8; -# endif - -# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - if ((png_ptr->transformations & PNG_16_TO_8) != 0) - info_ptr->bit_depth = 8; -# endif - -# else - /* No 16-bit support: force chopping 16-bit input down to 8, in this case - * the app program can chose if both APIs are available by setting the - * correct scaling to use. - */ -# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - /* For compatibility with previous versions use the strip method by - * default. This code works because if PNG_SCALE_16_TO_8 is already - * set the code below will do that in preference to the chop. - */ - png_ptr->transformations |= PNG_16_TO_8; - info_ptr->bit_depth = 8; -# else - -# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - png_ptr->transformations |= PNG_SCALE_16_TO_8; - info_ptr->bit_depth = 8; -# else - - CONFIGURATION ERROR: you must enable at least one 16 to 8 method -# endif -# endif -#endif /* !READ_16BIT */ - } - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) - info_ptr->color_type = (png_byte)(info_ptr->color_type | - PNG_COLOR_MASK_COLOR); -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) - info_ptr->color_type = (png_byte)(info_ptr->color_type & - ~PNG_COLOR_MASK_COLOR); -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - if ((png_ptr->transformations & PNG_QUANTIZE) != 0) - { - if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || - (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && - png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8) - { - info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; - } - } -#endif - -#ifdef PNG_READ_EXPAND_16_SUPPORTED - if ((png_ptr->transformations & PNG_EXPAND_16) != 0 && - info_ptr->bit_depth == 8 && - info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - { - info_ptr->bit_depth = 16; - } -#endif - -#ifdef PNG_READ_PACK_SUPPORTED - if ((png_ptr->transformations & PNG_PACK) != 0 && - (info_ptr->bit_depth < 8)) - info_ptr->bit_depth = 8; -#endif - - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - info_ptr->channels = 1; - - else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - info_ptr->channels = 3; - - else - info_ptr->channels = 1; - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0) - { - info_ptr->color_type = (png_byte)(info_ptr->color_type & - ~PNG_COLOR_MASK_ALPHA); - info_ptr->num_trans = 0; - } -#endif - - if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) - info_ptr->channels++; - -#ifdef PNG_READ_FILLER_SUPPORTED - /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */ - if ((png_ptr->transformations & PNG_FILLER) != 0 && - (info_ptr->color_type == PNG_COLOR_TYPE_RGB || - info_ptr->color_type == PNG_COLOR_TYPE_GRAY)) - { - info_ptr->channels++; - /* If adding a true alpha channel not just filler */ - if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0) - info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; - } -#endif - -#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ -defined(PNG_READ_USER_TRANSFORM_SUPPORTED) - if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) - { - if (png_ptr->user_transform_depth != 0) - info_ptr->bit_depth = png_ptr->user_transform_depth; - - if (png_ptr->user_transform_channels != 0) - info_ptr->channels = png_ptr->user_transform_channels; - } -#endif - - info_ptr->pixel_depth = (png_byte)(info_ptr->channels * - info_ptr->bit_depth); - - info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); - - /* Adding in 1.5.4: cache the above value in png_struct so that we can later - * check in png_rowbytes that the user buffer won't get overwritten. Note - * that the field is not always set - if png_read_update_info isn't called - * the application has to either not do any transforms or get the calculation - * right itself. - */ - png_ptr->info_rowbytes = info_ptr->rowbytes; - -#ifndef PNG_READ_EXPAND_SUPPORTED - if (png_ptr != NULL) - return; -#endif -} - -#ifdef PNG_READ_PACK_SUPPORTED -/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel, - * without changing the actual values. Thus, if you had a row with - * a bit depth of 1, you would end up with bytes that only contained - * the numbers 0 or 1. If you would rather they contain 0 and 255, use - * png_do_shift() after this. - */ -static void -png_do_unpack(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_unpack"); - - if (row_info->bit_depth < 8) - { - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - switch (row_info->bit_depth) - { - case 1: - { - png_bytep sp = row + (size_t)((row_width - 1) >> 3); - png_bytep dp = row + (size_t)row_width - 1; - png_uint_32 shift = 7U - ((row_width + 7U) & 0x07); - for (i = 0; i < row_width; i++) - { - *dp = (png_byte)((*sp >> shift) & 0x01); - - if (shift == 7) - { - shift = 0; - sp--; - } - - else - shift++; - - dp--; - } - break; - } - - case 2: - { - - png_bytep sp = row + (size_t)((row_width - 1) >> 2); - png_bytep dp = row + (size_t)row_width - 1; - png_uint_32 shift = ((3U - ((row_width + 3U) & 0x03)) << 1); - for (i = 0; i < row_width; i++) - { - *dp = (png_byte)((*sp >> shift) & 0x03); - - if (shift == 6) - { - shift = 0; - sp--; - } - - else - shift += 2; - - dp--; - } - break; - } - - case 4: - { - png_bytep sp = row + (size_t)((row_width - 1) >> 1); - png_bytep dp = row + (size_t)row_width - 1; - png_uint_32 shift = ((1U - ((row_width + 1U) & 0x01)) << 2); - for (i = 0; i < row_width; i++) - { - *dp = (png_byte)((*sp >> shift) & 0x0f); - - if (shift == 4) - { - shift = 0; - sp--; - } - - else - shift = 4; - - dp--; - } - break; - } - - default: - break; - } - row_info->bit_depth = 8; - row_info->pixel_depth = (png_byte)(8 * row_info->channels); - row_info->rowbytes = row_width * row_info->channels; - } -} -#endif - -#ifdef PNG_READ_SHIFT_SUPPORTED -/* Reverse the effects of png_do_shift. This routine merely shifts the - * pixels back to their significant bits values. Thus, if you have - * a row of bit depth 8, but only 5 are significant, this will shift - * the values back to 0 through 31. - */ -static void -png_do_unshift(png_row_infop row_info, png_bytep row, - png_const_color_8p sig_bits) -{ - int color_type; - - png_debug(1, "in png_do_unshift"); - - /* The palette case has already been handled in the _init routine. */ - color_type = row_info->color_type; - - if (color_type != PNG_COLOR_TYPE_PALETTE) - { - int shift[4]; - int channels = 0; - int bit_depth = row_info->bit_depth; - - if ((color_type & PNG_COLOR_MASK_COLOR) != 0) - { - shift[channels++] = bit_depth - sig_bits->red; - shift[channels++] = bit_depth - sig_bits->green; - shift[channels++] = bit_depth - sig_bits->blue; - } - - else - { - shift[channels++] = bit_depth - sig_bits->gray; - } - - if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - shift[channels++] = bit_depth - sig_bits->alpha; - } - - { - int c, have_shift; - - for (c = have_shift = 0; c < channels; ++c) - { - /* A shift of more than the bit depth is an error condition but it - * gets ignored here. - */ - if (shift[c] <= 0 || shift[c] >= bit_depth) - shift[c] = 0; - - else - have_shift = 1; - } - - if (have_shift == 0) - return; - } - - switch (bit_depth) - { - default: - /* Must be 1bpp gray: should not be here! */ - /* NOTREACHED */ - break; - - case 2: - /* Must be 2bpp gray */ - /* assert(channels == 1 && shift[0] == 1) */ - { - png_bytep bp = row; - png_bytep bp_end = bp + row_info->rowbytes; - - while (bp < bp_end) - { - int b = (*bp >> 1) & 0x55; - *bp++ = (png_byte)b; - } - break; - } - - case 4: - /* Must be 4bpp gray */ - /* assert(channels == 1) */ - { - png_bytep bp = row; - png_bytep bp_end = bp + row_info->rowbytes; - int gray_shift = shift[0]; - int mask = 0xf >> gray_shift; - - mask |= mask << 4; - - while (bp < bp_end) - { - int b = (*bp >> gray_shift) & mask; - *bp++ = (png_byte)b; - } - break; - } - - case 8: - /* Single byte components, G, GA, RGB, RGBA */ - { - png_bytep bp = row; - png_bytep bp_end = bp + row_info->rowbytes; - int channel = 0; - - while (bp < bp_end) - { - int b = *bp >> shift[channel]; - if (++channel >= channels) - channel = 0; - *bp++ = (png_byte)b; - } - break; - } - -#ifdef PNG_READ_16BIT_SUPPORTED - case 16: - /* Double byte components, G, GA, RGB, RGBA */ - { - png_bytep bp = row; - png_bytep bp_end = bp + row_info->rowbytes; - int channel = 0; - - while (bp < bp_end) - { - int value = (bp[0] << 8) + bp[1]; - - value >>= shift[channel]; - if (++channel >= channels) - channel = 0; - *bp++ = (png_byte)(value >> 8); - *bp++ = (png_byte)value; - } - break; - } -#endif - } - } -} -#endif - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED -/* Scale rows of bit depth 16 down to 8 accurately */ -static void -png_do_scale_16_to_8(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_scale_16_to_8"); - - if (row_info->bit_depth == 16) - { - png_bytep sp = row; /* source */ - png_bytep dp = row; /* destination */ - png_bytep ep = sp + row_info->rowbytes; /* end+1 */ - - while (sp < ep) - { - /* The input is an array of 16-bit components, these must be scaled to - * 8 bits each. For a 16-bit value V the required value (from the PNG - * specification) is: - * - * (V * 255) / 65535 - * - * This reduces to round(V / 257), or floor((V + 128.5)/257) - * - * Represent V as the two byte value vhi.vlo. Make a guess that the - * result is the top byte of V, vhi, then the correction to this value - * is: - * - * error = floor(((V-vhi.vhi) + 128.5) / 257) - * = floor(((vlo-vhi) + 128.5) / 257) - * - * This can be approximated using integer arithmetic (and a signed - * shift): - * - * error = (vlo-vhi+128) >> 8; - * - * The approximate differs from the exact answer only when (vlo-vhi) is - * 128; it then gives a correction of +1 when the exact correction is - * 0. This gives 128 errors. The exact answer (correct for all 16-bit - * input values) is: - * - * error = (vlo-vhi+128)*65535 >> 24; - * - * An alternative arithmetic calculation which also gives no errors is: - * - * (V * 255 + 32895) >> 16 - */ - - png_int_32 tmp = *sp++; /* must be signed! */ - tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24; - *dp++ = (png_byte)tmp; - } - - row_info->bit_depth = 8; - row_info->pixel_depth = (png_byte)(8 * row_info->channels); - row_info->rowbytes = row_info->width * row_info->channels; - } -} -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED -static void -/* Simply discard the low byte. This was the default behavior prior - * to libpng-1.5.4. - */ -png_do_chop(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_chop"); - - if (row_info->bit_depth == 16) - { - png_bytep sp = row; /* source */ - png_bytep dp = row; /* destination */ - png_bytep ep = sp + row_info->rowbytes; /* end+1 */ - - while (sp < ep) - { - *dp++ = *sp; - sp += 2; /* skip low byte */ - } - - row_info->bit_depth = 8; - row_info->pixel_depth = (png_byte)(8 * row_info->channels); - row_info->rowbytes = row_info->width * row_info->channels; - } -} -#endif - -#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED -static void -png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) -{ - png_uint_32 row_width = row_info->width; - - png_debug(1, "in png_do_read_swap_alpha"); - - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - /* This converts from RGBA to ARGB */ - if (row_info->bit_depth == 8) - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - save = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - /* This converts from RRGGBBAA to AARRGGBB */ - else - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save[2]; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - save[0] = *(--sp); - save[1] = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save[0]; - *(--dp) = save[1]; - } - } -#endif - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - /* This converts from GA to AG */ - if (row_info->bit_depth == 8) - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - save = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - /* This converts from GGAA to AAGG */ - else - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save[2]; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - save[0] = *(--sp); - save[1] = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save[0]; - *(--dp) = save[1]; - } - } -#endif - } -} -#endif - -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED -static void -png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) -{ - png_uint_32 row_width; - png_debug(1, "in png_do_read_invert_alpha"); - - row_width = row_info->width; - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This inverts the alpha channel in RGBA */ - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - -/* This does nothing: - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - We can replace it with: -*/ - sp-=3; - dp=sp; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - /* This inverts the alpha channel in RRGGBBAA */ - else - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - *(--dp) = (png_byte)(255 - *(--sp)); - -/* This does nothing: - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - We can replace it with: -*/ - sp-=6; - dp=sp; - } - } -#endif - } - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This inverts the alpha channel in GA */ - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - *(--dp) = *(--sp); - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - else - { - /* This inverts the alpha channel in GGAA */ - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - *(--dp) = (png_byte)(255 - *(--sp)); -/* - *(--dp) = *(--sp); - *(--dp) = *(--sp); -*/ - sp-=2; - dp=sp; - } - } -#endif - } -} -#endif - -#ifdef PNG_READ_FILLER_SUPPORTED -/* Add filler channel if we have RGB color */ -static void -png_do_read_filler(png_row_infop row_info, png_bytep row, - png_uint_32 filler, png_uint_32 flags) -{ - png_uint_32 i; - png_uint_32 row_width = row_info->width; - -#ifdef PNG_READ_16BIT_SUPPORTED - png_byte hi_filler = (png_byte)(filler>>8); -#endif - png_byte lo_filler = (png_byte)filler; - - png_debug(1, "in png_do_read_filler"); - - if ( - row_info->color_type == PNG_COLOR_TYPE_GRAY) - { - if (row_info->bit_depth == 8) - { - if ((flags & PNG_FLAG_FILLER_AFTER) != 0) - { - /* This changes the data from G to GX */ - png_bytep sp = row + (size_t)row_width; - png_bytep dp = sp + (size_t)row_width; - for (i = 1; i < row_width; i++) - { - *(--dp) = lo_filler; - *(--dp) = *(--sp); - } - *(--dp) = lo_filler; - row_info->channels = 2; - row_info->pixel_depth = 16; - row_info->rowbytes = row_width * 2; - } - - else - { - /* This changes the data from G to XG */ - png_bytep sp = row + (size_t)row_width; - png_bytep dp = sp + (size_t)row_width; - for (i = 0; i < row_width; i++) - { - *(--dp) = *(--sp); - *(--dp) = lo_filler; - } - row_info->channels = 2; - row_info->pixel_depth = 16; - row_info->rowbytes = row_width * 2; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { - if ((flags & PNG_FLAG_FILLER_AFTER) != 0) - { - /* This changes the data from GG to GGXX */ - png_bytep sp = row + (size_t)row_width * 2; - png_bytep dp = sp + (size_t)row_width * 2; - for (i = 1; i < row_width; i++) - { - *(--dp) = lo_filler; - *(--dp) = hi_filler; - *(--dp) = *(--sp); - *(--dp) = *(--sp); - } - *(--dp) = lo_filler; - *(--dp) = hi_filler; - row_info->channels = 2; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - } - - else - { - /* This changes the data from GG to XXGG */ - png_bytep sp = row + (size_t)row_width * 2; - png_bytep dp = sp + (size_t)row_width * 2; - for (i = 0; i < row_width; i++) - { - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = lo_filler; - *(--dp) = hi_filler; - } - row_info->channels = 2; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - } - } -#endif - } /* COLOR_TYPE == GRAY */ - else if (row_info->color_type == PNG_COLOR_TYPE_RGB) - { - if (row_info->bit_depth == 8) - { - if ((flags & PNG_FLAG_FILLER_AFTER) != 0) - { - /* This changes the data from RGB to RGBX */ - png_bytep sp = row + (size_t)row_width * 3; - png_bytep dp = sp + (size_t)row_width; - for (i = 1; i < row_width; i++) - { - *(--dp) = lo_filler; - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - } - *(--dp) = lo_filler; - row_info->channels = 4; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - } - - else - { - /* This changes the data from RGB to XRGB */ - png_bytep sp = row + (size_t)row_width * 3; - png_bytep dp = sp + (size_t)row_width; - for (i = 0; i < row_width; i++) - { - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = lo_filler; - } - row_info->channels = 4; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - } - } - -#ifdef PNG_READ_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { - if ((flags & PNG_FLAG_FILLER_AFTER) != 0) - { - /* This changes the data from RRGGBB to RRGGBBXX */ - png_bytep sp = row + (size_t)row_width * 6; - png_bytep dp = sp + (size_t)row_width * 2; - for (i = 1; i < row_width; i++) - { - *(--dp) = lo_filler; - *(--dp) = hi_filler; - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - } - *(--dp) = lo_filler; - *(--dp) = hi_filler; - row_info->channels = 4; - row_info->pixel_depth = 64; - row_info->rowbytes = row_width * 8; - } - - else - { - /* This changes the data from RRGGBB to XXRRGGBB */ - png_bytep sp = row + (size_t)row_width * 6; - png_bytep dp = sp + (size_t)row_width * 2; - for (i = 0; i < row_width; i++) - { - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = lo_filler; - *(--dp) = hi_filler; - } - - row_info->channels = 4; - row_info->pixel_depth = 64; - row_info->rowbytes = row_width * 8; - } - } -#endif - } /* COLOR_TYPE == RGB */ -} -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED -/* Expand grayscale files to RGB, with or without alpha */ -static void -png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) -{ - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - png_debug(1, "in png_do_gray_to_rgb"); - - if (row_info->bit_depth >= 8 && - (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0) - { - if (row_info->color_type == PNG_COLOR_TYPE_GRAY) - { - if (row_info->bit_depth == 8) - { - /* This changes G to RGB */ - png_bytep sp = row + (size_t)row_width - 1; - png_bytep dp = sp + (size_t)row_width * 2; - for (i = 0; i < row_width; i++) - { - *(dp--) = *sp; - *(dp--) = *sp; - *(dp--) = *(sp--); - } - } - - else - { - /* This changes GG to RRGGBB */ - png_bytep sp = row + (size_t)row_width * 2 - 1; - png_bytep dp = sp + (size_t)row_width * 4; - for (i = 0; i < row_width; i++) - { - *(dp--) = *sp; - *(dp--) = *(sp - 1); - *(dp--) = *sp; - *(dp--) = *(sp - 1); - *(dp--) = *(sp--); - *(dp--) = *(sp--); - } - } - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This changes GA to RGBA */ - png_bytep sp = row + (size_t)row_width * 2 - 1; - png_bytep dp = sp + (size_t)row_width * 2; - for (i = 0; i < row_width; i++) - { - *(dp--) = *(sp--); - *(dp--) = *sp; - *(dp--) = *sp; - *(dp--) = *(sp--); - } - } - - else - { - /* This changes GGAA to RRGGBBAA */ - png_bytep sp = row + (size_t)row_width * 4 - 1; - png_bytep dp = sp + (size_t)row_width * 4; - for (i = 0; i < row_width; i++) - { - *(dp--) = *(sp--); - *(dp--) = *(sp--); - *(dp--) = *sp; - *(dp--) = *(sp - 1); - *(dp--) = *sp; - *(dp--) = *(sp - 1); - *(dp--) = *(sp--); - *(dp--) = *(sp--); - } - } - } - row_info->channels = (png_byte)(row_info->channels + 2); - row_info->color_type |= PNG_COLOR_MASK_COLOR; - row_info->pixel_depth = (png_byte)(row_info->channels * - row_info->bit_depth); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } -} -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -/* Reduce RGB files to grayscale, with or without alpha - * using the equation given in Poynton's ColorFAQ of 1998-01-04 at - * (THIS LINK IS DEAD June 2008 but - * versions dated 1998 through November 2002 have been archived at - * https://web.archive.org/web/20000816232553/www.inforamp.net/ - * ~poynton/notes/colour_and_gamma/ColorFAQ.txt ) - * Charles Poynton poynton at poynton.com - * - * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B - * - * which can be expressed with integers as - * - * Y = (6969 * R + 23434 * G + 2365 * B)/32768 - * - * Poynton's current link (as of January 2003 through July 2011): - * - * has changed the numbers slightly: - * - * Y = 0.2126*R + 0.7152*G + 0.0722*B - * - * which can be expressed with integers as - * - * Y = (6966 * R + 23436 * G + 2366 * B)/32768 - * - * Historically, however, libpng uses numbers derived from the ITU-R Rec 709 - * end point chromaticities and the D65 white point. Depending on the - * precision used for the D65 white point this produces a variety of different - * numbers, however if the four decimal place value used in ITU-R Rec 709 is - * used (0.3127,0.3290) the Y calculation would be: - * - * Y = (6968 * R + 23435 * G + 2366 * B)/32768 - * - * While this is correct the rounding results in an overflow for white, because - * the sum of the rounded coefficients is 32769, not 32768. Consequently - * libpng uses, instead, the closest non-overflowing approximation: - * - * Y = (6968 * R + 23434 * G + 2366 * B)/32768 - * - * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk - * (including an sRGB chunk) then the chromaticities are used to calculate the - * coefficients. See the chunk handling in pngrutil.c for more information. - * - * In all cases the calculation is to be done in a linear colorspace. If no - * gamma information is available to correct the encoding of the original RGB - * values this results in an implicit assumption that the original PNG RGB - * values were linear. - * - * Other integer coefficients can be used via png_set_rgb_to_gray(). Because - * the API takes just red and green coefficients the blue coefficient is - * calculated to make the sum 32768. This will result in different rounding - * to that used above. - */ -static int -png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) -{ - int rgb_error = 0; - - png_debug(1, "in png_do_rgb_to_gray"); - - if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 && - (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; - png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; - png_uint_32 bc = 32768 - rc - gc; - png_uint_32 row_width = row_info->width; - int have_alpha = (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; - - if (row_info->bit_depth == 8) - { -#ifdef PNG_READ_GAMMA_SUPPORTED - /* Notice that gamma to/from 1 are not necessarily inverses (if - * there is an overall gamma correction). Prior to 1.5.5 this code - * checked the linearized values for equality; this doesn't match - * the documentation, the original values must be checked. - */ - if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL) - { - png_bytep sp = row; - png_bytep dp = row; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - png_byte red = *(sp++); - png_byte green = *(sp++); - png_byte blue = *(sp++); - - if (red != green || red != blue) - { - red = png_ptr->gamma_to_1[red]; - green = png_ptr->gamma_to_1[green]; - blue = png_ptr->gamma_to_1[blue]; - - rgb_error |= 1; - *(dp++) = png_ptr->gamma_from_1[ - (rc*red + gc*green + bc*blue + 16384)>>15]; - } - - else - { - /* If there is no overall correction the table will not be - * set. - */ - if (png_ptr->gamma_table != NULL) - red = png_ptr->gamma_table[red]; - - *(dp++) = red; - } - - if (have_alpha != 0) - *(dp++) = *(sp++); - } - } - else -#endif - { - png_bytep sp = row; - png_bytep dp = row; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - png_byte red = *(sp++); - png_byte green = *(sp++); - png_byte blue = *(sp++); - - if (red != green || red != blue) - { - rgb_error |= 1; - /* NOTE: this is the historical approach which simply - * truncates the results. - */ - *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); - } - - else - *(dp++) = red; - - if (have_alpha != 0) - *(dp++) = *(sp++); - } - } - } - - else /* RGB bit_depth == 16 */ - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL) - { - png_bytep sp = row; - png_bytep dp = row; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - png_uint_16 red, green, blue, w; - png_byte hi,lo; - - hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo)); - hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo)); - hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo)); - - if (red == green && red == blue) - { - if (png_ptr->gamma_16_table != NULL) - w = png_ptr->gamma_16_table[(red & 0xff) - >> png_ptr->gamma_shift][red >> 8]; - - else - w = red; - } - - else - { - png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red & 0xff) - >> png_ptr->gamma_shift][red>>8]; - png_uint_16 green_1 = - png_ptr->gamma_16_to_1[(green & 0xff) >> - png_ptr->gamma_shift][green>>8]; - png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue & 0xff) - >> png_ptr->gamma_shift][blue>>8]; - png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 - + bc*blue_1 + 16384)>>15); - w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >> - png_ptr->gamma_shift][gray16 >> 8]; - rgb_error |= 1; - } - - *(dp++) = (png_byte)((w>>8) & 0xff); - *(dp++) = (png_byte)(w & 0xff); - - if (have_alpha != 0) - { - *(dp++) = *(sp++); - *(dp++) = *(sp++); - } - } - } - else -#endif - { - png_bytep sp = row; - png_bytep dp = row; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - png_uint_16 red, green, blue, gray16; - png_byte hi,lo; - - hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo)); - hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo)); - hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo)); - - if (red != green || red != blue) - rgb_error |= 1; - - /* From 1.5.5 in the 16-bit case do the accurate conversion even - * in the 'fast' case - this is because this is where the code - * ends up when handling linear 16-bit data. - */ - gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >> - 15); - *(dp++) = (png_byte)((gray16 >> 8) & 0xff); - *(dp++) = (png_byte)(gray16 & 0xff); - - if (have_alpha != 0) - { - *(dp++) = *(sp++); - *(dp++) = *(sp++); - } - } - } - } - - row_info->channels = (png_byte)(row_info->channels - 2); - row_info->color_type = (png_byte)(row_info->color_type & - ~PNG_COLOR_MASK_COLOR); - row_info->pixel_depth = (png_byte)(row_info->channels * - row_info->bit_depth); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } - return rgb_error; -} -#endif - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) -/* Replace any alpha or transparency with the supplied background color. - * "background" is already in the screen gamma, while "background_1" is - * at a gamma of 1.0. Paletted files have already been taken care of. - */ -static void -png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) -{ -#ifdef PNG_READ_GAMMA_SUPPORTED - png_const_bytep gamma_table = png_ptr->gamma_table; - png_const_bytep gamma_from_1 = png_ptr->gamma_from_1; - png_const_bytep gamma_to_1 = png_ptr->gamma_to_1; - png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table; - png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1; - png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1; - int gamma_shift = png_ptr->gamma_shift; - int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; -#endif - - png_bytep sp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - int shift; - - png_debug(1, "in png_do_compose"); - - switch (row_info->color_type) - { - case PNG_COLOR_TYPE_GRAY: - { - switch (row_info->bit_depth) - { - case 1: - { - sp = row; - shift = 7; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x01) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); - tmp |= - (unsigned int)(png_ptr->background.gray << shift); - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 7; - sp++; - } - - else - shift--; - } - break; - } - - case 2: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) - { - sp = row; - shift = 6; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x03) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= - (unsigned int)png_ptr->background.gray << shift; - *sp = (png_byte)(tmp & 0xff); - } - - else - { - unsigned int p = (*sp >> shift) & 0x03; - unsigned int g = (gamma_table [p | (p << 2) | - (p << 4) | (p << 6)] >> 6) & 0x03; - unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= (unsigned int)(g << shift); - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 6; - sp++; - } - - else - shift -= 2; - } - } - - else -#endif - { - sp = row; - shift = 6; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x03) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= - (unsigned int)png_ptr->background.gray << shift; - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 6; - sp++; - } - - else - shift -= 2; - } - } - break; - } - - case 4: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) - { - sp = row; - shift = 4; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x0f) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); - tmp |= - (unsigned int)(png_ptr->background.gray << shift); - *sp = (png_byte)(tmp & 0xff); - } - - else - { - unsigned int p = (*sp >> shift) & 0x0f; - unsigned int g = (gamma_table[p | (p << 4)] >> 4) & - 0x0f; - unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); - tmp |= (unsigned int)(g << shift); - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 4; - sp++; - } - - else - shift -= 4; - } - } - - else -#endif - { - sp = row; - shift = 4; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x0f) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); - tmp |= - (unsigned int)(png_ptr->background.gray << shift); - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 4; - sp++; - } - - else - shift -= 4; - } - } - break; - } - - case 8: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp++) - { - if (*sp == png_ptr->trans_color.gray) - *sp = (png_byte)png_ptr->background.gray; - - else - *sp = gamma_table[*sp]; - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp++) - { - if (*sp == png_ptr->trans_color.gray) - *sp = (png_byte)png_ptr->background.gray; - } - } - break; - } - - case 16: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 2) - { - png_uint_16 v; - - v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - if (v == png_ptr->trans_color.gray) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.gray >> 8) - & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray - & 0xff); - } - - else - { - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 2) - { - png_uint_16 v; - - v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - if (v == png_ptr->trans_color.gray) - { - *sp = (png_byte)((png_ptr->background.gray >> 8) - & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray - & 0xff); - } - } - } - break; - } - - default: - break; - } - break; - } - - case PNG_COLOR_TYPE_RGB: - { - if (row_info->bit_depth == 8) - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 3) - { - if (*sp == png_ptr->trans_color.red && - *(sp + 1) == png_ptr->trans_color.green && - *(sp + 2) == png_ptr->trans_color.blue) - { - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } - - else - { - *sp = gamma_table[*sp]; - *(sp + 1) = gamma_table[*(sp + 1)]; - *(sp + 2) = gamma_table[*(sp + 2)]; - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 3) - { - if (*sp == png_ptr->trans_color.red && - *(sp + 1) == png_ptr->trans_color.green && - *(sp + 2) == png_ptr->trans_color.blue) - { - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } - } - } - } - else /* if (row_info->bit_depth == 16) */ - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 6) - { - png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) - + *(sp + 5)); - - if (r == png_ptr->trans_color.red && - g == png_ptr->trans_color.green && - b == png_ptr->trans_color.blue) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) - & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green - & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) - & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - - else - { - png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; - *(sp + 2) = (png_byte)((v >> 8) & 0xff); - *(sp + 3) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; - *(sp + 4) = (png_byte)((v >> 8) & 0xff); - *(sp + 5) = (png_byte)(v & 0xff); - } - } - } - - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 6) - { - png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) - + *(sp + 5)); - - if (r == png_ptr->trans_color.red && - g == png_ptr->trans_color.green && - b == png_ptr->trans_color.blue) - { - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) - & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green - & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) - & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - } - } - } - break; - } - - case PNG_COLOR_TYPE_GRAY_ALPHA: - { - if (row_info->bit_depth == 8) - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_to_1 != NULL && gamma_from_1 != NULL && - gamma_table != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 2) - { - png_uint_16 a = *(sp + 1); - - if (a == 0xff) - *sp = gamma_table[*sp]; - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)png_ptr->background.gray; - } - - else - { - png_byte v, w; - - v = gamma_to_1[*sp]; - png_composite(w, v, a, png_ptr->background_1.gray); - if (optimize == 0) - w = gamma_from_1[w]; - *sp = w; - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 2) - { - png_byte a = *(sp + 1); - - if (a == 0) - *sp = (png_byte)png_ptr->background.gray; - - else if (a < 0xff) - png_composite(*sp, *sp, a, png_ptr->background.gray); - } - } - } - else /* if (png_ptr->bit_depth == 16) */ - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL && gamma_16_from_1 != NULL && - gamma_16_to_1 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - if (a == (png_uint_16)0xffff) - { - png_uint_16 v; - - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - } - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.gray >> 8) - & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); - } - - else - { - png_uint_16 g, v, w; - - g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; - png_composite_16(v, g, a, png_ptr->background_1.gray); - if (optimize != 0) - w = v; - else - w = gamma_16_from_1[(v & 0xff) >> - gamma_shift][v >> 8]; - *sp = (png_byte)((w >> 8) & 0xff); - *(sp + 1) = (png_byte)(w & 0xff); - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - if (a == 0) - { - *sp = (png_byte)((png_ptr->background.gray >> 8) - & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); - } - - else if (a < 0xffff) - { - png_uint_16 g, v; - - g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - png_composite_16(v, g, a, png_ptr->background.gray); - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - } - } - } - } - break; - } - - case PNG_COLOR_TYPE_RGB_ALPHA: - { - if (row_info->bit_depth == 8) - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_to_1 != NULL && gamma_from_1 != NULL && - gamma_table != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_byte a = *(sp + 3); - - if (a == 0xff) - { - *sp = gamma_table[*sp]; - *(sp + 1) = gamma_table[*(sp + 1)]; - *(sp + 2) = gamma_table[*(sp + 2)]; - } - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } - - else - { - png_byte v, w; - - v = gamma_to_1[*sp]; - png_composite(w, v, a, png_ptr->background_1.red); - if (optimize == 0) w = gamma_from_1[w]; - *sp = w; - - v = gamma_to_1[*(sp + 1)]; - png_composite(w, v, a, png_ptr->background_1.green); - if (optimize == 0) w = gamma_from_1[w]; - *(sp + 1) = w; - - v = gamma_to_1[*(sp + 2)]; - png_composite(w, v, a, png_ptr->background_1.blue); - if (optimize == 0) w = gamma_from_1[w]; - *(sp + 2) = w; - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_byte a = *(sp + 3); - - if (a == 0) - { - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } - - else if (a < 0xff) - { - png_composite(*sp, *sp, a, png_ptr->background.red); - - png_composite(*(sp + 1), *(sp + 1), a, - png_ptr->background.green); - - png_composite(*(sp + 2), *(sp + 2), a, - png_ptr->background.blue); - } - } - } - } - else /* if (row_info->bit_depth == 16) */ - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL && gamma_16_from_1 != NULL && - gamma_16_to_1 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 8) - { - png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) - << 8) + (png_uint_16)(*(sp + 7))); - - if (a == (png_uint_16)0xffff) - { - png_uint_16 v; - - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; - *(sp + 2) = (png_byte)((v >> 8) & 0xff); - *(sp + 3) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; - *(sp + 4) = (png_byte)((v >> 8) & 0xff); - *(sp + 5) = (png_byte)(v & 0xff); - } - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) - & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green - & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) - & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - - else - { - png_uint_16 v, w; - - v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; - png_composite_16(w, v, a, png_ptr->background_1.red); - if (optimize == 0) - w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> - 8]; - *sp = (png_byte)((w >> 8) & 0xff); - *(sp + 1) = (png_byte)(w & 0xff); - - v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; - png_composite_16(w, v, a, png_ptr->background_1.green); - if (optimize == 0) - w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> - 8]; - - *(sp + 2) = (png_byte)((w >> 8) & 0xff); - *(sp + 3) = (png_byte)(w & 0xff); - - v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; - png_composite_16(w, v, a, png_ptr->background_1.blue); - if (optimize == 0) - w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> - 8]; - - *(sp + 4) = (png_byte)((w >> 8) & 0xff); - *(sp + 5) = (png_byte)(w & 0xff); - } - } - } - - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 8) - { - png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) - << 8) + (png_uint_16)(*(sp + 7))); - - if (a == 0) - { - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) - & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green - & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) - & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - - else if (a < 0xffff) - { - png_uint_16 v; - - png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) - + *(sp + 5)); - - png_composite_16(v, r, a, png_ptr->background.red); - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - - png_composite_16(v, g, a, png_ptr->background.green); - *(sp + 2) = (png_byte)((v >> 8) & 0xff); - *(sp + 3) = (png_byte)(v & 0xff); - - png_composite_16(v, b, a, png_ptr->background.blue); - *(sp + 4) = (png_byte)((v >> 8) & 0xff); - *(sp + 5) = (png_byte)(v & 0xff); - } - } - } - } - break; - } - - default: - break; - } -} -#endif /* READ_BACKGROUND || READ_ALPHA_MODE */ - -#ifdef PNG_READ_GAMMA_SUPPORTED -/* Gamma correct the image, avoiding the alpha channel. Make sure - * you do this after you deal with the transparency issue on grayscale - * or RGB images. If your bit depth is 8, use gamma_table, if it - * is 16, use gamma_16_table and gamma_shift. Build these with - * build_gamma_table(). - */ -static void -png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr) -{ - png_const_bytep gamma_table = png_ptr->gamma_table; - png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table; - int gamma_shift = png_ptr->gamma_shift; - - png_bytep sp; - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - png_debug(1, "in png_do_gamma"); - - if (((row_info->bit_depth <= 8 && gamma_table != NULL) || - (row_info->bit_depth == 16 && gamma_16_table != NULL))) - { - switch (row_info->color_type) - { - case PNG_COLOR_TYPE_RGB: - { - if (row_info->bit_depth == 8) - { - sp = row; - for (i = 0; i < row_width; i++) - { - *sp = gamma_table[*sp]; - sp++; - *sp = gamma_table[*sp]; - sp++; - *sp = gamma_table[*sp]; - sp++; - } - } - - else /* if (row_info->bit_depth == 16) */ - { - sp = row; - for (i = 0; i < row_width; i++) - { - png_uint_16 v; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - } - } - break; - } - - case PNG_COLOR_TYPE_RGB_ALPHA: - { - if (row_info->bit_depth == 8) - { - sp = row; - for (i = 0; i < row_width; i++) - { - *sp = gamma_table[*sp]; - sp++; - - *sp = gamma_table[*sp]; - sp++; - - *sp = gamma_table[*sp]; - sp++; - - sp++; - } - } - - else /* if (row_info->bit_depth == 16) */ - { - sp = row; - for (i = 0; i < row_width; i++) - { - png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - - v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 4; - } - } - break; - } - - case PNG_COLOR_TYPE_GRAY_ALPHA: - { - if (row_info->bit_depth == 8) - { - sp = row; - for (i = 0; i < row_width; i++) - { - *sp = gamma_table[*sp]; - sp += 2; - } - } - - else /* if (row_info->bit_depth == 16) */ - { - sp = row; - for (i = 0; i < row_width; i++) - { - png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 4; - } - } - break; - } - - case PNG_COLOR_TYPE_GRAY: - { - if (row_info->bit_depth == 2) - { - sp = row; - for (i = 0; i < row_width; i += 4) - { - int a = *sp & 0xc0; - int b = *sp & 0x30; - int c = *sp & 0x0c; - int d = *sp & 0x03; - - *sp = (png_byte)( - ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)| - ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)| - ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)| - ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) )); - sp++; - } - } - - if (row_info->bit_depth == 4) - { - sp = row; - for (i = 0; i < row_width; i += 2) - { - int msb = *sp & 0xf0; - int lsb = *sp & 0x0f; - - *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0) - | (((int)gamma_table[(lsb << 4) | lsb]) >> 4)); - sp++; - } - } - - else if (row_info->bit_depth == 8) - { - sp = row; - for (i = 0; i < row_width; i++) - { - *sp = gamma_table[*sp]; - sp++; - } - } - - else if (row_info->bit_depth == 16) - { - sp = row; - for (i = 0; i < row_width; i++) - { - png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - sp += 2; - } - } - break; - } - - default: - break; - } - } -} -#endif - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED -/* Encode the alpha channel to the output gamma (the input channel is always - * linear.) Called only with color types that have an alpha channel. Needs the - * from_1 tables. - */ -static void -png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) -{ - png_uint_32 row_width = row_info->width; - - png_debug(1, "in png_do_encode_alpha"); - - if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - if (row_info->bit_depth == 8) - { - png_bytep table = png_ptr->gamma_from_1; - - if (table != NULL) - { - int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; - - /* The alpha channel is the last component: */ - row += step - 1; - - for (; row_width > 0; --row_width, row += step) - *row = table[*row]; - - return; - } - } - - else if (row_info->bit_depth == 16) - { - png_uint_16pp table = png_ptr->gamma_16_from_1; - int gamma_shift = png_ptr->gamma_shift; - - if (table != NULL) - { - int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; - - /* The alpha channel is the last component: */ - row += step - 2; - - for (; row_width > 0; --row_width, row += step) - { - png_uint_16 v; - - v = table[*(row + 1) >> gamma_shift][*row]; - *row = (png_byte)((v >> 8) & 0xff); - *(row + 1) = (png_byte)(v & 0xff); - } - - return; - } - } - } - - /* Only get to here if called with a weird row_info; no harm has been done, - * so just issue a warning. - */ - png_warning(png_ptr, "png_do_encode_alpha: unexpected call"); -} -#endif - -#ifdef PNG_READ_EXPAND_SUPPORTED -/* Expands a palette row to an RGB or RGBA row depending - * upon whether you supply trans and num_trans. - */ -static void -png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info, - png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha, - int num_trans) -{ - int shift, value; - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - png_debug(1, "in png_do_expand_palette"); - - if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (row_info->bit_depth < 8) - { - switch (row_info->bit_depth) - { - case 1: - { - sp = row + (size_t)((row_width - 1) >> 3); - dp = row + (size_t)row_width - 1; - shift = 7 - (int)((row_width + 7) & 0x07); - for (i = 0; i < row_width; i++) - { - if ((*sp >> shift) & 0x01) - *dp = 1; - - else - *dp = 0; - - if (shift == 7) - { - shift = 0; - sp--; - } - - else - shift++; - - dp--; - } - break; - } - - case 2: - { - sp = row + (size_t)((row_width - 1) >> 2); - dp = row + (size_t)row_width - 1; - shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); - for (i = 0; i < row_width; i++) - { - value = (*sp >> shift) & 0x03; - *dp = (png_byte)value; - if (shift == 6) - { - shift = 0; - sp--; - } - - else - shift += 2; - - dp--; - } - break; - } - - case 4: - { - sp = row + (size_t)((row_width - 1) >> 1); - dp = row + (size_t)row_width - 1; - shift = (int)((row_width & 0x01) << 2); - for (i = 0; i < row_width; i++) - { - value = (*sp >> shift) & 0x0f; - *dp = (png_byte)value; - if (shift == 4) - { - shift = 0; - sp--; - } - - else - shift += 4; - - dp--; - } - break; - } - - default: - break; - } - row_info->bit_depth = 8; - row_info->pixel_depth = 8; - row_info->rowbytes = row_width; - } - - if (row_info->bit_depth == 8) - { - { - if (num_trans > 0) - { - sp = row + (size_t)row_width - 1; - dp = row + ((size_t)row_width << 2) - 1; - - i = 0; -#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE - if (png_ptr->riffled_palette != NULL) - { - /* The RGBA optimization works with png_ptr->bit_depth == 8 - * but sometimes row_info->bit_depth has been changed to 8. - * In these cases, the palette hasn't been riffled. - */ - i = png_do_expand_palette_rgba8_neon(png_ptr, row_info, row, - &sp, &dp); - } -#else - PNG_UNUSED(png_ptr) -#endif - - for (; i < row_width; i++) - { - if ((int)(*sp) >= num_trans) - *dp-- = 0xff; - else - *dp-- = trans_alpha[*sp]; - *dp-- = palette[*sp].blue; - *dp-- = palette[*sp].green; - *dp-- = palette[*sp].red; - sp--; - } - row_info->bit_depth = 8; - row_info->pixel_depth = 32; - row_info->rowbytes = row_width * 4; - row_info->color_type = 6; - row_info->channels = 4; - } - - else - { - sp = row + (size_t)row_width - 1; - dp = row + (size_t)(row_width * 3) - 1; - i = 0; -#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE - i = png_do_expand_palette_rgb8_neon(png_ptr, row_info, row, - &sp, &dp); -#else - PNG_UNUSED(png_ptr) -#endif - - for (; i < row_width; i++) - { - *dp-- = palette[*sp].blue; - *dp-- = palette[*sp].green; - *dp-- = palette[*sp].red; - sp--; - } - - row_info->bit_depth = 8; - row_info->pixel_depth = 24; - row_info->rowbytes = row_width * 3; - row_info->color_type = 2; - row_info->channels = 3; - } - } - } - } -} - -/* If the bit depth < 8, it is expanded to 8. Also, if the already - * expanded transparency value is supplied, an alpha channel is built. - */ -static void -png_do_expand(png_row_infop row_info, png_bytep row, - png_const_color_16p trans_color) -{ - int shift, value; - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - png_debug(1, "in png_do_expand"); - - if (row_info->color_type == PNG_COLOR_TYPE_GRAY) - { - unsigned int gray = trans_color != NULL ? trans_color->gray : 0; - - if (row_info->bit_depth < 8) - { - switch (row_info->bit_depth) - { - case 1: - { - gray = (gray & 0x01) * 0xff; - sp = row + (size_t)((row_width - 1) >> 3); - dp = row + (size_t)row_width - 1; - shift = 7 - (int)((row_width + 7) & 0x07); - for (i = 0; i < row_width; i++) - { - if ((*sp >> shift) & 0x01) - *dp = 0xff; - - else - *dp = 0; - - if (shift == 7) - { - shift = 0; - sp--; - } - - else - shift++; - - dp--; - } - break; - } - - case 2: - { - gray = (gray & 0x03) * 0x55; - sp = row + (size_t)((row_width - 1) >> 2); - dp = row + (size_t)row_width - 1; - shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); - for (i = 0; i < row_width; i++) - { - value = (*sp >> shift) & 0x03; - *dp = (png_byte)(value | (value << 2) | (value << 4) | - (value << 6)); - if (shift == 6) - { - shift = 0; - sp--; - } - - else - shift += 2; - - dp--; - } - break; - } - - case 4: - { - gray = (gray & 0x0f) * 0x11; - sp = row + (size_t)((row_width - 1) >> 1); - dp = row + (size_t)row_width - 1; - shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); - for (i = 0; i < row_width; i++) - { - value = (*sp >> shift) & 0x0f; - *dp = (png_byte)(value | (value << 4)); - if (shift == 4) - { - shift = 0; - sp--; - } - - else - shift = 4; - - dp--; - } - break; - } - - default: - break; - } - - row_info->bit_depth = 8; - row_info->pixel_depth = 8; - row_info->rowbytes = row_width; - } - - if (trans_color != NULL) - { - if (row_info->bit_depth == 8) - { - gray = gray & 0xff; - sp = row + (size_t)row_width - 1; - dp = row + ((size_t)row_width << 1) - 1; - - for (i = 0; i < row_width; i++) - { - if ((*sp & 0xffU) == gray) - *dp-- = 0; - - else - *dp-- = 0xff; - - *dp-- = *sp--; - } - } - - else if (row_info->bit_depth == 16) - { - unsigned int gray_high = (gray >> 8) & 0xff; - unsigned int gray_low = gray & 0xff; - sp = row + row_info->rowbytes - 1; - dp = row + (row_info->rowbytes << 1) - 1; - for (i = 0; i < row_width; i++) - { - if ((*(sp - 1) & 0xffU) == gray_high && - (*(sp) & 0xffU) == gray_low) - { - *dp-- = 0; - *dp-- = 0; - } - - else - { - *dp-- = 0xff; - *dp-- = 0xff; - } - - *dp-- = *sp--; - *dp-- = *sp--; - } - } - - row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; - row_info->channels = 2; - row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, - row_width); - } - } - else if (row_info->color_type == PNG_COLOR_TYPE_RGB && - trans_color != NULL) - { - if (row_info->bit_depth == 8) - { - png_byte red = (png_byte)(trans_color->red & 0xff); - png_byte green = (png_byte)(trans_color->green & 0xff); - png_byte blue = (png_byte)(trans_color->blue & 0xff); - sp = row + (size_t)row_info->rowbytes - 1; - dp = row + ((size_t)row_width << 2) - 1; - for (i = 0; i < row_width; i++) - { - if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) - *dp-- = 0; - - else - *dp-- = 0xff; - - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - } - } - else if (row_info->bit_depth == 16) - { - png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff); - png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff); - png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff); - png_byte red_low = (png_byte)(trans_color->red & 0xff); - png_byte green_low = (png_byte)(trans_color->green & 0xff); - png_byte blue_low = (png_byte)(trans_color->blue & 0xff); - sp = row + row_info->rowbytes - 1; - dp = row + ((size_t)row_width << 3) - 1; - for (i = 0; i < row_width; i++) - { - if (*(sp - 5) == red_high && - *(sp - 4) == red_low && - *(sp - 3) == green_high && - *(sp - 2) == green_low && - *(sp - 1) == blue_high && - *(sp ) == blue_low) - { - *dp-- = 0; - *dp-- = 0; - } - - else - { - *dp-- = 0xff; - *dp-- = 0xff; - } - - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - } - } - row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; - row_info->channels = 4; - row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } -} -#endif - -#ifdef PNG_READ_EXPAND_16_SUPPORTED -/* If the bit depth is 8 and the color type is not a palette type expand the - * whole row to 16 bits. Has no effect otherwise. - */ -static void -png_do_expand_16(png_row_infop row_info, png_bytep row) -{ - if (row_info->bit_depth == 8 && - row_info->color_type != PNG_COLOR_TYPE_PALETTE) - { - /* The row have a sequence of bytes containing [0..255] and we need - * to turn it into another row containing [0..65535], to do this we - * calculate: - * - * (input / 255) * 65535 - * - * Which happens to be exactly input * 257 and this can be achieved - * simply by byte replication in place (copying backwards). - */ - png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */ - png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */ - while (dp > sp) - { - dp[-2] = dp[-1] = *--sp; dp -= 2; - } - - row_info->rowbytes *= 2; - row_info->bit_depth = 16; - row_info->pixel_depth = (png_byte)(row_info->channels * 16); - } -} -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -static void -png_do_quantize(png_row_infop row_info, png_bytep row, - png_const_bytep palette_lookup, png_const_bytep quantize_lookup) -{ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width=row_info->width; - - png_debug(1, "in png_do_quantize"); - - if (row_info->bit_depth == 8) - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup) - { - int r, g, b, p; - sp = row; - dp = row; - for (i = 0; i < row_width; i++) - { - r = *sp++; - g = *sp++; - b = *sp++; - - /* This looks real messy, but the compiler will reduce - * it down to a reasonable formula. For example, with - * 5 bits per color, we get: - * p = (((r >> 3) & 0x1f) << 10) | - * (((g >> 3) & 0x1f) << 5) | - * ((b >> 3) & 0x1f); - */ - p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & - ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << - (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | - (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & - ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << - (PNG_QUANTIZE_BLUE_BITS)) | - ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & - ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); - - *dp++ = palette_lookup[p]; - } - - row_info->color_type = PNG_COLOR_TYPE_PALETTE; - row_info->channels = 1; - row_info->pixel_depth = row_info->bit_depth; - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && - palette_lookup != NULL) - { - int r, g, b, p; - sp = row; - dp = row; - for (i = 0; i < row_width; i++) - { - r = *sp++; - g = *sp++; - b = *sp++; - sp++; - - p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & - ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << - (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | - (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & - ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << - (PNG_QUANTIZE_BLUE_BITS)) | - ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & - ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); - - *dp++ = palette_lookup[p]; - } - - row_info->color_type = PNG_COLOR_TYPE_PALETTE; - row_info->channels = 1; - row_info->pixel_depth = row_info->bit_depth; - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); - } - - else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && - quantize_lookup) - { - sp = row; - - for (i = 0; i < row_width; i++, sp++) - { - *sp = quantize_lookup[*sp]; - } - } - } -} -#endif /* READ_QUANTIZE */ - -/* Transform the row. The order of transformations is significant, - * and is very touchy. If you add a transformation, take care to - * decide how it fits in with the other transformations here. - */ -void /* PRIVATE */ -png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) -{ - png_debug(1, "in png_do_read_transformations"); - - if (png_ptr->row_buf == NULL) - { - /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this - * error is incredibly rare and incredibly easy to debug without this - * information. - */ - png_error(png_ptr, "NULL row buffer"); - } - - /* The following is debugging; prior to 1.5.4 the code was never compiled in; - * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro - * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for - * all transformations, however in practice the ROW_INIT always gets done on - * demand, if necessary. - */ - if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 && - (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0) - { - /* Application has failed to call either png_read_start_image() or - * png_read_update_info() after setting transforms that expand pixels. - * This check added to libpng-1.2.19 (but not enabled until 1.5.4). - */ - png_error(png_ptr, "Uninitialized row"); - } - -#ifdef PNG_READ_EXPAND_SUPPORTED - if ((png_ptr->transformations & PNG_EXPAND) != 0) - { - if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) - { -#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE - if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8)) - { - if (png_ptr->riffled_palette == NULL) - { - /* Initialize the accelerated palette expansion. */ - png_ptr->riffled_palette = - (png_bytep)png_malloc(png_ptr, 256 * 4); - png_riffle_palette_neon(png_ptr); - } - } -#endif - png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1, - png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); - } - - else - { - if (png_ptr->num_trans != 0 && - (png_ptr->transformations & PNG_EXPAND_tRNS) != 0) - png_do_expand(row_info, png_ptr->row_buf + 1, - &(png_ptr->trans_color)); - - else - png_do_expand(row_info, png_ptr->row_buf + 1, NULL); - } - } -#endif - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && - (png_ptr->transformations & PNG_COMPOSE) == 0 && - (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) - png_do_strip_channel(row_info, png_ptr->row_buf + 1, - 0 /* at_start == false, because SWAP_ALPHA happens later */); -#endif - -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0) - { - int rgb_error = - png_do_rgb_to_gray(png_ptr, row_info, - png_ptr->row_buf + 1); - - if (rgb_error != 0) - { - png_ptr->rgb_to_gray_status=1; - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == - PNG_RGB_TO_GRAY_WARN) - png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); - - if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == - PNG_RGB_TO_GRAY_ERR) - png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); - } - } -#endif - -/* From Andreas Dilger e-mail to png-implement, 26 March 1998: - * - * In most cases, the "simple transparency" should be done prior to doing - * gray-to-RGB, or you will have to test 3x as many bytes to check if a - * pixel is transparent. You would also need to make sure that the - * transparency information is upgraded to RGB. - * - * To summarize, the current flow is: - * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite - * with background "in place" if transparent, - * convert to RGB if necessary - * - Gray + alpha -> composite with gray background and remove alpha bytes, - * convert to RGB if necessary - * - * To support RGB backgrounds for gray images we need: - * - Gray + simple transparency -> convert to RGB + simple transparency, - * compare 3 or 6 bytes and composite with - * background "in place" if transparent - * (3x compare/pixel compared to doing - * composite with gray bkgrnd) - * - Gray + alpha -> convert to RGB + alpha, composite with background and - * remove alpha bytes (3x float - * operations/pixel compared with composite - * on gray background) - * - * Greg's change will do this. The reason it wasn't done before is for - * performance, as this increases the per-pixel operations. If we would check - * in advance if the background was gray or RGB, and position the gray-to-RGB - * transform appropriately, then it would save a lot of work/time. - */ - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /* If gray -> RGB, do so now only if background is non-gray; else do later - * for performance reasons - */ - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && - (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0) - png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); -#endif - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) - if ((png_ptr->transformations & PNG_COMPOSE) != 0) - png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED - if ((png_ptr->transformations & PNG_GAMMA) != 0 && -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - /* Because RGB_TO_GRAY does the gamma transform. */ - (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 && -#endif -#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) - /* Because PNG_COMPOSE does the gamma transform if there is something to - * do (if there is an alpha channel or transparency.) - */ - !((png_ptr->transformations & PNG_COMPOSE) != 0 && - ((png_ptr->num_trans != 0) || - (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) && -#endif - /* Because png_init_read_transformations transforms the palette, unless - * RGB_TO_GRAY will do the transform. - */ - (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) - png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 && - (png_ptr->transformations & PNG_COMPOSE) != 0 && - (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA || - row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)) - png_do_strip_channel(row_info, png_ptr->row_buf + 1, - 0 /* at_start == false, because SWAP_ALPHA happens later */); -#endif - -#ifdef PNG_READ_ALPHA_MODE_SUPPORTED - if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 && - (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) - png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr); -#endif - -#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED - if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0) - png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED - /* There is no harm in doing both of these because only one has any effect, - * by putting the 'scale' option first if the app asks for scale (either by - * calling the API or in a TRANSFORM flag) this is what happens. - */ - if ((png_ptr->transformations & PNG_16_TO_8) != 0) - png_do_chop(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - if ((png_ptr->transformations & PNG_QUANTIZE) != 0) - { - png_do_quantize(row_info, png_ptr->row_buf + 1, - png_ptr->palette_lookup, png_ptr->quantize_index); - - if (row_info->rowbytes == 0) - png_error(png_ptr, "png_do_quantize returned rowbytes=0"); - } -#endif /* READ_QUANTIZE */ - -#ifdef PNG_READ_EXPAND_16_SUPPORTED - /* Do the expansion now, after all the arithmetic has been done. Notice - * that previous transformations can handle the PNG_EXPAND_16 flag if this - * is efficient (particularly true in the case of gamma correction, where - * better accuracy results faster!) - */ - if ((png_ptr->transformations & PNG_EXPAND_16) != 0) - png_do_expand_16(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /* NOTE: moved here in 1.5.4 (from much later in this list.) */ - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 && - (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0) - png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_INVERT_SUPPORTED - if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) - png_do_invert(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) - png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_SHIFT_SUPPORTED - if ((png_ptr->transformations & PNG_SHIFT) != 0) - png_do_unshift(row_info, png_ptr->row_buf + 1, - &(png_ptr->shift)); -#endif - -#ifdef PNG_READ_PACK_SUPPORTED - if ((png_ptr->transformations & PNG_PACK) != 0) - png_do_unpack(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED - /* Added at libpng-1.5.10 */ - if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && - png_ptr->num_palette_max >= 0) - png_do_check_palette_indexes(png_ptr, row_info); -#endif - -#ifdef PNG_READ_BGR_SUPPORTED - if ((png_ptr->transformations & PNG_BGR) != 0) - png_do_bgr(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - png_do_packswap(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_FILLER_SUPPORTED - if ((png_ptr->transformations & PNG_FILLER) != 0) - png_do_read_filler(row_info, png_ptr->row_buf + 1, - (png_uint_32)png_ptr->filler, png_ptr->flags); -#endif - -#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) - png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_READ_16BIT_SUPPORTED -#ifdef PNG_READ_SWAP_SUPPORTED - if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) - png_do_swap(row_info, png_ptr->row_buf + 1); -#endif -#endif - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) - { - if (png_ptr->read_user_transform_fn != NULL) - (*(png_ptr->read_user_transform_fn)) /* User read transform function */ - (png_ptr, /* png_ptr */ - row_info, /* row_info: */ - /* png_uint_32 width; width of row */ - /* size_t rowbytes; number of bytes in row */ - /* png_byte color_type; color type of pixels */ - /* png_byte bit_depth; bit depth of samples */ - /* png_byte channels; number of channels (1-4) */ - /* png_byte pixel_depth; bits per pixel (depth*channels) */ - png_ptr->row_buf + 1); /* start of pixel data for row */ -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED - if (png_ptr->user_transform_depth != 0) - row_info->bit_depth = png_ptr->user_transform_depth; - - if (png_ptr->user_transform_channels != 0) - row_info->channels = png_ptr->user_transform_channels; -#endif - row_info->pixel_depth = (png_byte)(row_info->bit_depth * - row_info->channels); - - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width); - } -#endif -} - -#endif /* READ_TRANSFORMS */ -#endif /* READ */ diff --git a/extern/libpng/pngrutil.c b/extern/libpng/pngrutil.c deleted file mode 100644 index d5fa08c39..000000000 --- a/extern/libpng/pngrutil.c +++ /dev/null @@ -1,4681 +0,0 @@ - -/* pngrutil.c - utilities to read a PNG file - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file contains routines that are only called from within - * libpng itself during the course of reading an image. - */ - -#include "pngpriv.h" - -#ifdef PNG_READ_SUPPORTED - -png_uint_32 PNGAPI -png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf) -{ - png_uint_32 uval = png_get_uint_32(buf); - - if (uval > PNG_UINT_31_MAX) - png_error(png_ptr, "PNG unsigned integer out of range"); - - return (uval); -} - -#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED) -/* The following is a variation on the above for use with the fixed - * point values used for gAMA and cHRM. Instead of png_error it - * issues a warning and returns (-1) - an invalid value because both - * gAMA and cHRM use *unsigned* integers for fixed point values. - */ -#define PNG_FIXED_ERROR (-1) - -static png_fixed_point /* PRIVATE */ -png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf) -{ - png_uint_32 uval = png_get_uint_32(buf); - - if (uval <= PNG_UINT_31_MAX) - return (png_fixed_point)uval; /* known to be in range */ - - /* The caller can turn off the warning by passing NULL. */ - if (png_ptr != NULL) - png_warning(png_ptr, "PNG fixed point integer out of range"); - - return PNG_FIXED_ERROR; -} -#endif - -#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED -/* NOTE: the read macros will obscure these definitions, so that if - * PNG_USE_READ_MACROS is set the library will not use them internally, - * but the APIs will still be available externally. - * - * The parentheses around "PNGAPI function_name" in the following three - * functions are necessary because they allow the macros to co-exist with - * these (unused but exported) functions. - */ - -/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ -png_uint_32 (PNGAPI -png_get_uint_32)(png_const_bytep buf) -{ - png_uint_32 uval = - ((png_uint_32)(*(buf )) << 24) + - ((png_uint_32)(*(buf + 1)) << 16) + - ((png_uint_32)(*(buf + 2)) << 8) + - ((png_uint_32)(*(buf + 3)) ) ; - - return uval; -} - -/* Grab a signed 32-bit integer from a buffer in big-endian format. The - * data is stored in the PNG file in two's complement format and there - * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore - * the following code does a two's complement to native conversion. - */ -png_int_32 (PNGAPI -png_get_int_32)(png_const_bytep buf) -{ - png_uint_32 uval = png_get_uint_32(buf); - if ((uval & 0x80000000) == 0) /* non-negative */ - return (png_int_32)uval; - - uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */ - if ((uval & 0x80000000) == 0) /* no overflow */ - return -(png_int_32)uval; - /* The following has to be safe; this function only gets called on PNG data - * and if we get here that data is invalid. 0 is the most safe value and - * if not then an attacker would surely just generate a PNG with 0 instead. - */ - return 0; -} - -/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ -png_uint_16 (PNGAPI -png_get_uint_16)(png_const_bytep buf) -{ - /* ANSI-C requires an int value to accommodate at least 16 bits so this - * works and allows the compiler not to worry about possible narrowing - * on 32-bit systems. (Pre-ANSI systems did not make integers smaller - * than 16 bits either.) - */ - unsigned int val = - ((unsigned int)(*buf) << 8) + - ((unsigned int)(*(buf + 1))); - - return (png_uint_16)val; -} - -#endif /* READ_INT_FUNCTIONS */ - -/* Read and check the PNG file signature */ -void /* PRIVATE */ -png_read_sig(png_structrp png_ptr, png_inforp info_ptr) -{ - size_t num_checked, num_to_check; - - /* Exit if the user application does not expect a signature. */ - if (png_ptr->sig_bytes >= 8) - return; - - num_checked = png_ptr->sig_bytes; - num_to_check = 8 - num_checked; - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE; -#endif - - /* The signature must be serialized in a single I/O call. */ - png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check); - png_ptr->sig_bytes = 8; - - if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0) - { - if (num_checked < 4 && - png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) - png_error(png_ptr, "Not a PNG file"); - else - png_error(png_ptr, "PNG file corrupted by ASCII conversion"); - } - if (num_checked < 3) - png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; -} - -/* Read the chunk header (length + type name). - * Put the type name into png_ptr->chunk_name, and return the length. - */ -png_uint_32 /* PRIVATE */ -png_read_chunk_header(png_structrp png_ptr) -{ - png_byte buf[8]; - png_uint_32 length; - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR; -#endif - - /* Read the length and the chunk name. - * This must be performed in a single I/O call. - */ - png_read_data(png_ptr, buf, 8); - length = png_get_uint_31(png_ptr, buf); - - /* Put the chunk name into png_ptr->chunk_name. */ - png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); - - png_debug2(0, "Reading %lx chunk, length = %lu", - (unsigned long)png_ptr->chunk_name, (unsigned long)length); - - /* Reset the crc and run it over the chunk name. */ - png_reset_crc(png_ptr); - png_calculate_crc(png_ptr, buf + 4, 4); - - /* Check to see if chunk name is valid. */ - png_check_chunk_name(png_ptr, png_ptr->chunk_name); - - /* Check for too-large chunk length */ - png_check_chunk_length(png_ptr, length); - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; -#endif - - return length; -} - -/* Read data, and (optionally) run it through the CRC. */ -void /* PRIVATE */ -png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length) -{ - if (png_ptr == NULL) - return; - - png_read_data(png_ptr, buf, length); - png_calculate_crc(png_ptr, buf, length); -} - -/* Optionally skip data and then check the CRC. Depending on whether we - * are reading an ancillary or critical chunk, and how the program has set - * things up, we may calculate the CRC on the data and print a message. - * Returns '1' if there was a CRC error, '0' otherwise. - */ -int /* PRIVATE */ -png_crc_finish(png_structrp png_ptr, png_uint_32 skip) -{ - /* The size of the local buffer for inflate is a good guess as to a - * reasonable size to use for buffering reads from the application. - */ - while (skip > 0) - { - png_uint_32 len; - png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; - - len = (sizeof tmpbuf); - if (len > skip) - len = skip; - skip -= len; - - png_crc_read(png_ptr, tmpbuf, len); - } - - if (png_crc_error(png_ptr) != 0) - { - if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ? - (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0 : - (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE) != 0) - { - png_chunk_warning(png_ptr, "CRC error"); - } - - else - png_chunk_error(png_ptr, "CRC error"); - - return (1); - } - - return (0); -} - -/* Compare the CRC stored in the PNG file with that calculated by libpng from - * the data it has read thus far. - */ -int /* PRIVATE */ -png_crc_error(png_structrp png_ptr) -{ - png_byte crc_bytes[4]; - png_uint_32 crc; - int need_crc = 1; - - if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0) - { - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == - (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) - need_crc = 0; - } - - else /* critical */ - { - if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0) - need_crc = 0; - } - -#ifdef PNG_IO_STATE_SUPPORTED - png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC; -#endif - - /* The chunk CRC must be serialized in a single I/O call. */ - png_read_data(png_ptr, crc_bytes, 4); - - if (need_crc != 0) - { - crc = png_get_uint_32(crc_bytes); - return ((int)(crc != png_ptr->crc)); - } - - else - return (0); -} - -#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ - defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\ - defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\ - defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED) -/* Manage the read buffer; this simply reallocates the buffer if it is not small - * enough (or if it is not allocated). The routine returns a pointer to the - * buffer; if an error occurs and 'warn' is set the routine returns NULL, else - * it will call png_error (via png_malloc) on failure. (warn == 2 means - * 'silent'). - */ -static png_bytep -png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn) -{ - png_bytep buffer = png_ptr->read_buffer; - - if (buffer != NULL && new_size > png_ptr->read_buffer_size) - { - png_ptr->read_buffer = NULL; - png_ptr->read_buffer = NULL; - png_ptr->read_buffer_size = 0; - png_free(png_ptr, buffer); - buffer = NULL; - } - - if (buffer == NULL) - { - buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size)); - - if (buffer != NULL) - { - memset(buffer, 0, new_size); /* just in case */ - png_ptr->read_buffer = buffer; - png_ptr->read_buffer_size = new_size; - } - - else if (warn < 2) /* else silent */ - { - if (warn != 0) - png_chunk_warning(png_ptr, "insufficient memory to read chunk"); - - else - png_chunk_error(png_ptr, "insufficient memory to read chunk"); - } - } - - return buffer; -} -#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */ - -/* png_inflate_claim: claim the zstream for some nefarious purpose that involves - * decompression. Returns Z_OK on success, else a zlib error code. It checks - * the owner but, in final release builds, just issues a warning if some other - * chunk apparently owns the stream. Prior to release it does a png_error. - */ -static int -png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) -{ - if (png_ptr->zowner != 0) - { - char msg[64]; - - PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner); - /* So the message that results is " using zstream"; this is an - * internal error, but is very useful for debugging. i18n requirements - * are minimal. - */ - (void)png_safecat(msg, (sizeof msg), 4, " using zstream"); -#if PNG_RELEASE_BUILD - png_chunk_warning(png_ptr, msg); - png_ptr->zowner = 0; -#else - png_chunk_error(png_ptr, msg); -#endif - } - - /* Implementation note: unlike 'png_deflate_claim' this internal function - * does not take the size of the data as an argument. Some efficiency could - * be gained by using this when it is known *if* the zlib stream itself does - * not record the number; however, this is an illusion: the original writer - * of the PNG may have selected a lower window size, and we really must - * follow that because, for systems with with limited capabilities, we - * would otherwise reject the application's attempts to use a smaller window - * size (zlib doesn't have an interface to say "this or lower"!). - * - * inflateReset2 was added to zlib 1.2.4; before this the window could not be - * reset, therefore it is necessary to always allocate the maximum window - * size with earlier zlibs just in case later compressed chunks need it. - */ - { - int ret; /* zlib return code */ -#if ZLIB_VERNUM >= 0x1240 - int window_bits = 0; - -# if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW) - if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) == - PNG_OPTION_ON) - { - window_bits = 15; - png_ptr->zstream_start = 0; /* fixed window size */ - } - - else - { - png_ptr->zstream_start = 1; - } -# endif - -#endif /* ZLIB_VERNUM >= 0x1240 */ - - /* Set this for safety, just in case the previous owner left pointers to - * memory allocations. - */ - png_ptr->zstream.next_in = NULL; - png_ptr->zstream.avail_in = 0; - png_ptr->zstream.next_out = NULL; - png_ptr->zstream.avail_out = 0; - - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) - { -#if ZLIB_VERNUM >= 0x1240 - ret = inflateReset2(&png_ptr->zstream, window_bits); -#else - ret = inflateReset(&png_ptr->zstream); -#endif - } - - else - { -#if ZLIB_VERNUM >= 0x1240 - ret = inflateInit2(&png_ptr->zstream, window_bits); -#else - ret = inflateInit(&png_ptr->zstream); -#endif - - if (ret == Z_OK) - png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; - } - -#if ZLIB_VERNUM >= 0x1290 && \ - defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32) - if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON) - /* Turn off validation of the ADLER32 checksum in IDAT chunks */ - ret = inflateValidate(&png_ptr->zstream, 0); -#endif - - if (ret == Z_OK) - png_ptr->zowner = owner; - - else - png_zstream_error(png_ptr, ret); - - return ret; - } - -#ifdef window_bits -# undef window_bits -#endif -} - -#if ZLIB_VERNUM >= 0x1240 -/* Handle the start of the inflate stream if we called inflateInit2(strm,0); - * in this case some zlib versions skip validation of the CINFO field and, in - * certain circumstances, libpng may end up displaying an invalid image, in - * contrast to implementations that call zlib in the normal way (e.g. libpng - * 1.5). - */ -int /* PRIVATE */ -png_zlib_inflate(png_structrp png_ptr, int flush) -{ - if (png_ptr->zstream_start && png_ptr->zstream.avail_in > 0) - { - if ((*png_ptr->zstream.next_in >> 4) > 7) - { - png_ptr->zstream.msg = "invalid window size (libpng)"; - return Z_DATA_ERROR; - } - - png_ptr->zstream_start = 0; - } - - return inflate(&png_ptr->zstream, flush); -} -#endif /* Zlib >= 1.2.4 */ - -#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED -#if defined(PNG_READ_zTXt_SUPPORTED) || defined (PNG_READ_iTXt_SUPPORTED) -/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to - * allow the caller to do multiple calls if required. If the 'finish' flag is - * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must - * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and - * Z_OK or Z_STREAM_END will be returned on success. - * - * The input and output sizes are updated to the actual amounts of data consumed - * or written, not the amount available (as in a z_stream). The data pointers - * are not changed, so the next input is (data+input_size) and the next - * available output is (output+output_size). - */ -static int -png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish, - /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr, - /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr) -{ - if (png_ptr->zowner == owner) /* Else not claimed */ - { - int ret; - png_alloc_size_t avail_out = *output_size_ptr; - png_uint_32 avail_in = *input_size_ptr; - - /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it - * can't even necessarily handle 65536 bytes) because the type uInt is - * "16 bits or more". Consequently it is necessary to chunk the input to - * zlib. This code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the - * maximum value that can be stored in a uInt.) It is possible to set - * ZLIB_IO_MAX to a lower value in pngpriv.h and this may sometimes have - * a performance advantage, because it reduces the amount of data accessed - * at each step and that may give the OS more time to page it in. - */ - png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); - /* avail_in and avail_out are set below from 'size' */ - png_ptr->zstream.avail_in = 0; - png_ptr->zstream.avail_out = 0; - - /* Read directly into the output if it is available (this is set to - * a local buffer below if output is NULL). - */ - if (output != NULL) - png_ptr->zstream.next_out = output; - - do - { - uInt avail; - Byte local_buffer[PNG_INFLATE_BUF_SIZE]; - - /* zlib INPUT BUFFER */ - /* The setting of 'avail_in' used to be outside the loop; by setting it - * inside it is possible to chunk the input to zlib and simply rely on - * zlib to advance the 'next_in' pointer. This allows arbitrary - * amounts of data to be passed through zlib at the unavoidable cost of - * requiring a window save (memcpy of up to 32768 output bytes) - * every ZLIB_IO_MAX input bytes. - */ - avail_in += png_ptr->zstream.avail_in; /* not consumed last time */ - - avail = ZLIB_IO_MAX; - - if (avail_in < avail) - avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */ - - avail_in -= avail; - png_ptr->zstream.avail_in = avail; - - /* zlib OUTPUT BUFFER */ - avail_out += png_ptr->zstream.avail_out; /* not written last time */ - - avail = ZLIB_IO_MAX; /* maximum zlib can process */ - - if (output == NULL) - { - /* Reset the output buffer each time round if output is NULL and - * make available the full buffer, up to 'remaining_space' - */ - png_ptr->zstream.next_out = local_buffer; - if ((sizeof local_buffer) < avail) - avail = (sizeof local_buffer); - } - - if (avail_out < avail) - avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */ - - png_ptr->zstream.avail_out = avail; - avail_out -= avail; - - /* zlib inflate call */ - /* In fact 'avail_out' may be 0 at this point, that happens at the end - * of the read when the final LZ end code was not passed at the end of - * the previous chunk of input data. Tell zlib if we have reached the - * end of the output buffer. - */ - ret = PNG_INFLATE(png_ptr, avail_out > 0 ? Z_NO_FLUSH : - (finish ? Z_FINISH : Z_SYNC_FLUSH)); - } while (ret == Z_OK); - - /* For safety kill the local buffer pointer now */ - if (output == NULL) - png_ptr->zstream.next_out = NULL; - - /* Claw back the 'size' and 'remaining_space' byte counts. */ - avail_in += png_ptr->zstream.avail_in; - avail_out += png_ptr->zstream.avail_out; - - /* Update the input and output sizes; the updated values are the amount - * consumed or written, effectively the inverse of what zlib uses. - */ - if (avail_out > 0) - *output_size_ptr -= avail_out; - - if (avail_in > 0) - *input_size_ptr -= avail_in; - - /* Ensure png_ptr->zstream.msg is set (even in the success case!) */ - png_zstream_error(png_ptr, ret); - return ret; - } - - else - { - /* This is a bad internal error. The recovery assigns to the zstream msg - * pointer, which is not owned by the caller, but this is safe; it's only - * used on errors! - */ - png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); - return Z_STREAM_ERROR; - } -} - -/* - * Decompress trailing data in a chunk. The assumption is that read_buffer - * points at an allocated area holding the contents of a chunk with a - * trailing compressed part. What we get back is an allocated area - * holding the original prefix part and an uncompressed version of the - * trailing part (the malloc area passed in is freed). - */ -static int -png_decompress_chunk(png_structrp png_ptr, - png_uint_32 chunklength, png_uint_32 prefix_size, - png_alloc_size_t *newlength /* must be initialized to the maximum! */, - int terminate /*add a '\0' to the end of the uncompressed data*/) -{ - /* TODO: implement different limits for different types of chunk. - * - * The caller supplies *newlength set to the maximum length of the - * uncompressed data, but this routine allocates space for the prefix and - * maybe a '\0' terminator too. We have to assume that 'prefix_size' is - * limited only by the maximum chunk size. - */ - png_alloc_size_t limit = PNG_SIZE_MAX; - -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < limit) - limit = png_ptr->user_chunk_malloc_max; -# elif PNG_USER_CHUNK_MALLOC_MAX > 0 - if (PNG_USER_CHUNK_MALLOC_MAX < limit) - limit = PNG_USER_CHUNK_MALLOC_MAX; -# endif - - if (limit >= prefix_size + (terminate != 0)) - { - int ret; - - limit -= prefix_size + (terminate != 0); - - if (limit < *newlength) - *newlength = limit; - - /* Now try to claim the stream. */ - ret = png_inflate_claim(png_ptr, png_ptr->chunk_name); - - if (ret == Z_OK) - { - png_uint_32 lzsize = chunklength - prefix_size; - - ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, - /* input: */ png_ptr->read_buffer + prefix_size, &lzsize, - /* output: */ NULL, newlength); - - if (ret == Z_STREAM_END) - { - /* Use 'inflateReset' here, not 'inflateReset2' because this - * preserves the previously decided window size (otherwise it would - * be necessary to store the previous window size.) In practice - * this doesn't matter anyway, because png_inflate will call inflate - * with Z_FINISH in almost all cases, so the window will not be - * maintained. - */ - if (inflateReset(&png_ptr->zstream) == Z_OK) - { - /* Because of the limit checks above we know that the new, - * expanded, size will fit in a size_t (let alone an - * png_alloc_size_t). Use png_malloc_base here to avoid an - * extra OOM message. - */ - png_alloc_size_t new_size = *newlength; - png_alloc_size_t buffer_size = prefix_size + new_size + - (terminate != 0); - png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr, - buffer_size)); - - if (text != NULL) - { - memset(text, 0, buffer_size); - - ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/, - png_ptr->read_buffer + prefix_size, &lzsize, - text + prefix_size, newlength); - - if (ret == Z_STREAM_END) - { - if (new_size == *newlength) - { - if (terminate != 0) - text[prefix_size + *newlength] = 0; - - if (prefix_size > 0) - memcpy(text, png_ptr->read_buffer, prefix_size); - - { - png_bytep old_ptr = png_ptr->read_buffer; - - png_ptr->read_buffer = text; - png_ptr->read_buffer_size = buffer_size; - text = old_ptr; /* freed below */ - } - } - - else - { - /* The size changed on the second read, there can be no - * guarantee that anything is correct at this point. - * The 'msg' pointer has been set to "unexpected end of - * LZ stream", which is fine, but return an error code - * that the caller won't accept. - */ - ret = PNG_UNEXPECTED_ZLIB_RETURN; - } - } - - else if (ret == Z_OK) - ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */ - - /* Free the text pointer (this is the old read_buffer on - * success) - */ - png_free(png_ptr, text); - - /* This really is very benign, but it's still an error because - * the extra space may otherwise be used as a Trojan Horse. - */ - if (ret == Z_STREAM_END && - chunklength - prefix_size != lzsize) - png_chunk_benign_error(png_ptr, "extra compressed data"); - } - - else - { - /* Out of memory allocating the buffer */ - ret = Z_MEM_ERROR; - png_zstream_error(png_ptr, Z_MEM_ERROR); - } - } - - else - { - /* inflateReset failed, store the error message */ - png_zstream_error(png_ptr, ret); - ret = PNG_UNEXPECTED_ZLIB_RETURN; - } - } - - else if (ret == Z_OK) - ret = PNG_UNEXPECTED_ZLIB_RETURN; - - /* Release the claimed stream */ - png_ptr->zowner = 0; - } - - else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */ - ret = PNG_UNEXPECTED_ZLIB_RETURN; - - return ret; - } - - else - { - /* Application/configuration limits exceeded */ - png_zstream_error(png_ptr, Z_MEM_ERROR); - return Z_MEM_ERROR; - } -} -#endif /* READ_zTXt || READ_iTXt */ -#endif /* READ_COMPRESSED_TEXT */ - -#ifdef PNG_READ_iCCP_SUPPORTED -/* Perform a partial read and decompress, producing 'avail_out' bytes and - * reading from the current chunk as required. - */ -static int -png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size, - png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size, - int finish) -{ - if (png_ptr->zowner == png_ptr->chunk_name) - { - int ret; - - /* next_in and avail_in must have been initialized by the caller. */ - png_ptr->zstream.next_out = next_out; - png_ptr->zstream.avail_out = 0; /* set in the loop */ - - do - { - if (png_ptr->zstream.avail_in == 0) - { - if (read_size > *chunk_bytes) - read_size = (uInt)*chunk_bytes; - *chunk_bytes -= read_size; - - if (read_size > 0) - png_crc_read(png_ptr, read_buffer, read_size); - - png_ptr->zstream.next_in = read_buffer; - png_ptr->zstream.avail_in = read_size; - } - - if (png_ptr->zstream.avail_out == 0) - { - uInt avail = ZLIB_IO_MAX; - if (avail > *out_size) - avail = (uInt)*out_size; - *out_size -= avail; - - png_ptr->zstream.avail_out = avail; - } - - /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all - * the available output is produced; this allows reading of truncated - * streams. - */ - ret = PNG_INFLATE(png_ptr, *chunk_bytes > 0 ? - Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); - } - while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0)); - - *out_size += png_ptr->zstream.avail_out; - png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */ - - /* Ensure the error message pointer is always set: */ - png_zstream_error(png_ptr, ret); - return ret; - } - - else - { - png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed"); - return Z_STREAM_ERROR; - } -} -#endif /* READ_iCCP */ - -/* Read and check the IDHR chunk */ - -void /* PRIVATE */ -png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_byte buf[13]; - png_uint_32 width, height; - int bit_depth, color_type, compression_type, filter_type; - int interlace_type; - - png_debug(1, "in png_handle_IHDR"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) != 0) - png_chunk_error(png_ptr, "out of place"); - - /* Check the length */ - if (length != 13) - png_chunk_error(png_ptr, "invalid"); - - png_ptr->mode |= PNG_HAVE_IHDR; - - png_crc_read(png_ptr, buf, 13); - png_crc_finish(png_ptr, 0); - - width = png_get_uint_31(png_ptr, buf); - height = png_get_uint_31(png_ptr, buf + 4); - bit_depth = buf[8]; - color_type = buf[9]; - compression_type = buf[10]; - filter_type = buf[11]; - interlace_type = buf[12]; - - /* Set internal variables */ - png_ptr->width = width; - png_ptr->height = height; - png_ptr->bit_depth = (png_byte)bit_depth; - png_ptr->interlaced = (png_byte)interlace_type; - png_ptr->color_type = (png_byte)color_type; -#ifdef PNG_MNG_FEATURES_SUPPORTED - png_ptr->filter_type = (png_byte)filter_type; -#endif - png_ptr->compression_type = (png_byte)compression_type; - - /* Find number of channels */ - switch (png_ptr->color_type) - { - default: /* invalid, png_set_IHDR calls png_error */ - case PNG_COLOR_TYPE_GRAY: - case PNG_COLOR_TYPE_PALETTE: - png_ptr->channels = 1; - break; - - case PNG_COLOR_TYPE_RGB: - png_ptr->channels = 3; - break; - - case PNG_COLOR_TYPE_GRAY_ALPHA: - png_ptr->channels = 2; - break; - - case PNG_COLOR_TYPE_RGB_ALPHA: - png_ptr->channels = 4; - break; - } - - /* Set up other useful info */ - png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->channels); - png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); - png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); - png_debug1(3, "channels = %d", png_ptr->channels); - png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes); - png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, - color_type, interlace_type, compression_type, filter_type); -} - -/* Read and check the palette */ -void /* PRIVATE */ -png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_color palette[PNG_MAX_PALETTE_LENGTH]; - int max_palette_length, num, i; -#ifdef PNG_POINTER_INDEXING_SUPPORTED - png_colorp pal_ptr; -#endif - - png_debug(1, "in png_handle_PLTE"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - /* Moved to before the 'after IDAT' check below because otherwise duplicate - * PLTE chunks are potentially ignored (the spec says there shall not be more - * than one PLTE, the error is not treated as benign, so this check trumps - * the requirement that PLTE appears before IDAT.) - */ - else if ((png_ptr->mode & PNG_HAVE_PLTE) != 0) - png_chunk_error(png_ptr, "duplicate"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - /* This is benign because the non-benign error happened before, when an - * IDAT was encountered in a color-mapped image with no PLTE. - */ - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - png_ptr->mode |= PNG_HAVE_PLTE; - - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "ignored in grayscale PNG"); - return; - } - -#ifndef PNG_READ_OPT_PLTE_SUPPORTED - if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - { - png_crc_finish(png_ptr, length); - return; - } -#endif - - if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) - { - png_crc_finish(png_ptr, length); - - if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) - png_chunk_benign_error(png_ptr, "invalid"); - - else - png_chunk_error(png_ptr, "invalid"); - - return; - } - - /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */ - num = (int)length / 3; - - /* If the palette has 256 or fewer entries but is too large for the bit - * depth, we don't issue an error, to preserve the behavior of previous - * libpng versions. We silently truncate the unused extra palette entries - * here. - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - max_palette_length = (1 << png_ptr->bit_depth); - else - max_palette_length = PNG_MAX_PALETTE_LENGTH; - - if (num > max_palette_length) - num = max_palette_length; - -#ifdef PNG_POINTER_INDEXING_SUPPORTED - for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) - { - png_byte buf[3]; - - png_crc_read(png_ptr, buf, 3); - pal_ptr->red = buf[0]; - pal_ptr->green = buf[1]; - pal_ptr->blue = buf[2]; - } -#else - for (i = 0; i < num; i++) - { - png_byte buf[3]; - - png_crc_read(png_ptr, buf, 3); - /* Don't depend upon png_color being any order */ - palette[i].red = buf[0]; - palette[i].green = buf[1]; - palette[i].blue = buf[2]; - } -#endif - - /* If we actually need the PLTE chunk (ie for a paletted image), we do - * whatever the normal CRC configuration tells us. However, if we - * have an RGB image, the PLTE can be considered ancillary, so - * we will act as though it is. - */ -#ifndef PNG_READ_OPT_PLTE_SUPPORTED - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) -#endif - { - png_crc_finish(png_ptr, (png_uint_32) (length - (unsigned int)num * 3)); - } - -#ifndef PNG_READ_OPT_PLTE_SUPPORTED - else if (png_crc_error(png_ptr) != 0) /* Only if we have a CRC error */ - { - /* If we don't want to use the data from an ancillary chunk, - * we have two options: an error abort, or a warning and we - * ignore the data in this chunk (which should be OK, since - * it's considered ancillary for a RGB or RGBA image). - * - * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the - * chunk type to determine whether to check the ancillary or the critical - * flags. - */ - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE) == 0) - { - if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) != 0) - return; - - else - png_chunk_error(png_ptr, "CRC error"); - } - - /* Otherwise, we (optionally) emit a warning and use the chunk. */ - else if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0) - png_chunk_warning(png_ptr, "CRC error"); - } -#endif - - /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its - * own copy of the palette. This has the side effect that when png_start_row - * is called (this happens after any call to png_read_update_info) the - * info_ptr palette gets changed. This is extremely unexpected and - * confusing. - * - * Fix this by not sharing the palette in this way. - */ - png_set_PLTE(png_ptr, info_ptr, palette, num); - - /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before - * IDAT. Prior to 1.6.0 this was not checked; instead the code merely - * checked the apparent validity of a tRNS chunk inserted before PLTE on a - * palette PNG. 1.6.0 attempts to rigorously follow the standard and - * therefore does a benign error if the erroneous condition is detected *and* - * cancels the tRNS if the benign error returns. The alternative is to - * amend the standard since it would be rather hypocritical of the standards - * maintainers to ignore it. - */ -#ifdef PNG_READ_tRNS_SUPPORTED - if (png_ptr->num_trans > 0 || - (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0)) - { - /* Cancel this because otherwise it would be used if the transforms - * require it. Don't cancel the 'valid' flag because this would prevent - * detection of duplicate chunks. - */ - png_ptr->num_trans = 0; - - if (info_ptr != NULL) - info_ptr->num_trans = 0; - - png_chunk_benign_error(png_ptr, "tRNS must be after"); - } -#endif - -#ifdef PNG_READ_hIST_SUPPORTED - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) - png_chunk_benign_error(png_ptr, "hIST must be after"); -#endif - -#ifdef PNG_READ_bKGD_SUPPORTED - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) - png_chunk_benign_error(png_ptr, "bKGD must be after"); -#endif -} - -void /* PRIVATE */ -png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_debug(1, "in png_handle_IEND"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0 || - (png_ptr->mode & PNG_HAVE_IDAT) == 0) - png_chunk_error(png_ptr, "out of place"); - - png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); - - png_crc_finish(png_ptr, length); - - if (length != 0) - png_chunk_benign_error(png_ptr, "invalid"); - - PNG_UNUSED(info_ptr) -} - -#ifdef PNG_READ_gAMA_SUPPORTED -void /* PRIVATE */ -png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_fixed_point igamma; - png_byte buf[4]; - - png_debug(1, "in png_handle_gAMA"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - if (length != 4) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 4); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - igamma = png_get_fixed_point(NULL, buf); - - png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma); - png_colorspace_sync(png_ptr, info_ptr); -} -#endif - -#ifdef PNG_READ_sBIT_SUPPORTED -void /* PRIVATE */ -png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - unsigned int truelen, i; - png_byte sample_depth; - png_byte buf[4]; - - png_debug(1, "in png_handle_sBIT"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - truelen = 3; - sample_depth = 8; - } - - else - { - truelen = png_ptr->channels; - sample_depth = png_ptr->bit_depth; - } - - if (length != truelen || length > 4) - { - png_chunk_benign_error(png_ptr, "invalid"); - png_crc_finish(png_ptr, length); - return; - } - - buf[0] = buf[1] = buf[2] = buf[3] = sample_depth; - png_crc_read(png_ptr, buf, truelen); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - for (i=0; i sample_depth) - { - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - } - - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_ptr->sig_bit.red = buf[0]; - png_ptr->sig_bit.green = buf[1]; - png_ptr->sig_bit.blue = buf[2]; - png_ptr->sig_bit.alpha = buf[3]; - } - - else - { - png_ptr->sig_bit.gray = buf[0]; - png_ptr->sig_bit.red = buf[0]; - png_ptr->sig_bit.green = buf[0]; - png_ptr->sig_bit.blue = buf[0]; - png_ptr->sig_bit.alpha = buf[1]; - } - - png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); -} -#endif - -#ifdef PNG_READ_cHRM_SUPPORTED -void /* PRIVATE */ -png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_byte buf[32]; - png_xy xy; - - png_debug(1, "in png_handle_cHRM"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - if (length != 32) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 32); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - xy.whitex = png_get_fixed_point(NULL, buf); - xy.whitey = png_get_fixed_point(NULL, buf + 4); - xy.redx = png_get_fixed_point(NULL, buf + 8); - xy.redy = png_get_fixed_point(NULL, buf + 12); - xy.greenx = png_get_fixed_point(NULL, buf + 16); - xy.greeny = png_get_fixed_point(NULL, buf + 20); - xy.bluex = png_get_fixed_point(NULL, buf + 24); - xy.bluey = png_get_fixed_point(NULL, buf + 28); - - if (xy.whitex == PNG_FIXED_ERROR || - xy.whitey == PNG_FIXED_ERROR || - xy.redx == PNG_FIXED_ERROR || - xy.redy == PNG_FIXED_ERROR || - xy.greenx == PNG_FIXED_ERROR || - xy.greeny == PNG_FIXED_ERROR || - xy.bluex == PNG_FIXED_ERROR || - xy.bluey == PNG_FIXED_ERROR) - { - png_chunk_benign_error(png_ptr, "invalid values"); - return; - } - - /* If a colorspace error has already been output skip this chunk */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) - return; - - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0) - { - png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; - png_colorspace_sync(png_ptr, info_ptr); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; - (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy, - 1/*prefer cHRM values*/); - png_colorspace_sync(png_ptr, info_ptr); -} -#endif - -#ifdef PNG_READ_sRGB_SUPPORTED -void /* PRIVATE */ -png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_byte intent; - - png_debug(1, "in png_handle_sRGB"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - if (length != 1) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, &intent, 1); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - /* If a colorspace error has already been output skip this chunk */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) - return; - - /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect - * this. - */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) != 0) - { - png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; - png_colorspace_sync(png_ptr, info_ptr); - png_chunk_benign_error(png_ptr, "too many profiles"); - return; - } - - (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent); - png_colorspace_sync(png_ptr, info_ptr); -} -#endif /* READ_sRGB */ - -#ifdef PNG_READ_iCCP_SUPPORTED -void /* PRIVATE */ -png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -/* Note: this does not properly handle profiles that are > 64K under DOS */ -{ - png_const_charp errmsg = NULL; /* error message output, or no error */ - int finished = 0; /* crc checked */ - - png_debug(1, "in png_handle_iCCP"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - /* Consistent with all the above colorspace handling an obviously *invalid* - * chunk is just ignored, so does not invalidate the color space. An - * alternative is to set the 'invalid' flags at the start of this routine - * and only clear them in they were not set before and all the tests pass. - */ - - /* The keyword must be at least one character and there is a - * terminator (0) byte and the compression method byte, and the - * 'zlib' datastream is at least 11 bytes. - */ - if (length < 14) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "too short"); - return; - } - - /* If a colorspace error has already been output skip this chunk */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0) - { - png_crc_finish(png_ptr, length); - return; - } - - /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect - * this. - */ - if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0) - { - uInt read_length, keyword_length; - char keyword[81]; - - /* Find the keyword; the keyword plus separator and compression method - * bytes can be at most 81 characters long. - */ - read_length = 81; /* maximum */ - if (read_length > length) - read_length = (uInt)length; - - png_crc_read(png_ptr, (png_bytep)keyword, read_length); - length -= read_length; - - /* The minimum 'zlib' stream is assumed to be just the 2 byte header, - * 5 bytes minimum 'deflate' stream, and the 4 byte checksum. - */ - if (length < 11) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "too short"); - return; - } - - keyword_length = 0; - while (keyword_length < 80 && keyword_length < read_length && - keyword[keyword_length] != 0) - ++keyword_length; - - /* TODO: make the keyword checking common */ - if (keyword_length >= 1 && keyword_length <= 79) - { - /* We only understand '0' compression - deflate - so if we get a - * different value we can't safely decode the chunk. - */ - if (keyword_length+1 < read_length && - keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE) - { - read_length -= keyword_length+2; - - if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK) - { - Byte profile_header[132]={0}; - Byte local_buffer[PNG_INFLATE_BUF_SIZE]; - png_alloc_size_t size = (sizeof profile_header); - - png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2); - png_ptr->zstream.avail_in = read_length; - (void)png_inflate_read(png_ptr, local_buffer, - (sizeof local_buffer), &length, profile_header, &size, - 0/*finish: don't, because the output is too small*/); - - if (size == 0) - { - /* We have the ICC profile header; do the basic header checks. - */ - png_uint_32 profile_length = png_get_uint_32(profile_header); - - if (png_icc_check_length(png_ptr, &png_ptr->colorspace, - keyword, profile_length) != 0) - { - /* The length is apparently ok, so we can check the 132 - * byte header. - */ - if (png_icc_check_header(png_ptr, &png_ptr->colorspace, - keyword, profile_length, profile_header, - png_ptr->color_type) != 0) - { - /* Now read the tag table; a variable size buffer is - * needed at this point, allocate one for the whole - * profile. The header check has already validated - * that none of this stuff will overflow. - */ - png_uint_32 tag_count = - png_get_uint_32(profile_header + 128); - png_bytep profile = png_read_buffer(png_ptr, - profile_length, 2/*silent*/); - - if (profile != NULL) - { - memcpy(profile, profile_header, - (sizeof profile_header)); - - size = 12 * tag_count; - - (void)png_inflate_read(png_ptr, local_buffer, - (sizeof local_buffer), &length, - profile + (sizeof profile_header), &size, 0); - - /* Still expect a buffer error because we expect - * there to be some tag data! - */ - if (size == 0) - { - if (png_icc_check_tag_table(png_ptr, - &png_ptr->colorspace, keyword, profile_length, - profile) != 0) - { - /* The profile has been validated for basic - * security issues, so read the whole thing in. - */ - size = profile_length - (sizeof profile_header) - - 12 * tag_count; - - (void)png_inflate_read(png_ptr, local_buffer, - (sizeof local_buffer), &length, - profile + (sizeof profile_header) + - 12 * tag_count, &size, 1/*finish*/); - - if (length > 0 && !(png_ptr->flags & - PNG_FLAG_BENIGN_ERRORS_WARN)) - errmsg = "extra compressed data"; - - /* But otherwise allow extra data: */ - else if (size == 0) - { - if (length > 0) - { - /* This can be handled completely, so - * keep going. - */ - png_chunk_warning(png_ptr, - "extra compressed data"); - } - - png_crc_finish(png_ptr, length); - finished = 1; - -# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0 - /* Check for a match against sRGB */ - png_icc_set_sRGB(png_ptr, - &png_ptr->colorspace, profile, - png_ptr->zstream.adler); -# endif - - /* Steal the profile for info_ptr. */ - if (info_ptr != NULL) - { - png_free_data(png_ptr, info_ptr, - PNG_FREE_ICCP, 0); - - info_ptr->iccp_name = png_voidcast(char*, - png_malloc_base(png_ptr, - keyword_length+1)); - if (info_ptr->iccp_name != NULL) - { - memcpy(info_ptr->iccp_name, keyword, - keyword_length+1); - info_ptr->iccp_proflen = - profile_length; - info_ptr->iccp_profile = profile; - png_ptr->read_buffer = NULL; /*steal*/ - info_ptr->free_me |= PNG_FREE_ICCP; - info_ptr->valid |= PNG_INFO_iCCP; - } - - else - { - png_ptr->colorspace.flags |= - PNG_COLORSPACE_INVALID; - errmsg = "out of memory"; - } - } - - /* else the profile remains in the read - * buffer which gets reused for subsequent - * chunks. - */ - - if (info_ptr != NULL) - png_colorspace_sync(png_ptr, info_ptr); - - if (errmsg == NULL) - { - png_ptr->zowner = 0; - return; - } - } - if (errmsg == NULL) - errmsg = png_ptr->zstream.msg; - } - /* else png_icc_check_tag_table output an error */ - } - else /* profile truncated */ - errmsg = png_ptr->zstream.msg; - } - - else - errmsg = "out of memory"; - } - - /* else png_icc_check_header output an error */ - } - - /* else png_icc_check_length output an error */ - } - - else /* profile truncated */ - errmsg = png_ptr->zstream.msg; - - /* Release the stream */ - png_ptr->zowner = 0; - } - - else /* png_inflate_claim failed */ - errmsg = png_ptr->zstream.msg; - } - - else - errmsg = "bad compression method"; /* or missing */ - } - - else - errmsg = "bad keyword"; - } - - else - errmsg = "too many profiles"; - - /* Failure: the reason is in 'errmsg' */ - if (finished == 0) - png_crc_finish(png_ptr, length); - - png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID; - png_colorspace_sync(png_ptr, info_ptr); - if (errmsg != NULL) /* else already output */ - png_chunk_benign_error(png_ptr, errmsg); -} -#endif /* READ_iCCP */ - -#ifdef PNG_READ_sPLT_SUPPORTED -void /* PRIVATE */ -png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -/* Note: this does not properly handle chunks that are > 64K under DOS */ -{ - png_bytep entry_start, buffer; - png_sPLT_t new_palette; - png_sPLT_entryp pp; - png_uint_32 data_length; - int entry_size, i; - png_uint_32 skip = 0; - png_uint_32 dl; - size_t max_dl; - - png_debug(1, "in png_handle_sPLT"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_warning(png_ptr, "No space in chunk cache for sPLT"); - png_crc_finish(png_ptr, length); - return; - } - } -#endif - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - -#ifdef PNG_MAX_MALLOC_64K - if (length > 65535U) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "too large to fit in memory"); - return; - } -#endif - - buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); - if (buffer == NULL) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - - /* WARNING: this may break if size_t is less than 32 bits; it is assumed - * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a - * potential breakage point if the types in pngconf.h aren't exactly right. - */ - png_crc_read(png_ptr, buffer, length); - - if (png_crc_finish(png_ptr, skip) != 0) - return; - - buffer[length] = 0; - - for (entry_start = buffer; *entry_start; entry_start++) - /* Empty loop to find end of name */ ; - - ++entry_start; - - /* A sample depth should follow the separator, and we should be on it */ - if (length < 2U || entry_start > buffer + (length - 2U)) - { - png_warning(png_ptr, "malformed sPLT chunk"); - return; - } - - new_palette.depth = *entry_start++; - entry_size = (new_palette.depth == 8 ? 6 : 10); - /* This must fit in a png_uint_32 because it is derived from the original - * chunk data length. - */ - data_length = length - (png_uint_32)(entry_start - buffer); - - /* Integrity-check the data length */ - if ((data_length % (unsigned int)entry_size) != 0) - { - png_warning(png_ptr, "sPLT chunk has bad length"); - return; - } - - dl = (png_uint_32)(data_length / (unsigned int)entry_size); - max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry)); - - if (dl > max_dl) - { - png_warning(png_ptr, "sPLT chunk too long"); - return; - } - - new_palette.nentries = (png_int_32)(data_length / (unsigned int)entry_size); - - new_palette.entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, - (png_alloc_size_t) new_palette.nentries * (sizeof (png_sPLT_entry))); - - if (new_palette.entries == NULL) - { - png_warning(png_ptr, "sPLT chunk requires too much memory"); - return; - } - -#ifdef PNG_POINTER_INDEXING_SUPPORTED - for (i = 0; i < new_palette.nentries; i++) - { - pp = new_palette.entries + i; - - if (new_palette.depth == 8) - { - pp->red = *entry_start++; - pp->green = *entry_start++; - pp->blue = *entry_start++; - pp->alpha = *entry_start++; - } - - else - { - pp->red = png_get_uint_16(entry_start); entry_start += 2; - pp->green = png_get_uint_16(entry_start); entry_start += 2; - pp->blue = png_get_uint_16(entry_start); entry_start += 2; - pp->alpha = png_get_uint_16(entry_start); entry_start += 2; - } - - pp->frequency = png_get_uint_16(entry_start); entry_start += 2; - } -#else - pp = new_palette.entries; - - for (i = 0; i < new_palette.nentries; i++) - { - - if (new_palette.depth == 8) - { - pp[i].red = *entry_start++; - pp[i].green = *entry_start++; - pp[i].blue = *entry_start++; - pp[i].alpha = *entry_start++; - } - - else - { - pp[i].red = png_get_uint_16(entry_start); entry_start += 2; - pp[i].green = png_get_uint_16(entry_start); entry_start += 2; - pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; - pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; - } - - pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2; - } -#endif - - /* Discard all chunk data except the name and stash that */ - new_palette.name = (png_charp)buffer; - - png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); - - png_free(png_ptr, new_palette.entries); -} -#endif /* READ_sPLT */ - -#ifdef PNG_READ_tRNS_SUPPORTED -void /* PRIVATE */ -png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; - - png_debug(1, "in png_handle_tRNS"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) - { - png_byte buf[2]; - - if (length != 2) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 2); - png_ptr->num_trans = 1; - png_ptr->trans_color.gray = png_get_uint_16(buf); - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) - { - png_byte buf[6]; - - if (length != 6) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, length); - png_ptr->num_trans = 1; - png_ptr->trans_color.red = png_get_uint_16(buf); - png_ptr->trans_color.green = png_get_uint_16(buf + 2); - png_ptr->trans_color.blue = png_get_uint_16(buf + 4); - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - if ((png_ptr->mode & PNG_HAVE_PLTE) == 0) - { - /* TODO: is this actually an error in the ISO spec? */ - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - if (length > (unsigned int) png_ptr->num_palette || - length > (unsigned int) PNG_MAX_PALETTE_LENGTH || - length == 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, readbuf, length); - png_ptr->num_trans = (png_uint_16)length; - } - - else - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid with alpha channel"); - return; - } - - if (png_crc_finish(png_ptr, 0) != 0) - { - png_ptr->num_trans = 0; - return; - } - - /* TODO: this is a horrible side effect in the palette case because the - * png_struct ends up with a pointer to the tRNS buffer owned by the - * png_info. Fix this. - */ - png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, - &(png_ptr->trans_color)); -} -#endif - -#ifdef PNG_READ_bKGD_SUPPORTED -void /* PRIVATE */ -png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - unsigned int truelen; - png_byte buf[6]; - png_color_16 background; - - png_debug(1, "in png_handle_bKGD"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 || - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - (png_ptr->mode & PNG_HAVE_PLTE) == 0)) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - truelen = 1; - - else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - truelen = 6; - - else - truelen = 2; - - if (length != truelen) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, truelen); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - /* We convert the index value into RGB components so that we can allow - * arbitrary RGB values for background when we have transparency, and - * so it is easy to determine the RGB values of the background color - * from the info_ptr struct. - */ - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - background.index = buf[0]; - - if (info_ptr != NULL && info_ptr->num_palette != 0) - { - if (buf[0] >= info_ptr->num_palette) - { - png_chunk_benign_error(png_ptr, "invalid index"); - return; - } - - background.red = (png_uint_16)png_ptr->palette[buf[0]].red; - background.green = (png_uint_16)png_ptr->palette[buf[0]].green; - background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue; - } - - else - background.red = background.green = background.blue = 0; - - background.gray = 0; - } - - else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */ - { - if (png_ptr->bit_depth <= 8) - { - if (buf[0] != 0 || buf[1] >= (unsigned int)(1 << png_ptr->bit_depth)) - { - png_chunk_benign_error(png_ptr, "invalid gray level"); - return; - } - } - - background.index = 0; - background.red = - background.green = - background.blue = - background.gray = png_get_uint_16(buf); - } - - else - { - if (png_ptr->bit_depth <= 8) - { - if (buf[0] != 0 || buf[2] != 0 || buf[4] != 0) - { - png_chunk_benign_error(png_ptr, "invalid color"); - return; - } - } - - background.index = 0; - background.red = png_get_uint_16(buf); - background.green = png_get_uint_16(buf + 2); - background.blue = png_get_uint_16(buf + 4); - background.gray = 0; - } - - png_set_bKGD(png_ptr, info_ptr, &background); -} -#endif - -#ifdef PNG_READ_eXIf_SUPPORTED -void /* PRIVATE */ -png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - unsigned int i; - - png_debug(1, "in png_handle_eXIf"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - if (length < 2) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "too short"); - return; - } - - else if (info_ptr == NULL || (info_ptr->valid & PNG_INFO_eXIf) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - info_ptr->free_me |= PNG_FREE_EXIF; - - info_ptr->eXIf_buf = png_voidcast(png_bytep, - png_malloc_warn(png_ptr, length)); - - if (info_ptr->eXIf_buf == NULL) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - for (i = 0; i < length; i++) - { - png_byte buf[1]; - png_crc_read(png_ptr, buf, 1); - info_ptr->eXIf_buf[i] = buf[0]; - if (i == 1 && buf[0] != 'M' && buf[0] != 'I' - && info_ptr->eXIf_buf[0] != buf[0]) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "incorrect byte-order specifier"); - png_free(png_ptr, info_ptr->eXIf_buf); - info_ptr->eXIf_buf = NULL; - return; - } - } - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf); - - png_free(png_ptr, info_ptr->eXIf_buf); - info_ptr->eXIf_buf = NULL; -} -#endif - -#ifdef PNG_READ_hIST_SUPPORTED -void /* PRIVATE */ -png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - unsigned int num, i; - png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; - - png_debug(1, "in png_handle_hIST"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 || - (png_ptr->mode & PNG_HAVE_PLTE) == 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - num = length / 2 ; - - if (num != (unsigned int) png_ptr->num_palette || - num > (unsigned int) PNG_MAX_PALETTE_LENGTH) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - for (i = 0; i < num; i++) - { - png_byte buf[2]; - - png_crc_read(png_ptr, buf, 2); - readbuf[i] = png_get_uint_16(buf); - } - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - png_set_hIST(png_ptr, info_ptr, readbuf); -} -#endif - -#ifdef PNG_READ_pHYs_SUPPORTED -void /* PRIVATE */ -png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_byte buf[9]; - png_uint_32 res_x, res_y; - int unit_type; - - png_debug(1, "in png_handle_pHYs"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if (length != 9) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 9); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - res_x = png_get_uint_32(buf); - res_y = png_get_uint_32(buf + 4); - unit_type = buf[8]; - png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); -} -#endif - -#ifdef PNG_READ_oFFs_SUPPORTED -void /* PRIVATE */ -png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_byte buf[9]; - png_int_32 offset_x, offset_y; - int unit_type; - - png_debug(1, "in png_handle_oFFs"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if (length != 9) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 9); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - offset_x = png_get_int_32(buf); - offset_y = png_get_int_32(buf + 4); - unit_type = buf[8]; - png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); -} -#endif - -#ifdef PNG_READ_pCAL_SUPPORTED -/* Read the pCAL chunk (described in the PNG Extensions document) */ -void /* PRIVATE */ -png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_int_32 X0, X1; - png_byte type, nparams; - png_bytep buffer, buf, units, endptr; - png_charpp params; - int i; - - png_debug(1, "in png_handle_pCAL"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", - length + 1); - - buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); - - if (buffer == NULL) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - png_crc_read(png_ptr, buffer, length); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - buffer[length] = 0; /* Null terminate the last string */ - - png_debug(3, "Finding end of pCAL purpose string"); - for (buf = buffer; *buf; buf++) - /* Empty loop */ ; - - endptr = buffer + length; - - /* We need to have at least 12 bytes after the purpose string - * in order to get the parameter information. - */ - if (endptr - buf <= 12) - { - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); - X0 = png_get_int_32((png_bytep)buf+1); - X1 = png_get_int_32((png_bytep)buf+5); - type = buf[9]; - nparams = buf[10]; - units = buf + 11; - - png_debug(3, "Checking pCAL equation type and number of parameters"); - /* Check that we have the right number of parameters for known - * equation types. - */ - if ((type == PNG_EQUATION_LINEAR && nparams != 2) || - (type == PNG_EQUATION_BASE_E && nparams != 3) || - (type == PNG_EQUATION_ARBITRARY && nparams != 3) || - (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) - { - png_chunk_benign_error(png_ptr, "invalid parameter count"); - return; - } - - else if (type >= PNG_EQUATION_LAST) - { - png_chunk_benign_error(png_ptr, "unrecognized equation type"); - } - - for (buf = units; *buf; buf++) - /* Empty loop to move past the units string. */ ; - - png_debug(3, "Allocating pCAL parameters array"); - - params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, - nparams * (sizeof (png_charp)))); - - if (params == NULL) - { - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - /* Get pointers to the start of each parameter string. */ - for (i = 0; i < nparams; i++) - { - buf++; /* Skip the null string terminator from previous parameter. */ - - png_debug1(3, "Reading pCAL parameter %d", i); - - for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++) - /* Empty loop to move past each parameter string */ ; - - /* Make sure we haven't run out of data yet */ - if (buf > endptr) - { - png_free(png_ptr, params); - png_chunk_benign_error(png_ptr, "invalid data"); - return; - } - } - - png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams, - (png_charp)units, params); - - png_free(png_ptr, params); -} -#endif - -#ifdef PNG_READ_sCAL_SUPPORTED -/* Read the sCAL chunk */ -void /* PRIVATE */ -png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_bytep buffer; - size_t i; - int state; - - png_debug(1, "in png_handle_sCAL"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of place"); - return; - } - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - /* Need unit type, width, \0, height: minimum 4 bytes */ - else if (length < 4) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", - length + 1); - - buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/); - - if (buffer == NULL) - { - png_chunk_benign_error(png_ptr, "out of memory"); - png_crc_finish(png_ptr, length); - return; - } - - png_crc_read(png_ptr, buffer, length); - buffer[length] = 0; /* Null terminate the last string */ - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - /* Validate the unit. */ - if (buffer[0] != 1 && buffer[0] != 2) - { - png_chunk_benign_error(png_ptr, "invalid unit"); - return; - } - - /* Validate the ASCII numbers, need two ASCII numbers separated by - * a '\0' and they need to fit exactly in the chunk data. - */ - i = 1; - state = 0; - - if (png_check_fp_number((png_const_charp)buffer, length, &state, &i) == 0 || - i >= length || buffer[i++] != 0) - png_chunk_benign_error(png_ptr, "bad width format"); - - else if (PNG_FP_IS_POSITIVE(state) == 0) - png_chunk_benign_error(png_ptr, "non-positive width"); - - else - { - size_t heighti = i; - - state = 0; - if (png_check_fp_number((png_const_charp)buffer, length, - &state, &i) == 0 || i != length) - png_chunk_benign_error(png_ptr, "bad height format"); - - else if (PNG_FP_IS_POSITIVE(state) == 0) - png_chunk_benign_error(png_ptr, "non-positive height"); - - else - /* This is the (only) success case. */ - png_set_sCAL_s(png_ptr, info_ptr, buffer[0], - (png_charp)buffer+1, (png_charp)buffer+heighti); - } -} -#endif - -#ifdef PNG_READ_tIME_SUPPORTED -void /* PRIVATE */ -png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_byte buf[7]; - png_time mod_time; - - png_debug(1, "in png_handle_tIME"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) != 0) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "duplicate"); - return; - } - - if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - - if (length != 7) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "invalid"); - return; - } - - png_crc_read(png_ptr, buf, 7); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - mod_time.second = buf[6]; - mod_time.minute = buf[5]; - mod_time.hour = buf[4]; - mod_time.day = buf[3]; - mod_time.month = buf[2]; - mod_time.year = png_get_uint_16(buf); - - png_set_tIME(png_ptr, info_ptr, &mod_time); -} -#endif - -#ifdef PNG_READ_tEXt_SUPPORTED -/* Note: this does not properly handle chunks that are > 64K under DOS */ -void /* PRIVATE */ -png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_text text_info; - png_bytep buffer; - png_charp key; - png_charp text; - png_uint_32 skip = 0; - - png_debug(1, "in png_handle_tEXt"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "no space in chunk cache"); - return; - } - } -#endif - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - -#ifdef PNG_MAX_MALLOC_64K - if (length > 65535U) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "too large to fit in memory"); - return; - } -#endif - - buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); - - if (buffer == NULL) - { - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - png_crc_read(png_ptr, buffer, length); - - if (png_crc_finish(png_ptr, skip) != 0) - return; - - key = (png_charp)buffer; - key[length] = 0; - - for (text = key; *text; text++) - /* Empty loop to find end of key */ ; - - if (text != key + length) - text++; - - text_info.compression = PNG_TEXT_COMPRESSION_NONE; - text_info.key = key; - text_info.lang = NULL; - text_info.lang_key = NULL; - text_info.itxt_length = 0; - text_info.text = text; - text_info.text_length = strlen(text); - - if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) != 0) - png_warning(png_ptr, "Insufficient memory to process text chunk"); -} -#endif - -#ifdef PNG_READ_zTXt_SUPPORTED -/* Note: this does not correctly handle chunks that are > 64K under DOS */ -void /* PRIVATE */ -png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_const_charp errmsg = NULL; - png_bytep buffer; - png_uint_32 keyword_length; - - png_debug(1, "in png_handle_zTXt"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "no space in chunk cache"); - return; - } - } -#endif - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - - /* Note, "length" is sufficient here; we won't be adding - * a null terminator later. - */ - buffer = png_read_buffer(png_ptr, length, 2/*silent*/); - - if (buffer == NULL) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - png_crc_read(png_ptr, buffer, length); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - /* TODO: also check that the keyword contents match the spec! */ - for (keyword_length = 0; - keyword_length < length && buffer[keyword_length] != 0; - ++keyword_length) - /* Empty loop to find end of name */ ; - - if (keyword_length > 79 || keyword_length < 1) - errmsg = "bad keyword"; - - /* zTXt must have some LZ data after the keyword, although it may expand to - * zero bytes; we need a '\0' at the end of the keyword, the compression type - * then the LZ data: - */ - else if (keyword_length + 3 > length) - errmsg = "truncated"; - - else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE) - errmsg = "unknown compression type"; - - else - { - png_alloc_size_t uncompressed_length = PNG_SIZE_MAX; - - /* TODO: at present png_decompress_chunk imposes a single application - * level memory limit, this should be split to different values for iCCP - * and text chunks. - */ - if (png_decompress_chunk(png_ptr, length, keyword_length+2, - &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) - { - png_text text; - - if (png_ptr->read_buffer == NULL) - errmsg="Read failure in png_handle_zTXt"; - else - { - /* It worked; png_ptr->read_buffer now looks like a tEXt chunk - * except for the extra compression type byte and the fact that - * it isn't necessarily '\0' terminated. - */ - buffer = png_ptr->read_buffer; - buffer[uncompressed_length+(keyword_length+2)] = 0; - - text.compression = PNG_TEXT_COMPRESSION_zTXt; - text.key = (png_charp)buffer; - text.text = (png_charp)(buffer + keyword_length+2); - text.text_length = uncompressed_length; - text.itxt_length = 0; - text.lang = NULL; - text.lang_key = NULL; - - if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) - errmsg = "insufficient memory"; - } - } - - else - errmsg = png_ptr->zstream.msg; - } - - if (errmsg != NULL) - png_chunk_benign_error(png_ptr, errmsg); -} -#endif - -#ifdef PNG_READ_iTXt_SUPPORTED -/* Note: this does not correctly handle chunks that are > 64K under DOS */ -void /* PRIVATE */ -png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -{ - png_const_charp errmsg = NULL; - png_bytep buffer; - png_uint_32 prefix_length; - - png_debug(1, "in png_handle_iTXt"); - -#ifdef PNG_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_cache_max != 0) - { - if (png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - return; - } - - if (--png_ptr->user_chunk_cache_max == 1) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "no space in chunk cache"); - return; - } - } -#endif - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - png_chunk_error(png_ptr, "missing IHDR"); - - if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - - buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/); - - if (buffer == NULL) - { - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "out of memory"); - return; - } - - png_crc_read(png_ptr, buffer, length); - - if (png_crc_finish(png_ptr, 0) != 0) - return; - - /* First the keyword. */ - for (prefix_length=0; - prefix_length < length && buffer[prefix_length] != 0; - ++prefix_length) - /* Empty loop */ ; - - /* Perform a basic check on the keyword length here. */ - if (prefix_length > 79 || prefix_length < 1) - errmsg = "bad keyword"; - - /* Expect keyword, compression flag, compression type, language, translated - * keyword (both may be empty but are 0 terminated) then the text, which may - * be empty. - */ - else if (prefix_length + 5 > length) - errmsg = "truncated"; - - else if (buffer[prefix_length+1] == 0 || - (buffer[prefix_length+1] == 1 && - buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE)) - { - int compressed = buffer[prefix_length+1] != 0; - png_uint_32 language_offset, translated_keyword_offset; - png_alloc_size_t uncompressed_length = 0; - - /* Now the language tag */ - prefix_length += 3; - language_offset = prefix_length; - - for (; prefix_length < length && buffer[prefix_length] != 0; - ++prefix_length) - /* Empty loop */ ; - - /* WARNING: the length may be invalid here, this is checked below. */ - translated_keyword_offset = ++prefix_length; - - for (; prefix_length < length && buffer[prefix_length] != 0; - ++prefix_length) - /* Empty loop */ ; - - /* prefix_length should now be at the trailing '\0' of the translated - * keyword, but it may already be over the end. None of this arithmetic - * can overflow because chunks are at most 2^31 bytes long, but on 16-bit - * systems the available allocation may overflow. - */ - ++prefix_length; - - if (compressed == 0 && prefix_length <= length) - uncompressed_length = length - prefix_length; - - else if (compressed != 0 && prefix_length < length) - { - uncompressed_length = PNG_SIZE_MAX; - - /* TODO: at present png_decompress_chunk imposes a single application - * level memory limit, this should be split to different values for - * iCCP and text chunks. - */ - if (png_decompress_chunk(png_ptr, length, prefix_length, - &uncompressed_length, 1/*terminate*/) == Z_STREAM_END) - buffer = png_ptr->read_buffer; - - else - errmsg = png_ptr->zstream.msg; - } - - else - errmsg = "truncated"; - - if (errmsg == NULL) - { - png_text text; - - buffer[uncompressed_length+prefix_length] = 0; - - if (compressed == 0) - text.compression = PNG_ITXT_COMPRESSION_NONE; - - else - text.compression = PNG_ITXT_COMPRESSION_zTXt; - - text.key = (png_charp)buffer; - text.lang = (png_charp)buffer + language_offset; - text.lang_key = (png_charp)buffer + translated_keyword_offset; - text.text = (png_charp)buffer + prefix_length; - text.text_length = 0; - text.itxt_length = uncompressed_length; - - if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0) - errmsg = "insufficient memory"; - } - } - - else - errmsg = "bad compression info"; - - if (errmsg != NULL) - png_chunk_benign_error(png_ptr, errmsg); -} -#endif - -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */ -static int -png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) -{ - png_alloc_size_t limit = PNG_SIZE_MAX; - - if (png_ptr->unknown_chunk.data != NULL) - { - png_free(png_ptr, png_ptr->unknown_chunk.data); - png_ptr->unknown_chunk.data = NULL; - } - -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < limit) - limit = png_ptr->user_chunk_malloc_max; - -# elif PNG_USER_CHUNK_MALLOC_MAX > 0 - if (PNG_USER_CHUNK_MALLOC_MAX < limit) - limit = PNG_USER_CHUNK_MALLOC_MAX; -# endif - - if (length <= limit) - { - PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); - /* The following is safe because of the PNG_SIZE_MAX init above */ - png_ptr->unknown_chunk.size = (size_t)length/*SAFE*/; - /* 'mode' is a flag array, only the bottom four bits matter here */ - png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/; - - if (length == 0) - png_ptr->unknown_chunk.data = NULL; - - else - { - /* Do a 'warn' here - it is handled below. */ - png_ptr->unknown_chunk.data = png_voidcast(png_bytep, - png_malloc_warn(png_ptr, length)); - } - } - - if (png_ptr->unknown_chunk.data == NULL && length > 0) - { - /* This is benign because we clean up correctly */ - png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "unknown chunk exceeds memory limits"); - return 0; - } - - else - { - if (length > 0) - png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length); - png_crc_finish(png_ptr, 0); - return 1; - } -} -#endif /* READ_UNKNOWN_CHUNKS */ - -/* Handle an unknown, or known but disabled, chunk */ -void /* PRIVATE */ -png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, - png_uint_32 length, int keep) -{ - int handled = 0; /* the chunk was handled */ - - png_debug(1, "in png_handle_unknown"); - -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing - * the bug which meant that setting a non-default behavior for a specific - * chunk would be ignored (the default was always used unless a user - * callback was installed). - * - * 'keep' is the value from the png_chunk_unknown_handling, the setting for - * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it - * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here. - * This is just an optimization to avoid multiple calls to the lookup - * function. - */ -# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name); -# endif -# endif - - /* One of the following methods will read the chunk or skip it (at least one - * of these is always defined because this is the only way to switch on - * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) - */ -# ifdef PNG_READ_USER_CHUNKS_SUPPORTED - /* The user callback takes precedence over the chunk keep value, but the - * keep value is still required to validate a save of a critical chunk. - */ - if (png_ptr->read_user_chunk_fn != NULL) - { - if (png_cache_unknown_chunk(png_ptr, length) != 0) - { - /* Callback to user unknown chunk handler */ - int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr, - &png_ptr->unknown_chunk); - - /* ret is: - * negative: An error occurred; png_chunk_error will be called. - * zero: The chunk was not handled, the chunk will be discarded - * unless png_set_keep_unknown_chunks has been used to set - * a 'keep' behavior for this particular chunk, in which - * case that will be used. A critical chunk will cause an - * error at this point unless it is to be saved. - * positive: The chunk was handled, libpng will ignore/discard it. - */ - if (ret < 0) - png_chunk_error(png_ptr, "error in user chunk"); - - else if (ret == 0) - { - /* If the keep value is 'default' or 'never' override it, but - * still error out on critical chunks unless the keep value is - * 'always' While this is weird it is the behavior in 1.4.12. - * A possible improvement would be to obey the value set for the - * chunk, but this would be an API change that would probably - * damage some applications. - * - * The png_app_warning below catches the case that matters, where - * the application has not set specific save or ignore for this - * chunk or global save or ignore. - */ - if (keep < PNG_HANDLE_CHUNK_IF_SAFE) - { -# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE) - { - png_chunk_warning(png_ptr, "Saving unknown chunk:"); - png_app_warning(png_ptr, - "forcing save of an unhandled chunk;" - " please call png_set_keep_unknown_chunks"); - /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */ - } -# endif - keep = PNG_HANDLE_CHUNK_IF_SAFE; - } - } - - else /* chunk was handled */ - { - handled = 1; - /* Critical chunks can be safely discarded at this point. */ - keep = PNG_HANDLE_CHUNK_NEVER; - } - } - - else - keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */ - } - - else - /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */ -# endif /* READ_USER_CHUNKS */ - -# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - { - /* keep is currently just the per-chunk setting, if there was no - * setting change it to the global default now (not that this may - * still be AS_DEFAULT) then obtain the cache of the chunk if required, - * if not simply skip the chunk. - */ - if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) - keep = png_ptr->unknown_default; - - if (keep == PNG_HANDLE_CHUNK_ALWAYS || - (keep == PNG_HANDLE_CHUNK_IF_SAFE && - PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) - { - if (png_cache_unknown_chunk(png_ptr, length) == 0) - keep = PNG_HANDLE_CHUNK_NEVER; - } - - else - png_crc_finish(png_ptr, length); - } -# else -# ifndef PNG_READ_USER_CHUNKS_SUPPORTED -# error no method to support READ_UNKNOWN_CHUNKS -# endif - - { - /* If here there is no read callback pointer set and no support is - * compiled in to just save the unknown chunks, so simply skip this - * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then - * the app has erroneously asked for unknown chunk saving when there - * is no support. - */ - if (keep > PNG_HANDLE_CHUNK_NEVER) - png_app_error(png_ptr, "no unknown chunk support available"); - - png_crc_finish(png_ptr, length); - } -# endif - -# ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED - /* Now store the chunk in the chunk list if appropriate, and if the limits - * permit it. - */ - if (keep == PNG_HANDLE_CHUNK_ALWAYS || - (keep == PNG_HANDLE_CHUNK_IF_SAFE && - PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))) - { -# ifdef PNG_USER_LIMITS_SUPPORTED - switch (png_ptr->user_chunk_cache_max) - { - case 2: - png_ptr->user_chunk_cache_max = 1; - png_chunk_benign_error(png_ptr, "no space in chunk cache"); - /* FALLTHROUGH */ - case 1: - /* NOTE: prior to 1.6.0 this case resulted in an unknown critical - * chunk being skipped, now there will be a hard error below. - */ - break; - - default: /* not at limit */ - --(png_ptr->user_chunk_cache_max); - /* FALLTHROUGH */ - case 0: /* no limit */ -# endif /* USER_LIMITS */ - /* Here when the limit isn't reached or when limits are compiled - * out; store the chunk. - */ - png_set_unknown_chunks(png_ptr, info_ptr, - &png_ptr->unknown_chunk, 1); - handled = 1; -# ifdef PNG_USER_LIMITS_SUPPORTED - break; - } -# endif - } -# else /* no store support: the chunk must be handled by the user callback */ - PNG_UNUSED(info_ptr) -# endif - - /* Regardless of the error handling below the cached data (if any) can be - * freed now. Notice that the data is not freed if there is a png_error, but - * it will be freed by destroy_read_struct. - */ - if (png_ptr->unknown_chunk.data != NULL) - png_free(png_ptr, png_ptr->unknown_chunk.data); - png_ptr->unknown_chunk.data = NULL; - -#else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */ - /* There is no support to read an unknown chunk, so just skip it. */ - png_crc_finish(png_ptr, length); - PNG_UNUSED(info_ptr) - PNG_UNUSED(keep) -#endif /* !READ_UNKNOWN_CHUNKS */ - - /* Check for unhandled critical chunks */ - if (handled == 0 && PNG_CHUNK_CRITICAL(png_ptr->chunk_name)) - png_chunk_error(png_ptr, "unhandled critical chunk"); -} - -/* This function is called to verify that a chunk name is valid. - * This function can't have the "critical chunk check" incorporated - * into it, since in the future we will need to be able to call user - * functions to handle unknown critical chunks after we check that - * the chunk name itself is valid. - */ - -/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is: - * - * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) - */ - -void /* PRIVATE */ -png_check_chunk_name(png_const_structrp png_ptr, png_uint_32 chunk_name) -{ - int i; - png_uint_32 cn=chunk_name; - - png_debug(1, "in png_check_chunk_name"); - - for (i=1; i<=4; ++i) - { - int c = cn & 0xff; - - if (c < 65 || c > 122 || (c > 90 && c < 97)) - png_chunk_error(png_ptr, "invalid chunk type"); - - cn >>= 8; - } -} - -void /* PRIVATE */ -png_check_chunk_length(png_const_structrp png_ptr, png_uint_32 length) -{ - png_alloc_size_t limit = PNG_UINT_31_MAX; - -# ifdef PNG_SET_USER_LIMITS_SUPPORTED - if (png_ptr->user_chunk_malloc_max > 0 && - png_ptr->user_chunk_malloc_max < limit) - limit = png_ptr->user_chunk_malloc_max; -# elif PNG_USER_CHUNK_MALLOC_MAX > 0 - if (PNG_USER_CHUNK_MALLOC_MAX < limit) - limit = PNG_USER_CHUNK_MALLOC_MAX; -# endif - if (png_ptr->chunk_name == png_IDAT) - { - png_alloc_size_t idat_limit = PNG_UINT_31_MAX; - size_t row_factor = - (size_t)png_ptr->width - * (size_t)png_ptr->channels - * (png_ptr->bit_depth > 8? 2: 1) - + 1 - + (png_ptr->interlaced? 6: 0); - if (png_ptr->height > PNG_UINT_32_MAX/row_factor) - idat_limit = PNG_UINT_31_MAX; - else - idat_limit = png_ptr->height * row_factor; - row_factor = row_factor > 32566? 32566 : row_factor; - idat_limit += 6 + 5*(idat_limit/row_factor+1); /* zlib+deflate overhead */ - idat_limit=idat_limit < PNG_UINT_31_MAX? idat_limit : PNG_UINT_31_MAX; - limit = limit < idat_limit? idat_limit : limit; - } - - if (length > limit) - { - png_debug2(0," length = %lu, limit = %lu", - (unsigned long)length,(unsigned long)limit); - png_chunk_error(png_ptr, "chunk data is too large"); - } -} - -/* Combines the row recently read in with the existing pixels in the row. This - * routine takes care of alpha and transparency if requested. This routine also - * handles the two methods of progressive display of interlaced images, - * depending on the 'display' value; if 'display' is true then the whole row - * (dp) is filled from the start by replicating the available pixels. If - * 'display' is false only those pixels present in the pass are filled in. - */ -void /* PRIVATE */ -png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) -{ - unsigned int pixel_depth = png_ptr->transformed_pixel_depth; - png_const_bytep sp = png_ptr->row_buf + 1; - png_alloc_size_t row_width = png_ptr->width; - unsigned int pass = png_ptr->pass; - png_bytep end_ptr = 0; - png_byte end_byte = 0; - unsigned int end_mask; - - png_debug(1, "in png_combine_row"); - - /* Added in 1.5.6: it should not be possible to enter this routine until at - * least one row has been read from the PNG data and transformed. - */ - if (pixel_depth == 0) - png_error(png_ptr, "internal row logic error"); - - /* Added in 1.5.4: the pixel depth should match the information returned by - * any call to png_read_update_info at this point. Do not continue if we got - * this wrong. - */ - if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes != - PNG_ROWBYTES(pixel_depth, row_width)) - png_error(png_ptr, "internal row size calculation error"); - - /* Don't expect this to ever happen: */ - if (row_width == 0) - png_error(png_ptr, "internal row width error"); - - /* Preserve the last byte in cases where only part of it will be overwritten, - * the multiply below may overflow, we don't care because ANSI-C guarantees - * we get the low bits. - */ - end_mask = (pixel_depth * row_width) & 7; - if (end_mask != 0) - { - /* end_ptr == NULL is a flag to say do nothing */ - end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1; - end_byte = *end_ptr; -# ifdef PNG_READ_PACKSWAP_SUPPORTED - if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - /* little-endian byte */ - end_mask = (unsigned int)(0xff << end_mask); - - else /* big-endian byte */ -# endif - end_mask = 0xff >> end_mask; - /* end_mask is now the bits to *keep* from the destination row */ - } - - /* For non-interlaced images this reduces to a memcpy(). A memcpy() - * will also happen if interlacing isn't supported or if the application - * does not call png_set_interlace_handling(). In the latter cases the - * caller just gets a sequence of the unexpanded rows from each interlace - * pass. - */ -#ifdef PNG_READ_INTERLACING_SUPPORTED - if (png_ptr->interlaced != 0 && - (png_ptr->transformations & PNG_INTERLACE) != 0 && - pass < 6 && (display == 0 || - /* The following copies everything for 'display' on passes 0, 2 and 4. */ - (display == 1 && (pass & 1) != 0))) - { - /* Narrow images may have no bits in a pass; the caller should handle - * this, but this test is cheap: - */ - if (row_width <= PNG_PASS_START_COL(pass)) - return; - - if (pixel_depth < 8) - { - /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit - * into 32 bits, then a single loop over the bytes using the four byte - * values in the 32-bit mask can be used. For the 'display' option the - * expanded mask may also not require any masking within a byte. To - * make this work the PACKSWAP option must be taken into account - it - * simply requires the pixels to be reversed in each byte. - * - * The 'regular' case requires a mask for each of the first 6 passes, - * the 'display' case does a copy for the even passes in the range - * 0..6. This has already been handled in the test above. - * - * The masks are arranged as four bytes with the first byte to use in - * the lowest bits (little-endian) regardless of the order (PACKSWAP or - * not) of the pixels in each byte. - * - * NOTE: the whole of this logic depends on the caller of this function - * only calling it on rows appropriate to the pass. This function only - * understands the 'x' logic; the 'y' logic is handled by the caller. - * - * The following defines allow generation of compile time constant bit - * masks for each pixel depth and each possibility of swapped or not - * swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index, - * is in the range 0..7; and the result is 1 if the pixel is to be - * copied in the pass, 0 if not. 'S' is for the sparkle method, 'B' - * for the block method. - * - * With some compilers a compile time expression of the general form: - * - * (shift >= 32) ? (a >> (shift-32)) : (b >> shift) - * - * Produces warnings with values of 'shift' in the range 33 to 63 - * because the right hand side of the ?: expression is evaluated by - * the compiler even though it isn't used. Microsoft Visual C (various - * versions) and the Intel C compiler are known to do this. To avoid - * this the following macros are used in 1.5.6. This is a temporary - * solution to avoid destabilizing the code during the release process. - */ -# if PNG_USE_COMPILE_TIME_MASKS -# define PNG_LSR(x,s) ((x)>>((s) & 0x1f)) -# define PNG_LSL(x,s) ((x)<<((s) & 0x1f)) -# else -# define PNG_LSR(x,s) ((x)>>(s)) -# define PNG_LSL(x,s) ((x)<<(s)) -# endif -# define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\ - PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1) -# define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\ - PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1) - - /* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is - * little endian - the first pixel is at bit 0 - however the extra - * parameter 's' can be set to cause the mask position to be swapped - * within each byte, to match the PNG format. This is done by XOR of - * the shift with 7, 6 or 4 for bit depths 1, 2 and 4. - */ -# define PIXEL_MASK(p,x,d,s) \ - (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0)))) - - /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask. - */ -# define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) -# define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0) - - /* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp - * cases the result needs replicating, for the 4-bpp case the above - * generates a full 32 bits. - */ -# define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1))) - -# define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\ - S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\ - S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d) - -# define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\ - B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\ - B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d) - -#if PNG_USE_COMPILE_TIME_MASKS - /* Utility macros to construct all the masks for a depth/swap - * combination. The 's' parameter says whether the format is PNG - * (big endian bytes) or not. Only the three odd-numbered passes are - * required for the display/block algorithm. - */ -# define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\ - S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) } - -# define B_MASKS(d,s) { B_MASK(1,d,s), B_MASK(3,d,s), B_MASK(5,d,s) } - -# define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2)) - - /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and - * then pass: - */ - static const png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = - { - /* Little-endian byte masks for PACKSWAP */ - { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) }, - /* Normal (big-endian byte) masks - PNG format */ - { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) } - }; - - /* display_mask has only three entries for the odd passes, so index by - * pass>>1. - */ - static const png_uint_32 display_mask[2][3][3] = - { - /* Little-endian byte masks for PACKSWAP */ - { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) }, - /* Normal (big-endian byte) masks - PNG format */ - { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) } - }; - -# define MASK(pass,depth,display,png)\ - ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\ - row_mask[png][DEPTH_INDEX(depth)][pass]) - -#else /* !PNG_USE_COMPILE_TIME_MASKS */ - /* This is the runtime alternative: it seems unlikely that this will - * ever be either smaller or faster than the compile time approach. - */ -# define MASK(pass,depth,display,png)\ - ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png)) -#endif /* !USE_COMPILE_TIME_MASKS */ - - /* Use the appropriate mask to copy the required bits. In some cases - * the byte mask will be 0 or 0xff; optimize these cases. row_width is - * the number of pixels, but the code copies bytes, so it is necessary - * to special case the end. - */ - png_uint_32 pixels_per_byte = 8 / pixel_depth; - png_uint_32 mask; - -# ifdef PNG_READ_PACKSWAP_SUPPORTED - if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - mask = MASK(pass, pixel_depth, display, 0); - - else -# endif - mask = MASK(pass, pixel_depth, display, 1); - - for (;;) - { - png_uint_32 m; - - /* It doesn't matter in the following if png_uint_32 has more than - * 32 bits because the high bits always match those in m<<24; it is, - * however, essential to use OR here, not +, because of this. - */ - m = mask; - mask = (m >> 8) | (m << 24); /* rotate right to good compilers */ - m &= 0xff; - - if (m != 0) /* something to copy */ - { - if (m != 0xff) - *dp = (png_byte)((*dp & ~m) | (*sp & m)); - else - *dp = *sp; - } - - /* NOTE: this may overwrite the last byte with garbage if the image - * is not an exact number of bytes wide; libpng has always done - * this. - */ - if (row_width <= pixels_per_byte) - break; /* May need to restore part of the last byte */ - - row_width -= pixels_per_byte; - ++dp; - ++sp; - } - } - - else /* pixel_depth >= 8 */ - { - unsigned int bytes_to_copy, bytes_to_jump; - - /* Validate the depth - it must be a multiple of 8 */ - if (pixel_depth & 7) - png_error(png_ptr, "invalid user transform pixel depth"); - - pixel_depth >>= 3; /* now in bytes */ - row_width *= pixel_depth; - - /* Regardless of pass number the Adam 7 interlace always results in a - * fixed number of pixels to copy then to skip. There may be a - * different number of pixels to skip at the start though. - */ - { - unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth; - - row_width -= offset; - dp += offset; - sp += offset; - } - - /* Work out the bytes to copy. */ - if (display != 0) - { - /* When doing the 'block' algorithm the pixel in the pass gets - * replicated to adjacent pixels. This is why the even (0,2,4,6) - * passes are skipped above - the entire expanded row is copied. - */ - bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth; - - /* But don't allow this number to exceed the actual row width. */ - if (bytes_to_copy > row_width) - bytes_to_copy = (unsigned int)/*SAFE*/row_width; - } - - else /* normal row; Adam7 only ever gives us one pixel to copy. */ - bytes_to_copy = pixel_depth; - - /* In Adam7 there is a constant offset between where the pixels go. */ - bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth; - - /* And simply copy these bytes. Some optimization is possible here, - * depending on the value of 'bytes_to_copy'. Special case the low - * byte counts, which we know to be frequent. - * - * Notice that these cases all 'return' rather than 'break' - this - * avoids an unnecessary test on whether to restore the last byte - * below. - */ - switch (bytes_to_copy) - { - case 1: - for (;;) - { - *dp = *sp; - - if (row_width <= bytes_to_jump) - return; - - dp += bytes_to_jump; - sp += bytes_to_jump; - row_width -= bytes_to_jump; - } - - case 2: - /* There is a possibility of a partial copy at the end here; this - * slows the code down somewhat. - */ - do - { - dp[0] = sp[0]; dp[1] = sp[1]; - - if (row_width <= bytes_to_jump) - return; - - sp += bytes_to_jump; - dp += bytes_to_jump; - row_width -= bytes_to_jump; - } - while (row_width > 1); - - /* And there can only be one byte left at this point: */ - *dp = *sp; - return; - - case 3: - /* This can only be the RGB case, so each copy is exactly one - * pixel and it is not necessary to check for a partial copy. - */ - for (;;) - { - dp[0] = sp[0]; dp[1] = sp[1]; dp[2] = sp[2]; - - if (row_width <= bytes_to_jump) - return; - - sp += bytes_to_jump; - dp += bytes_to_jump; - row_width -= bytes_to_jump; - } - - default: -#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE - /* Check for double byte alignment and, if possible, use a - * 16-bit copy. Don't attempt this for narrow images - ones that - * are less than an interlace panel wide. Don't attempt it for - * wide bytes_to_copy either - use the memcpy there. - */ - if (bytes_to_copy < 16 /*else use memcpy*/ && - png_isaligned(dp, png_uint_16) && - png_isaligned(sp, png_uint_16) && - bytes_to_copy % (sizeof (png_uint_16)) == 0 && - bytes_to_jump % (sizeof (png_uint_16)) == 0) - { - /* Everything is aligned for png_uint_16 copies, but try for - * png_uint_32 first. - */ - if (png_isaligned(dp, png_uint_32) && - png_isaligned(sp, png_uint_32) && - bytes_to_copy % (sizeof (png_uint_32)) == 0 && - bytes_to_jump % (sizeof (png_uint_32)) == 0) - { - png_uint_32p dp32 = png_aligncast(png_uint_32p,dp); - png_const_uint_32p sp32 = png_aligncastconst( - png_const_uint_32p, sp); - size_t skip = (bytes_to_jump-bytes_to_copy) / - (sizeof (png_uint_32)); - - do - { - size_t c = bytes_to_copy; - do - { - *dp32++ = *sp32++; - c -= (sizeof (png_uint_32)); - } - while (c > 0); - - if (row_width <= bytes_to_jump) - return; - - dp32 += skip; - sp32 += skip; - row_width -= bytes_to_jump; - } - while (bytes_to_copy <= row_width); - - /* Get to here when the row_width truncates the final copy. - * There will be 1-3 bytes left to copy, so don't try the - * 16-bit loop below. - */ - dp = (png_bytep)dp32; - sp = (png_const_bytep)sp32; - do - *dp++ = *sp++; - while (--row_width > 0); - return; - } - - /* Else do it in 16-bit quantities, but only if the size is - * not too large. - */ - else - { - png_uint_16p dp16 = png_aligncast(png_uint_16p, dp); - png_const_uint_16p sp16 = png_aligncastconst( - png_const_uint_16p, sp); - size_t skip = (bytes_to_jump-bytes_to_copy) / - (sizeof (png_uint_16)); - - do - { - size_t c = bytes_to_copy; - do - { - *dp16++ = *sp16++; - c -= (sizeof (png_uint_16)); - } - while (c > 0); - - if (row_width <= bytes_to_jump) - return; - - dp16 += skip; - sp16 += skip; - row_width -= bytes_to_jump; - } - while (bytes_to_copy <= row_width); - - /* End of row - 1 byte left, bytes_to_copy > row_width: */ - dp = (png_bytep)dp16; - sp = (png_const_bytep)sp16; - do - *dp++ = *sp++; - while (--row_width > 0); - return; - } - } -#endif /* ALIGN_TYPE code */ - - /* The true default - use a memcpy: */ - for (;;) - { - memcpy(dp, sp, bytes_to_copy); - - if (row_width <= bytes_to_jump) - return; - - sp += bytes_to_jump; - dp += bytes_to_jump; - row_width -= bytes_to_jump; - if (bytes_to_copy > row_width) - bytes_to_copy = (unsigned int)/*SAFE*/row_width; - } - } - - /* NOT REACHED*/ - } /* pixel_depth >= 8 */ - - /* Here if pixel_depth < 8 to check 'end_ptr' below. */ - } - else -#endif /* READ_INTERLACING */ - - /* If here then the switch above wasn't used so just memcpy the whole row - * from the temporary row buffer (notice that this overwrites the end of the - * destination row if it is a partial byte.) - */ - memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width)); - - /* Restore the overwritten bits from the last byte if necessary. */ - if (end_ptr != NULL) - *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask)); -} - -#ifdef PNG_READ_INTERLACING_SUPPORTED -void /* PRIVATE */ -png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, - png_uint_32 transformations /* Because these may affect the byte layout */) -{ - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - /* Offset to next interlace block */ - static const unsigned int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - png_debug(1, "in png_do_read_interlace"); - if (row != NULL && row_info != NULL) - { - png_uint_32 final_width; - - final_width = row_info->width * png_pass_inc[pass]; - - switch (row_info->pixel_depth) - { - case 1: - { - png_bytep sp = row + (size_t)((row_info->width - 1) >> 3); - png_bytep dp = row + (size_t)((final_width - 1) >> 3); - unsigned int sshift, dshift; - unsigned int s_start, s_end; - int s_inc; - int jstop = (int)png_pass_inc[pass]; - png_byte v; - png_uint_32 i; - int j; - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if ((transformations & PNG_PACKSWAP) != 0) - { - sshift = ((row_info->width + 7) & 0x07); - dshift = ((final_width + 7) & 0x07); - s_start = 7; - s_end = 0; - s_inc = -1; - } - - else -#endif - { - sshift = 7 - ((row_info->width + 7) & 0x07); - dshift = 7 - ((final_width + 7) & 0x07); - s_start = 0; - s_end = 7; - s_inc = 1; - } - - for (i = 0; i < row_info->width; i++) - { - v = (png_byte)((*sp >> sshift) & 0x01); - for (j = 0; j < jstop; j++) - { - unsigned int tmp = *dp & (0x7f7f >> (7 - dshift)); - tmp |= (unsigned int)(v << dshift); - *dp = (png_byte)(tmp & 0xff); - - if (dshift == s_end) - { - dshift = s_start; - dp--; - } - - else - dshift = (unsigned int)((int)dshift + s_inc); - } - - if (sshift == s_end) - { - sshift = s_start; - sp--; - } - - else - sshift = (unsigned int)((int)sshift + s_inc); - } - break; - } - - case 2: - { - png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); - png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); - unsigned int sshift, dshift; - unsigned int s_start, s_end; - int s_inc; - int jstop = (int)png_pass_inc[pass]; - png_uint_32 i; - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if ((transformations & PNG_PACKSWAP) != 0) - { - sshift = (((row_info->width + 3) & 0x03) << 1); - dshift = (((final_width + 3) & 0x03) << 1); - s_start = 6; - s_end = 0; - s_inc = -2; - } - - else -#endif - { - sshift = ((3 - ((row_info->width + 3) & 0x03)) << 1); - dshift = ((3 - ((final_width + 3) & 0x03)) << 1); - s_start = 0; - s_end = 6; - s_inc = 2; - } - - for (i = 0; i < row_info->width; i++) - { - png_byte v; - int j; - - v = (png_byte)((*sp >> sshift) & 0x03); - for (j = 0; j < jstop; j++) - { - unsigned int tmp = *dp & (0x3f3f >> (6 - dshift)); - tmp |= (unsigned int)(v << dshift); - *dp = (png_byte)(tmp & 0xff); - - if (dshift == s_end) - { - dshift = s_start; - dp--; - } - - else - dshift = (unsigned int)((int)dshift + s_inc); - } - - if (sshift == s_end) - { - sshift = s_start; - sp--; - } - - else - sshift = (unsigned int)((int)sshift + s_inc); - } - break; - } - - case 4: - { - png_bytep sp = row + (size_t)((row_info->width - 1) >> 1); - png_bytep dp = row + (size_t)((final_width - 1) >> 1); - unsigned int sshift, dshift; - unsigned int s_start, s_end; - int s_inc; - png_uint_32 i; - int jstop = (int)png_pass_inc[pass]; - -#ifdef PNG_READ_PACKSWAP_SUPPORTED - if ((transformations & PNG_PACKSWAP) != 0) - { - sshift = (((row_info->width + 1) & 0x01) << 2); - dshift = (((final_width + 1) & 0x01) << 2); - s_start = 4; - s_end = 0; - s_inc = -4; - } - - else -#endif - { - sshift = ((1 - ((row_info->width + 1) & 0x01)) << 2); - dshift = ((1 - ((final_width + 1) & 0x01)) << 2); - s_start = 0; - s_end = 4; - s_inc = 4; - } - - for (i = 0; i < row_info->width; i++) - { - png_byte v = (png_byte)((*sp >> sshift) & 0x0f); - int j; - - for (j = 0; j < jstop; j++) - { - unsigned int tmp = *dp & (0xf0f >> (4 - dshift)); - tmp |= (unsigned int)(v << dshift); - *dp = (png_byte)(tmp & 0xff); - - if (dshift == s_end) - { - dshift = s_start; - dp--; - } - - else - dshift = (unsigned int)((int)dshift + s_inc); - } - - if (sshift == s_end) - { - sshift = s_start; - sp--; - } - - else - sshift = (unsigned int)((int)sshift + s_inc); - } - break; - } - - default: - { - size_t pixel_bytes = (row_info->pixel_depth >> 3); - - png_bytep sp = row + (size_t)(row_info->width - 1) - * pixel_bytes; - - png_bytep dp = row + (size_t)(final_width - 1) * pixel_bytes; - - int jstop = (int)png_pass_inc[pass]; - png_uint_32 i; - - for (i = 0; i < row_info->width; i++) - { - png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */ - int j; - - memcpy(v, sp, pixel_bytes); - - for (j = 0; j < jstop; j++) - { - memcpy(dp, v, pixel_bytes); - dp -= pixel_bytes; - } - - sp -= pixel_bytes; - } - break; - } - } - - row_info->width = final_width; - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); - } -#ifndef PNG_READ_PACKSWAP_SUPPORTED - PNG_UNUSED(transformations) /* Silence compiler warning */ -#endif -} -#endif /* READ_INTERLACING */ - -static void -png_read_filter_row_sub(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - size_t i; - size_t istop = row_info->rowbytes; - unsigned int bpp = (row_info->pixel_depth + 7) >> 3; - png_bytep rp = row + bpp; - - PNG_UNUSED(prev_row) - - for (i = bpp; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff); - rp++; - } -} - -static void -png_read_filter_row_up(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - size_t i; - size_t istop = row_info->rowbytes; - png_bytep rp = row; - png_const_bytep pp = prev_row; - - for (i = 0; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); - rp++; - } -} - -static void -png_read_filter_row_avg(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - size_t i; - png_bytep rp = row; - png_const_bytep pp = prev_row; - unsigned int bpp = (row_info->pixel_depth + 7) >> 3; - size_t istop = row_info->rowbytes - bpp; - - for (i = 0; i < bpp; i++) - { - *rp = (png_byte)(((int)(*rp) + - ((int)(*pp++) / 2 )) & 0xff); - - rp++; - } - - for (i = 0; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + - (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff); - - rp++; - } -} - -static void -png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - png_bytep rp_end = row + row_info->rowbytes; - int a, c; - - /* First pixel/byte */ - c = *prev_row++; - a = *row + c; - *row++ = (png_byte)a; - - /* Remainder */ - while (row < rp_end) - { - int b, pa, pb, pc, p; - - a &= 0xff; /* From previous iteration or start */ - b = *prev_row++; - - p = b - c; - pc = a - c; - -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - - /* Find the best predictor, the least of pa, pb, pc favoring the earlier - * ones in the case of a tie. - */ - if (pb < pa) - { - pa = pb; a = b; - } - if (pc < pa) a = c; - - /* Calculate the current pixel in a, and move the previous row pixel to c - * for the next time round the loop - */ - c = b; - a += *row; - *row++ = (png_byte)a; - } -} - -static void -png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) -{ - unsigned int bpp = (row_info->pixel_depth + 7) >> 3; - png_bytep rp_end = row + bpp; - - /* Process the first pixel in the row completely (this is the same as 'up' - * because there is only one candidate predictor for the first row). - */ - while (row < rp_end) - { - int a = *row + *prev_row++; - *row++ = (png_byte)a; - } - - /* Remainder */ - rp_end = rp_end + (row_info->rowbytes - bpp); - - while (row < rp_end) - { - int a, b, c, pa, pb, pc, p; - - c = *(prev_row - bpp); - a = *(row - bpp); - b = *prev_row++; - - p = b - c; - pc = a - c; - -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - - if (pb < pa) - { - pa = pb; a = b; - } - if (pc < pa) a = c; - - a += *row; - *row++ = (png_byte)a; - } -} - -static void -png_init_filter_functions(png_structrp pp) - /* This function is called once for every PNG image (except for PNG images - * that only use PNG_FILTER_VALUE_NONE for all rows) to set the - * implementations required to reverse the filtering of PNG rows. Reversing - * the filter is the first transformation performed on the row data. It is - * performed in place, therefore an implementation can be selected based on - * the image pixel format. If the implementation depends on image width then - * take care to ensure that it works correctly if the image is interlaced - - * interlacing causes the actual row width to vary. - */ -{ - unsigned int bpp = (pp->pixel_depth + 7) >> 3; - - pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub; - pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up; - pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg; - if (bpp == 1) - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth_1byte_pixel; - else - pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = - png_read_filter_row_paeth_multibyte_pixel; - -#ifdef PNG_FILTER_OPTIMIZATIONS - /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to - * call to install hardware optimizations for the above functions; simply - * replace whatever elements of the pp->read_filter[] array with a hardware - * specific (or, for that matter, generic) optimization. - * - * To see an example of this examine what configure.ac does when - * --enable-arm-neon is specified on the command line. - */ - PNG_FILTER_OPTIMIZATIONS(pp, bpp); -#endif -} - -void /* PRIVATE */ -png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row, - png_const_bytep prev_row, int filter) -{ - /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define - * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic - * implementations. See png_init_filter_functions above. - */ - if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST) - { - if (pp->read_filter[0] == NULL) - png_init_filter_functions(pp); - - pp->read_filter[filter-1](row_info, row, prev_row); - } -} - -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED -void /* PRIVATE */ -png_read_IDAT_data(png_structrp png_ptr, png_bytep output, - png_alloc_size_t avail_out) -{ - /* Loop reading IDATs and decompressing the result into output[avail_out] */ - png_ptr->zstream.next_out = output; - png_ptr->zstream.avail_out = 0; /* safety: set below */ - - if (output == NULL) - avail_out = 0; - - do - { - int ret; - png_byte tmpbuf[PNG_INFLATE_BUF_SIZE]; - - if (png_ptr->zstream.avail_in == 0) - { - uInt avail_in; - png_bytep buffer; - - while (png_ptr->idat_size == 0) - { - png_crc_finish(png_ptr, 0); - - png_ptr->idat_size = png_read_chunk_header(png_ptr); - /* This is an error even in the 'check' case because the code just - * consumed a non-IDAT header. - */ - if (png_ptr->chunk_name != png_IDAT) - png_error(png_ptr, "Not enough image data"); - } - - avail_in = png_ptr->IDAT_read_size; - - if (avail_in > png_ptr->idat_size) - avail_in = (uInt)png_ptr->idat_size; - - /* A PNG with a gradually increasing IDAT size will defeat this attempt - * to minimize memory usage by causing lots of re-allocs, but - * realistically doing IDAT_read_size re-allocs is not likely to be a - * big problem. - */ - buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/); - - png_crc_read(png_ptr, buffer, avail_in); - png_ptr->idat_size -= avail_in; - - png_ptr->zstream.next_in = buffer; - png_ptr->zstream.avail_in = avail_in; - } - - /* And set up the output side. */ - if (output != NULL) /* standard read */ - { - uInt out = ZLIB_IO_MAX; - - if (out > avail_out) - out = (uInt)avail_out; - - avail_out -= out; - png_ptr->zstream.avail_out = out; - } - - else /* after last row, checking for end */ - { - png_ptr->zstream.next_out = tmpbuf; - png_ptr->zstream.avail_out = (sizeof tmpbuf); - } - - /* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the - * process. If the LZ stream is truncated the sequential reader will - * terminally damage the stream, above, by reading the chunk header of the - * following chunk (it then exits with png_error). - * - * TODO: deal more elegantly with truncated IDAT lists. - */ - ret = PNG_INFLATE(png_ptr, Z_NO_FLUSH); - - /* Take the unconsumed output back. */ - if (output != NULL) - avail_out += png_ptr->zstream.avail_out; - - else /* avail_out counts the extra bytes */ - avail_out += (sizeof tmpbuf) - png_ptr->zstream.avail_out; - - png_ptr->zstream.avail_out = 0; - - if (ret == Z_STREAM_END) - { - /* Do this for safety; we won't read any more into this row. */ - png_ptr->zstream.next_out = NULL; - - png_ptr->mode |= PNG_AFTER_IDAT; - png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; - - if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0) - png_chunk_benign_error(png_ptr, "Extra compressed data"); - break; - } - - if (ret != Z_OK) - { - png_zstream_error(png_ptr, ret); - - if (output != NULL) - png_chunk_error(png_ptr, png_ptr->zstream.msg); - - else /* checking */ - { - png_chunk_benign_error(png_ptr, png_ptr->zstream.msg); - return; - } - } - } while (avail_out > 0); - - if (avail_out > 0) - { - /* The stream ended before the image; this is the same as too few IDATs so - * should be handled the same way. - */ - if (output != NULL) - png_error(png_ptr, "Not enough image data"); - - else /* the deflate stream contained extra data */ - png_chunk_benign_error(png_ptr, "Too much image data"); - } -} - -void /* PRIVATE */ -png_read_finish_IDAT(png_structrp png_ptr) -{ - /* We don't need any more data and the stream should have ended, however the - * LZ end code may actually not have been processed. In this case we must - * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk - * may still remain to be consumed. - */ - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) - { - /* The NULL causes png_read_IDAT_data to swallow any remaining bytes in - * the compressed stream, but the stream may be damaged too, so even after - * this call we may need to terminate the zstream ownership. - */ - png_read_IDAT_data(png_ptr, NULL, 0); - png_ptr->zstream.next_out = NULL; /* safety */ - - /* Now clear everything out for safety; the following may not have been - * done. - */ - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) - { - png_ptr->mode |= PNG_AFTER_IDAT; - png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; - } - } - - /* If the zstream has not been released do it now *and* terminate the reading - * of the final IDAT chunk. - */ - if (png_ptr->zowner == png_IDAT) - { - /* Always do this; the pointers otherwise point into the read buffer. */ - png_ptr->zstream.next_in = NULL; - png_ptr->zstream.avail_in = 0; - - /* Now we no longer own the zstream. */ - png_ptr->zowner = 0; - - /* The slightly weird semantics of the sequential IDAT reading is that we - * are always in or at the end of an IDAT chunk, so we always need to do a - * crc_finish here. If idat_size is non-zero we also need to read the - * spurious bytes at the end of the chunk now. - */ - (void)png_crc_finish(png_ptr, png_ptr->idat_size); - } -} - -void /* PRIVATE */ -png_read_finish_row(png_structrp png_ptr) -{ - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; - - png_debug(1, "in png_read_finish_row"); - png_ptr->row_number++; - if (png_ptr->row_number < png_ptr->num_rows) - return; - - if (png_ptr->interlaced != 0) - { - png_ptr->row_number = 0; - - /* TO DO: don't do this if prev_row isn't needed (requires - * read-ahead of the next row's filter byte. - */ - memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); - - do - { - png_ptr->pass++; - - if (png_ptr->pass >= 7) - break; - - png_ptr->iwidth = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - - if ((png_ptr->transformations & PNG_INTERLACE) == 0) - { - png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; - } - - else /* if (png_ptr->transformations & PNG_INTERLACE) */ - break; /* libpng deinterlacing sees every row */ - - } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0); - - if (png_ptr->pass < 7) - return; - } - - /* Here after at the end of the last row of the last pass. */ - png_read_finish_IDAT(png_ptr); -} -#endif /* SEQUENTIAL_READ */ - -void /* PRIVATE */ -png_read_start_row(png_structrp png_ptr) -{ - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; - - unsigned int max_pixel_depth; - size_t row_bytes; - - png_debug(1, "in png_read_start_row"); - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED - png_init_read_transformations(png_ptr); -#endif - if (png_ptr->interlaced != 0) - { - if ((png_ptr->transformations & PNG_INTERLACE) == 0) - png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - - png_pass_ystart[0]) / png_pass_yinc[0]; - - else - png_ptr->num_rows = png_ptr->height; - - png_ptr->iwidth = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - } - - else - { - png_ptr->num_rows = png_ptr->height; - png_ptr->iwidth = png_ptr->width; - } - - max_pixel_depth = (unsigned int)png_ptr->pixel_depth; - - /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of - * calculations to calculate the final pixel depth, then - * png_do_read_transforms actually does the transforms. This means that the - * code which effectively calculates this value is actually repeated in three - * separate places. They must all match. Innocent changes to the order of - * transformations can and will break libpng in a way that causes memory - * overwrites. - * - * TODO: fix this. - */ -#ifdef PNG_READ_PACK_SUPPORTED - if ((png_ptr->transformations & PNG_PACK) != 0 && png_ptr->bit_depth < 8) - max_pixel_depth = 8; -#endif - -#ifdef PNG_READ_EXPAND_SUPPORTED - if ((png_ptr->transformations & PNG_EXPAND) != 0) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (png_ptr->num_trans != 0) - max_pixel_depth = 32; - - else - max_pixel_depth = 24; - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) - { - if (max_pixel_depth < 8) - max_pixel_depth = 8; - - if (png_ptr->num_trans != 0) - max_pixel_depth *= 2; - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) - { - if (png_ptr->num_trans != 0) - { - max_pixel_depth *= 4; - max_pixel_depth /= 3; - } - } - } -#endif - -#ifdef PNG_READ_EXPAND_16_SUPPORTED - if ((png_ptr->transformations & PNG_EXPAND_16) != 0) - { -# ifdef PNG_READ_EXPAND_SUPPORTED - /* In fact it is an error if it isn't supported, but checking is - * the safe way. - */ - if ((png_ptr->transformations & PNG_EXPAND) != 0) - { - if (png_ptr->bit_depth < 16) - max_pixel_depth *= 2; - } - else -# endif - png_ptr->transformations &= ~PNG_EXPAND_16; - } -#endif - -#ifdef PNG_READ_FILLER_SUPPORTED - if ((png_ptr->transformations & (PNG_FILLER)) != 0) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) - { - if (max_pixel_depth <= 8) - max_pixel_depth = 16; - - else - max_pixel_depth = 32; - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB || - png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - if (max_pixel_depth <= 32) - max_pixel_depth = 32; - - else - max_pixel_depth = 64; - } - } -#endif - -#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0) - { - if ( -#ifdef PNG_READ_EXPAND_SUPPORTED - (png_ptr->num_trans != 0 && - (png_ptr->transformations & PNG_EXPAND) != 0) || -#endif -#ifdef PNG_READ_FILLER_SUPPORTED - (png_ptr->transformations & (PNG_FILLER)) != 0 || -#endif - png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (max_pixel_depth <= 16) - max_pixel_depth = 32; - - else - max_pixel_depth = 64; - } - - else - { - if (max_pixel_depth <= 8) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - max_pixel_depth = 32; - - else - max_pixel_depth = 24; - } - - else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - max_pixel_depth = 64; - - else - max_pixel_depth = 48; - } - } -#endif - -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ -defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) - if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) - { - unsigned int user_pixel_depth = png_ptr->user_transform_depth * - png_ptr->user_transform_channels; - - if (user_pixel_depth > max_pixel_depth) - max_pixel_depth = user_pixel_depth; - } -#endif - - /* This value is stored in png_struct and double checked in the row read - * code. - */ - png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth; - png_ptr->transformed_pixel_depth = 0; /* calculated on demand */ - - /* Align the width on the next larger 8 pixels. Mainly used - * for interlacing - */ - row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); - /* Calculate the maximum bytes needed, adding a byte and a pixel - * for safety's sake - */ - row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + - 1 + ((max_pixel_depth + 7) >> 3U); - -#ifdef PNG_MAX_MALLOC_64K - if (row_bytes > (png_uint_32)65536L) - png_error(png_ptr, "This image requires a row greater than 64KB"); -#endif - - if (row_bytes + 48 > png_ptr->old_big_row_buf_size) - { - png_free(png_ptr, png_ptr->big_row_buf); - png_free(png_ptr, png_ptr->big_prev_row); - - if (png_ptr->interlaced != 0) - png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, - row_bytes + 48); - - else - png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48); - - png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48); - -#ifdef PNG_ALIGNED_MEMORY_SUPPORTED - /* Use 16-byte aligned memory for row_buf with at least 16 bytes - * of padding before and after row_buf; treat prev_row similarly. - * NOTE: the alignment is to the start of the pixels, one beyond the start - * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this - * was incorrect; the filter byte was aligned, which had the exact - * opposite effect of that intended. - */ - { - png_bytep temp = png_ptr->big_row_buf + 32; - int extra = (int)((temp - (png_bytep)0) & 0x0f); - png_ptr->row_buf = temp - extra - 1/*filter byte*/; - - temp = png_ptr->big_prev_row + 32; - extra = (int)((temp - (png_bytep)0) & 0x0f); - png_ptr->prev_row = temp - extra - 1/*filter byte*/; - } - -#else - /* Use 31 bytes of padding before and 17 bytes after row_buf. */ - png_ptr->row_buf = png_ptr->big_row_buf + 31; - png_ptr->prev_row = png_ptr->big_prev_row + 31; -#endif - png_ptr->old_big_row_buf_size = row_bytes + 48; - } - -#ifdef PNG_MAX_MALLOC_64K - if (png_ptr->rowbytes > 65535) - png_error(png_ptr, "This image requires a row greater than 64KB"); - -#endif - if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1)) - png_error(png_ptr, "Row has too many bytes to allocate in memory"); - - memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); - - png_debug1(3, "width = %u,", png_ptr->width); - png_debug1(3, "height = %u,", png_ptr->height); - png_debug1(3, "iwidth = %u,", png_ptr->iwidth); - png_debug1(3, "num_rows = %u,", png_ptr->num_rows); - png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes); - png_debug1(3, "irowbytes = %lu", - (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); - - /* The sequential reader needs a buffer for IDAT, but the progressive reader - * does not, so free the read buffer now regardless; the sequential reader - * reallocates it on demand. - */ - if (png_ptr->read_buffer != NULL) - { - png_bytep buffer = png_ptr->read_buffer; - - png_ptr->read_buffer_size = 0; - png_ptr->read_buffer = NULL; - png_free(png_ptr, buffer); - } - - /* Finally claim the zstream for the inflate of the IDAT data, use the bits - * value from the stream (note that this will result in a fatal error if the - * IDAT stream has a bogus deflate header window_bits value, but this should - * not be happening any longer!) - */ - if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK) - png_error(png_ptr, png_ptr->zstream.msg); - - png_ptr->flags |= PNG_FLAG_ROW_INIT; -} -#endif /* READ */ diff --git a/extern/libpng/pngset.c b/extern/libpng/pngset.c deleted file mode 100644 index ec75dbe36..000000000 --- a/extern/libpng/pngset.c +++ /dev/null @@ -1,1802 +0,0 @@ - -/* pngset.c - storage of image information into info struct - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * The functions here are used during reads to store data from the file - * into the info struct, and during writes to store application data - * into the info struct for writing into the file. This abstracts the - * info struct and allows us to change the structure in the future. - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -#ifdef PNG_bKGD_SUPPORTED -void PNGAPI -png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_color_16p background) -{ - png_debug1(1, "in %s storage function", "bKGD"); - - if (png_ptr == NULL || info_ptr == NULL || background == NULL) - return; - - info_ptr->background = *background; - info_ptr->valid |= PNG_INFO_bKGD; -} -#endif - -#ifdef PNG_cHRM_SUPPORTED -void PNGFAPI -png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr, - png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, - png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, - png_fixed_point blue_x, png_fixed_point blue_y) -{ - png_xy xy; - - png_debug1(1, "in %s storage function", "cHRM fixed"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - xy.redx = red_x; - xy.redy = red_y; - xy.greenx = green_x; - xy.greeny = green_y; - xy.bluex = blue_x; - xy.bluey = blue_y; - xy.whitex = white_x; - xy.whitey = white_y; - - if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy, - 2/* override with app values*/) != 0) - info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; - - png_colorspace_sync_info(png_ptr, info_ptr); -} - -void PNGFAPI -png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr, - png_fixed_point int_red_X, png_fixed_point int_red_Y, - png_fixed_point int_red_Z, png_fixed_point int_green_X, - png_fixed_point int_green_Y, png_fixed_point int_green_Z, - png_fixed_point int_blue_X, png_fixed_point int_blue_Y, - png_fixed_point int_blue_Z) -{ - png_XYZ XYZ; - - png_debug1(1, "in %s storage function", "cHRM XYZ fixed"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - XYZ.red_X = int_red_X; - XYZ.red_Y = int_red_Y; - XYZ.red_Z = int_red_Z; - XYZ.green_X = int_green_X; - XYZ.green_Y = int_green_Y; - XYZ.green_Z = int_green_Z; - XYZ.blue_X = int_blue_X; - XYZ.blue_Y = int_blue_Y; - XYZ.blue_Z = int_blue_Z; - - if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace, - &XYZ, 2) != 0) - info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM; - - png_colorspace_sync_info(png_ptr, info_ptr); -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, - double white_x, double white_y, double red_x, double red_y, - double green_x, double green_y, double blue_x, double blue_y) -{ - png_set_cHRM_fixed(png_ptr, info_ptr, - png_fixed(png_ptr, white_x, "cHRM White X"), - png_fixed(png_ptr, white_y, "cHRM White Y"), - png_fixed(png_ptr, red_x, "cHRM Red X"), - png_fixed(png_ptr, red_y, "cHRM Red Y"), - png_fixed(png_ptr, green_x, "cHRM Green X"), - png_fixed(png_ptr, green_y, "cHRM Green Y"), - png_fixed(png_ptr, blue_x, "cHRM Blue X"), - png_fixed(png_ptr, blue_y, "cHRM Blue Y")); -} - -void PNGAPI -png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X, - double red_Y, double red_Z, double green_X, double green_Y, double green_Z, - double blue_X, double blue_Y, double blue_Z) -{ - png_set_cHRM_XYZ_fixed(png_ptr, info_ptr, - png_fixed(png_ptr, red_X, "cHRM Red X"), - png_fixed(png_ptr, red_Y, "cHRM Red Y"), - png_fixed(png_ptr, red_Z, "cHRM Red Z"), - png_fixed(png_ptr, green_X, "cHRM Green X"), - png_fixed(png_ptr, green_Y, "cHRM Green Y"), - png_fixed(png_ptr, green_Z, "cHRM Green Z"), - png_fixed(png_ptr, blue_X, "cHRM Blue X"), - png_fixed(png_ptr, blue_Y, "cHRM Blue Y"), - png_fixed(png_ptr, blue_Z, "cHRM Blue Z")); -} -# endif /* FLOATING_POINT */ - -#endif /* cHRM */ - -#ifdef PNG_eXIf_SUPPORTED -void PNGAPI -png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr, - png_bytep eXIf_buf) -{ - png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1"); - PNG_UNUSED(info_ptr) - PNG_UNUSED(eXIf_buf) -} - -void PNGAPI -png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_32 num_exif, png_bytep eXIf_buf) -{ - int i; - - png_debug1(1, "in %s storage function", "eXIf"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (info_ptr->exif) - { - png_free(png_ptr, info_ptr->exif); - info_ptr->exif = NULL; - } - - info_ptr->num_exif = num_exif; - - info_ptr->exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr, - info_ptr->num_exif)); - - if (info_ptr->exif == NULL) - { - png_warning(png_ptr, "Insufficient memory for eXIf chunk data"); - return; - } - - info_ptr->free_me |= PNG_FREE_EXIF; - - for (i = 0; i < (int) info_ptr->num_exif; i++) - info_ptr->exif[i] = eXIf_buf[i]; - - info_ptr->valid |= PNG_INFO_eXIf; -} -#endif /* eXIf */ - -#ifdef PNG_gAMA_SUPPORTED -void PNGFAPI -png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr, - png_fixed_point file_gamma) -{ - png_debug1(1, "in %s storage function", "gAMA"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma); - png_colorspace_sync_info(png_ptr, info_ptr); -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma) -{ - png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma, - "png_set_gAMA")); -} -# endif -#endif - -#ifdef PNG_hIST_SUPPORTED -void PNGAPI -png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_uint_16p hist) -{ - int i; - - png_debug1(1, "in %s storage function", "hIST"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (info_ptr->num_palette == 0 || info_ptr->num_palette - > PNG_MAX_PALETTE_LENGTH) - { - png_warning(png_ptr, - "Invalid palette size, hIST allocation skipped"); - - return; - } - - png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); - - /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in - * version 1.2.1 - */ - info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr, - PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16)))); - - if (info_ptr->hist == NULL) - { - png_warning(png_ptr, "Insufficient memory for hIST chunk data"); - - return; - } - - info_ptr->free_me |= PNG_FREE_HIST; - - for (i = 0; i < info_ptr->num_palette; i++) - info_ptr->hist[i] = hist[i]; - - info_ptr->valid |= PNG_INFO_hIST; -} -#endif - -void PNGAPI -png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type) -{ - png_debug1(1, "in %s storage function", "IHDR"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->width = width; - info_ptr->height = height; - info_ptr->bit_depth = (png_byte)bit_depth; - info_ptr->color_type = (png_byte)color_type; - info_ptr->compression_type = (png_byte)compression_type; - info_ptr->filter_type = (png_byte)filter_type; - info_ptr->interlace_type = (png_byte)interlace_type; - - png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height, - info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, - info_ptr->compression_type, info_ptr->filter_type); - - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - info_ptr->channels = 1; - - else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0) - info_ptr->channels = 3; - - else - info_ptr->channels = 1; - - if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0) - info_ptr->channels++; - - info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); - - info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); -} - -#ifdef PNG_oFFs_SUPPORTED -void PNGAPI -png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr, - png_int_32 offset_x, png_int_32 offset_y, int unit_type) -{ - png_debug1(1, "in %s storage function", "oFFs"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->x_offset = offset_x; - info_ptr->y_offset = offset_y; - info_ptr->offset_unit_type = (png_byte)unit_type; - info_ptr->valid |= PNG_INFO_oFFs; -} -#endif - -#ifdef PNG_pCAL_SUPPORTED -void PNGAPI -png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, - int nparams, png_const_charp units, png_charpp params) -{ - size_t length; - int i; - - png_debug1(1, "in %s storage function", "pCAL"); - - if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL - || (nparams > 0 && params == NULL)) - return; - - length = strlen(purpose) + 1; - png_debug1(3, "allocating purpose for info (%lu bytes)", - (unsigned long)length); - - /* TODO: validate format of calibration name and unit name */ - - /* Check that the type matches the specification. */ - if (type < 0 || type > 3) - { - png_chunk_report(png_ptr, "Invalid pCAL equation type", - PNG_CHUNK_WRITE_ERROR); - return; - } - - if (nparams < 0 || nparams > 255) - { - png_chunk_report(png_ptr, "Invalid pCAL parameter count", - PNG_CHUNK_WRITE_ERROR); - return; - } - - /* Validate params[nparams] */ - for (i=0; ipcal_purpose = png_voidcast(png_charp, - png_malloc_warn(png_ptr, length)); - - if (info_ptr->pcal_purpose == NULL) - { - png_chunk_report(png_ptr, "Insufficient memory for pCAL purpose", - PNG_CHUNK_WRITE_ERROR); - return; - } - - memcpy(info_ptr->pcal_purpose, purpose, length); - - png_debug(3, "storing X0, X1, type, and nparams in info"); - info_ptr->pcal_X0 = X0; - info_ptr->pcal_X1 = X1; - info_ptr->pcal_type = (png_byte)type; - info_ptr->pcal_nparams = (png_byte)nparams; - - length = strlen(units) + 1; - png_debug1(3, "allocating units for info (%lu bytes)", - (unsigned long)length); - - info_ptr->pcal_units = png_voidcast(png_charp, - png_malloc_warn(png_ptr, length)); - - if (info_ptr->pcal_units == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL units"); - - return; - } - - memcpy(info_ptr->pcal_units, units, length); - - info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, - (size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp))))); - - if (info_ptr->pcal_params == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL params"); - - return; - } - - memset(info_ptr->pcal_params, 0, ((unsigned int)nparams + 1) * - (sizeof (png_charp))); - - for (i = 0; i < nparams; i++) - { - length = strlen(params[i]) + 1; - png_debug2(3, "allocating parameter %d for info (%lu bytes)", i, - (unsigned long)length); - - info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length); - - if (info_ptr->pcal_params[i] == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL parameter"); - - return; - } - - memcpy(info_ptr->pcal_params[i], params[i], length); - } - - info_ptr->valid |= PNG_INFO_pCAL; - info_ptr->free_me |= PNG_FREE_PCAL; -} -#endif - -#ifdef PNG_sCAL_SUPPORTED -void PNGAPI -png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, - int unit, png_const_charp swidth, png_const_charp sheight) -{ - size_t lengthw = 0, lengthh = 0; - - png_debug1(1, "in %s storage function", "sCAL"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* Double check the unit (should never get here with an invalid - * unit unless this is an API call.) - */ - if (unit != 1 && unit != 2) - png_error(png_ptr, "Invalid sCAL unit"); - - if (swidth == NULL || (lengthw = strlen(swidth)) == 0 || - swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw)) - png_error(png_ptr, "Invalid sCAL width"); - - if (sheight == NULL || (lengthh = strlen(sheight)) == 0 || - sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh)) - png_error(png_ptr, "Invalid sCAL height"); - - info_ptr->scal_unit = (png_byte)unit; - - ++lengthw; - - png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw); - - info_ptr->scal_s_width = png_voidcast(png_charp, - png_malloc_warn(png_ptr, lengthw)); - - if (info_ptr->scal_s_width == NULL) - { - png_warning(png_ptr, "Memory allocation failed while processing sCAL"); - - return; - } - - memcpy(info_ptr->scal_s_width, swidth, lengthw); - - ++lengthh; - - png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh); - - info_ptr->scal_s_height = png_voidcast(png_charp, - png_malloc_warn(png_ptr, lengthh)); - - if (info_ptr->scal_s_height == NULL) - { - png_free (png_ptr, info_ptr->scal_s_width); - info_ptr->scal_s_width = NULL; - - png_warning(png_ptr, "Memory allocation failed while processing sCAL"); - - return; - } - - memcpy(info_ptr->scal_s_height, sheight, lengthh); - - info_ptr->valid |= PNG_INFO_sCAL; - info_ptr->free_me |= PNG_FREE_SCAL; -} - -# ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit, - double width, double height) -{ - png_debug1(1, "in %s storage function", "sCAL"); - - /* Check the arguments. */ - if (width <= 0) - png_warning(png_ptr, "Invalid sCAL width ignored"); - - else if (height <= 0) - png_warning(png_ptr, "Invalid sCAL height ignored"); - - else - { - /* Convert 'width' and 'height' to ASCII. */ - char swidth[PNG_sCAL_MAX_DIGITS+1]; - char sheight[PNG_sCAL_MAX_DIGITS+1]; - - png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width, - PNG_sCAL_PRECISION); - png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height, - PNG_sCAL_PRECISION); - - png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); - } -} -# endif - -# ifdef PNG_FIXED_POINT_SUPPORTED -void PNGAPI -png_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit, - png_fixed_point width, png_fixed_point height) -{ - png_debug1(1, "in %s storage function", "sCAL"); - - /* Check the arguments. */ - if (width <= 0) - png_warning(png_ptr, "Invalid sCAL width ignored"); - - else if (height <= 0) - png_warning(png_ptr, "Invalid sCAL height ignored"); - - else - { - /* Convert 'width' and 'height' to ASCII. */ - char swidth[PNG_sCAL_MAX_DIGITS+1]; - char sheight[PNG_sCAL_MAX_DIGITS+1]; - - png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width); - png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height); - - png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); - } -} -# endif -#endif - -#ifdef PNG_pHYs_SUPPORTED -void PNGAPI -png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr, - png_uint_32 res_x, png_uint_32 res_y, int unit_type) -{ - png_debug1(1, "in %s storage function", "pHYs"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->x_pixels_per_unit = res_x; - info_ptr->y_pixels_per_unit = res_y; - info_ptr->phys_unit_type = (png_byte)unit_type; - info_ptr->valid |= PNG_INFO_pHYs; -} -#endif - -void PNGAPI -png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr, - png_const_colorp palette, int num_palette) -{ - - png_uint_32 max_palette_length; - - png_debug1(1, "in %s storage function", "PLTE"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? - (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; - - if (num_palette < 0 || num_palette > (int) max_palette_length) - { - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - png_error(png_ptr, "Invalid palette length"); - - else - { - png_warning(png_ptr, "Invalid palette length"); - - return; - } - } - - if ((num_palette > 0 && palette == NULL) || - (num_palette == 0 -# ifdef PNG_MNG_FEATURES_SUPPORTED - && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 -# endif - )) - { - png_error(png_ptr, "Invalid palette"); - } - - /* It may not actually be necessary to set png_ptr->palette here; - * we do it for backward compatibility with the way the png_handle_tRNS - * function used to do the allocation. - * - * 1.6.0: the above statement appears to be incorrect; something has to set - * the palette inside png_struct on read. - */ - png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); - - /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead - * of num_palette entries, in case of an invalid PNG file or incorrect - * call to png_set_PLTE() with too-large sample values. - */ - png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr, - PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)))); - - if (num_palette > 0) - memcpy(png_ptr->palette, palette, (unsigned int)num_palette * - (sizeof (png_color))); - info_ptr->palette = png_ptr->palette; - info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; - - info_ptr->free_me |= PNG_FREE_PLTE; - - info_ptr->valid |= PNG_INFO_PLTE; -} - -#ifdef PNG_sBIT_SUPPORTED -void PNGAPI -png_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_color_8p sig_bit) -{ - png_debug1(1, "in %s storage function", "sBIT"); - - if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL) - return; - - info_ptr->sig_bit = *sig_bit; - info_ptr->valid |= PNG_INFO_sBIT; -} -#endif - -#ifdef PNG_sRGB_SUPPORTED -void PNGAPI -png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent) -{ - png_debug1(1, "in %s storage function", "sRGB"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent); - png_colorspace_sync_info(png_ptr, info_ptr); -} - -void PNGAPI -png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr, - int srgb_intent) -{ - png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, - srgb_intent) != 0) - { - /* This causes the gAMA and cHRM to be written too */ - info_ptr->colorspace.flags |= - PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; - } - - png_colorspace_sync_info(png_ptr, info_ptr); -} -#endif /* sRGB */ - - -#ifdef PNG_iCCP_SUPPORTED -void PNGAPI -png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_charp name, int compression_type, - png_const_bytep profile, png_uint_32 proflen) -{ - png_charp new_iccp_name; - png_bytep new_iccp_profile; - size_t length; - - png_debug1(1, "in %s storage function", "iCCP"); - - if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) - return; - - if (compression_type != PNG_COMPRESSION_TYPE_BASE) - png_app_error(png_ptr, "Invalid iCCP compression method"); - - /* Set the colorspace first because this validates the profile; do not - * override previously set app cHRM or gAMA here (because likely as not the - * application knows better than libpng what the correct values are.) Pass - * the info_ptr color_type field to png_colorspace_set_ICC because in the - * write case it has not yet been stored in png_ptr. - */ - { - int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name, - proflen, profile, info_ptr->color_type); - - png_colorspace_sync_info(png_ptr, info_ptr); - - /* Don't do any of the copying if the profile was bad, or inconsistent. */ - if (result == 0) - return; - - /* But do write the gAMA and cHRM chunks from the profile. */ - info_ptr->colorspace.flags |= - PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM; - } - - length = strlen(name)+1; - new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length)); - - if (new_iccp_name == NULL) - { - png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk"); - - return; - } - - memcpy(new_iccp_name, name, length); - new_iccp_profile = png_voidcast(png_bytep, - png_malloc_warn(png_ptr, proflen)); - - if (new_iccp_profile == NULL) - { - png_free(png_ptr, new_iccp_name); - png_benign_error(png_ptr, - "Insufficient memory to process iCCP profile"); - - return; - } - - memcpy(new_iccp_profile, profile, proflen); - - png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); - - info_ptr->iccp_proflen = proflen; - info_ptr->iccp_name = new_iccp_name; - info_ptr->iccp_profile = new_iccp_profile; - info_ptr->free_me |= PNG_FREE_ICCP; - info_ptr->valid |= PNG_INFO_iCCP; -} -#endif - -#ifdef PNG_TEXT_SUPPORTED -void PNGAPI -png_set_text(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_textp text_ptr, int num_text) -{ - int ret; - ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); - - if (ret != 0) - png_error(png_ptr, "Insufficient memory to store text"); -} - -int /* PRIVATE */ -png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_textp text_ptr, int num_text) -{ - int i; - - png_debug1(1, "in %lx storage function", png_ptr == NULL ? 0xabadca11U : - (unsigned long)png_ptr->chunk_name); - - if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL) - return(0); - - /* Make sure we have enough space in the "text" array in info_struct - * to hold all of the incoming text_ptr objects. This compare can't overflow - * because max_text >= num_text (anyway, subtract of two positive integers - * can't overflow in any case.) - */ - if (num_text > info_ptr->max_text - info_ptr->num_text) - { - int old_num_text = info_ptr->num_text; - int max_text; - png_textp new_text = NULL; - - /* Calculate an appropriate max_text, checking for overflow. */ - max_text = old_num_text; - if (num_text <= INT_MAX - max_text) - { - max_text += num_text; - - /* Round up to a multiple of 8 */ - if (max_text < INT_MAX-8) - max_text = (max_text + 8) & ~0x7; - - else - max_text = INT_MAX; - - /* Now allocate a new array and copy the old members in; this does all - * the overflow checks. - */ - new_text = png_voidcast(png_textp,png_realloc_array(png_ptr, - info_ptr->text, old_num_text, max_text-old_num_text, - sizeof *new_text)); - } - - if (new_text == NULL) - { - png_chunk_report(png_ptr, "too many text chunks", - PNG_CHUNK_WRITE_ERROR); - - return 1; - } - - png_free(png_ptr, info_ptr->text); - - info_ptr->text = new_text; - info_ptr->free_me |= PNG_FREE_TEXT; - info_ptr->max_text = max_text; - /* num_text is adjusted below as the entries are copied in */ - - png_debug1(3, "allocated %d entries for info_ptr->text", max_text); - } - - for (i = 0; i < num_text; i++) - { - size_t text_length, key_len; - size_t lang_len, lang_key_len; - png_textp textp = &(info_ptr->text[info_ptr->num_text]); - - if (text_ptr[i].key == NULL) - continue; - - if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE || - text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST) - { - png_chunk_report(png_ptr, "text compression mode is out of range", - PNG_CHUNK_WRITE_ERROR); - continue; - } - - key_len = strlen(text_ptr[i].key); - - if (text_ptr[i].compression <= 0) - { - lang_len = 0; - lang_key_len = 0; - } - - else -# ifdef PNG_iTXt_SUPPORTED - { - /* Set iTXt data */ - - if (text_ptr[i].lang != NULL) - lang_len = strlen(text_ptr[i].lang); - - else - lang_len = 0; - - if (text_ptr[i].lang_key != NULL) - lang_key_len = strlen(text_ptr[i].lang_key); - - else - lang_key_len = 0; - } -# else /* iTXt */ - { - png_chunk_report(png_ptr, "iTXt chunk not supported", - PNG_CHUNK_WRITE_ERROR); - continue; - } -# endif - - if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0') - { - text_length = 0; -# ifdef PNG_iTXt_SUPPORTED - if (text_ptr[i].compression > 0) - textp->compression = PNG_ITXT_COMPRESSION_NONE; - - else -# endif - textp->compression = PNG_TEXT_COMPRESSION_NONE; - } - - else - { - text_length = strlen(text_ptr[i].text); - textp->compression = text_ptr[i].compression; - } - - textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr, - key_len + text_length + lang_len + lang_key_len + 4)); - - if (textp->key == NULL) - { - png_chunk_report(png_ptr, "text chunk: out of memory", - PNG_CHUNK_WRITE_ERROR); - - return 1; - } - - png_debug2(2, "Allocated %lu bytes at %p in png_set_text", - (unsigned long)(png_uint_32) - (key_len + lang_len + lang_key_len + text_length + 4), - textp->key); - - memcpy(textp->key, text_ptr[i].key, key_len); - *(textp->key + key_len) = '\0'; - - if (text_ptr[i].compression > 0) - { - textp->lang = textp->key + key_len + 1; - memcpy(textp->lang, text_ptr[i].lang, lang_len); - *(textp->lang + lang_len) = '\0'; - textp->lang_key = textp->lang + lang_len + 1; - memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); - *(textp->lang_key + lang_key_len) = '\0'; - textp->text = textp->lang_key + lang_key_len + 1; - } - - else - { - textp->lang=NULL; - textp->lang_key=NULL; - textp->text = textp->key + key_len + 1; - } - - if (text_length != 0) - memcpy(textp->text, text_ptr[i].text, text_length); - - *(textp->text + text_length) = '\0'; - -# ifdef PNG_iTXt_SUPPORTED - if (textp->compression > 0) - { - textp->text_length = 0; - textp->itxt_length = text_length; - } - - else -# endif - { - textp->text_length = text_length; - textp->itxt_length = 0; - } - - info_ptr->num_text++; - png_debug1(3, "transferred text chunk %d", info_ptr->num_text); - } - - return(0); -} -#endif - -#ifdef PNG_tIME_SUPPORTED -void PNGAPI -png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr, - png_const_timep mod_time) -{ - png_debug1(1, "in %s storage function", "tIME"); - - if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL || - (png_ptr->mode & PNG_WROTE_tIME) != 0) - return; - - if (mod_time->month == 0 || mod_time->month > 12 || - mod_time->day == 0 || mod_time->day > 31 || - mod_time->hour > 23 || mod_time->minute > 59 || - mod_time->second > 60) - { - png_warning(png_ptr, "Ignoring invalid time value"); - - return; - } - - info_ptr->mod_time = *mod_time; - info_ptr->valid |= PNG_INFO_tIME; -} -#endif - -#ifdef PNG_tRNS_SUPPORTED -void PNGAPI -png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, - png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color) -{ - png_debug1(1, "in %s storage function", "tRNS"); - - if (png_ptr == NULL || info_ptr == NULL) - - return; - - if (trans_alpha != NULL) - { - /* It may not actually be necessary to set png_ptr->trans_alpha here; - * we do it for backward compatibility with the way the png_handle_tRNS - * function used to do the allocation. - * - * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively - * relies on png_set_tRNS storing the information in png_struct - * (otherwise it won't be there for the code in pngrtran.c). - */ - - png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); - - if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) - { - /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ - info_ptr->trans_alpha = png_voidcast(png_bytep, - png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); - memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans); - } - png_ptr->trans_alpha = info_ptr->trans_alpha; - } - - if (trans_color != NULL) - { -#ifdef PNG_WARNINGS_SUPPORTED - if (info_ptr->bit_depth < 16) - { - int sample_max = (1 << info_ptr->bit_depth) - 1; - - if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && - trans_color->gray > sample_max) || - (info_ptr->color_type == PNG_COLOR_TYPE_RGB && - (trans_color->red > sample_max || - trans_color->green > sample_max || - trans_color->blue > sample_max))) - png_warning(png_ptr, - "tRNS chunk has out-of-range samples for bit_depth"); - } -#endif - - info_ptr->trans_color = *trans_color; - - if (num_trans == 0) - num_trans = 1; - } - - info_ptr->num_trans = (png_uint_16)num_trans; - - if (num_trans != 0) - { - info_ptr->valid |= PNG_INFO_tRNS; - info_ptr->free_me |= PNG_FREE_TRNS; - } -} -#endif - -#ifdef PNG_sPLT_SUPPORTED -void PNGAPI -png_set_sPLT(png_const_structrp png_ptr, - png_inforp info_ptr, png_const_sPLT_tp entries, int nentries) -/* - * entries - array of png_sPLT_t structures - * to be added to the list of palettes - * in the info structure. - * - * nentries - number of palette structures to be - * added. - */ -{ - png_sPLT_tp np; - - if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL) - return; - - /* Use the internal realloc function, which checks for all the possible - * overflows. Notice that the parameters are (int) and (size_t) - */ - np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr, - info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries, - sizeof *np)); - - if (np == NULL) - { - /* Out of memory or too many chunks */ - png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR); - - return; - } - - png_free(png_ptr, info_ptr->splt_palettes); - info_ptr->splt_palettes = np; - info_ptr->free_me |= PNG_FREE_SPLT; - - np += info_ptr->splt_palettes_num; - - do - { - size_t length; - - /* Skip invalid input entries */ - if (entries->name == NULL || entries->entries == NULL) - { - /* png_handle_sPLT doesn't do this, so this is an app error */ - png_app_error(png_ptr, "png_set_sPLT: invalid sPLT"); - /* Just skip the invalid entry */ - continue; - } - - np->depth = entries->depth; - - /* In the event of out-of-memory just return - there's no point keeping - * on trying to add sPLT chunks. - */ - length = strlen(entries->name) + 1; - np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length)); - - if (np->name == NULL) - break; - - memcpy(np->name, entries->name, length); - - /* IMPORTANT: we have memory now that won't get freed if something else - * goes wrong; this code must free it. png_malloc_array produces no - * warnings; use a png_chunk_report (below) if there is an error. - */ - np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr, - entries->nentries, sizeof (png_sPLT_entry))); - - if (np->entries == NULL) - { - png_free(png_ptr, np->name); - np->name = NULL; - break; - } - - np->nentries = entries->nentries; - /* This multiply can't overflow because png_malloc_array has already - * checked it when doing the allocation. - */ - memcpy(np->entries, entries->entries, - (unsigned int)entries->nentries * sizeof (png_sPLT_entry)); - - /* Note that 'continue' skips the advance of the out pointer and out - * count, so an invalid entry is not added. - */ - info_ptr->valid |= PNG_INFO_sPLT; - ++(info_ptr->splt_palettes_num); - ++np; - ++entries; - } - while (--nentries); - - if (nentries > 0) - png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR); -} -#endif /* sPLT */ - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -static png_byte -check_location(png_const_structrp png_ptr, int location) -{ - location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT); - - /* New in 1.6.0; copy the location and check it. This is an API - * change; previously the app had to use the - * png_set_unknown_chunk_location API below for each chunk. - */ - if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0) - { - /* Write struct, so unknown chunks come from the app */ - png_app_warning(png_ptr, - "png_set_unknown_chunks now expects a valid location"); - /* Use the old behavior */ - location = (png_byte)(png_ptr->mode & - (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)); - } - - /* This need not be an internal error - if the app calls - * png_set_unknown_chunks on a read pointer it must get the location right. - */ - if (location == 0) - png_error(png_ptr, "invalid location in png_set_unknown_chunks"); - - /* Now reduce the location to the top-most set bit by removing each least - * significant bit in turn. - */ - while (location != (location & -location)) - location &= ~(location & -location); - - /* The cast is safe because 'location' is a bit mask and only the low four - * bits are significant. - */ - return (png_byte)location; -} - -void PNGAPI -png_set_unknown_chunks(png_const_structrp png_ptr, - png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) -{ - png_unknown_chunkp np; - - if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 || - unknowns == NULL) - return; - - /* Check for the failure cases where support has been disabled at compile - * time. This code is hardly ever compiled - it's here because - * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this - * code) but may be meaningless if the read or write handling of unknown - * chunks is not compiled in. - */ -# if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \ - defined(PNG_READ_SUPPORTED) - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) - { - png_app_error(png_ptr, "no unknown chunk support on read"); - - return; - } -# endif -# if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \ - defined(PNG_WRITE_SUPPORTED) - if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) - { - png_app_error(png_ptr, "no unknown chunk support on write"); - - return; - } -# endif - - /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that - * unknown critical chunks could be lost with just a warning resulting in - * undefined behavior. Now png_chunk_report is used to provide behavior - * appropriate to read or write. - */ - np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr, - info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns, - sizeof *np)); - - if (np == NULL) - { - png_chunk_report(png_ptr, "too many unknown chunks", - PNG_CHUNK_WRITE_ERROR); - - return; - } - - png_free(png_ptr, info_ptr->unknown_chunks); - info_ptr->unknown_chunks = np; /* safe because it is initialized */ - info_ptr->free_me |= PNG_FREE_UNKN; - - np += info_ptr->unknown_chunks_num; - - /* Increment unknown_chunks_num each time round the loop to protect the - * just-allocated chunk data. - */ - for (; num_unknowns > 0; --num_unknowns, ++unknowns) - { - memcpy(np->name, unknowns->name, (sizeof np->name)); - np->name[(sizeof np->name)-1] = '\0'; - np->location = check_location(png_ptr, unknowns->location); - - if (unknowns->size == 0) - { - np->data = NULL; - np->size = 0; - } - - else - { - np->data = png_voidcast(png_bytep, - png_malloc_base(png_ptr, unknowns->size)); - - if (np->data == NULL) - { - png_chunk_report(png_ptr, "unknown chunk: out of memory", - PNG_CHUNK_WRITE_ERROR); - /* But just skip storing the unknown chunk */ - continue; - } - - memcpy(np->data, unknowns->data, unknowns->size); - np->size = unknowns->size; - } - - /* These increments are skipped on out-of-memory for the data - the - * unknown chunk entry gets overwritten if the png_chunk_report returns. - * This is correct in the read case (the chunk is just dropped.) - */ - ++np; - ++(info_ptr->unknown_chunks_num); - } -} - -void PNGAPI -png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr, - int chunk, int location) -{ - /* This API is pretty pointless in 1.6.0 because the location can be set - * before the call to png_set_unknown_chunks. - * - * TODO: add a png_app_warning in 1.7 - */ - if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && - chunk < info_ptr->unknown_chunks_num) - { - if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0) - { - png_app_error(png_ptr, "invalid unknown chunk location"); - /* Fake out the pre 1.6.0 behavior: */ - if (((unsigned int)location & PNG_HAVE_IDAT) != 0) /* undocumented! */ - location = PNG_AFTER_IDAT; - - else - location = PNG_HAVE_IHDR; /* also undocumented */ - } - - info_ptr->unknown_chunks[chunk].location = - check_location(png_ptr, location); - } -} -#endif /* STORE_UNKNOWN_CHUNKS */ - -#ifdef PNG_MNG_FEATURES_SUPPORTED -png_uint_32 PNGAPI -png_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features) -{ - png_debug(1, "in png_permit_mng_features"); - - if (png_ptr == NULL) - return 0; - - png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES; - - return png_ptr->mng_features_permitted; -} -#endif - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -static unsigned int -add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep) -{ - unsigned int i; - - /* Utility function: update the 'keep' state of a chunk if it is already in - * the list, otherwise add it to the list. - */ - for (i=0; i= PNG_HANDLE_CHUNK_LAST) - { - png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep"); - - return; - } - - if (num_chunks_in <= 0) - { - png_ptr->unknown_default = keep; - - /* '0' means just set the flags, so stop here */ - if (num_chunks_in == 0) - return; - } - - if (num_chunks_in < 0) - { - /* Ignore all unknown chunks and all chunks recognized by - * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND - */ - static const png_byte chunks_to_ignore[] = { - 98, 75, 71, 68, '\0', /* bKGD */ - 99, 72, 82, 77, '\0', /* cHRM */ - 101, 88, 73, 102, '\0', /* eXIf */ - 103, 65, 77, 65, '\0', /* gAMA */ - 104, 73, 83, 84, '\0', /* hIST */ - 105, 67, 67, 80, '\0', /* iCCP */ - 105, 84, 88, 116, '\0', /* iTXt */ - 111, 70, 70, 115, '\0', /* oFFs */ - 112, 67, 65, 76, '\0', /* pCAL */ - 112, 72, 89, 115, '\0', /* pHYs */ - 115, 66, 73, 84, '\0', /* sBIT */ - 115, 67, 65, 76, '\0', /* sCAL */ - 115, 80, 76, 84, '\0', /* sPLT */ - 115, 84, 69, 82, '\0', /* sTER */ - 115, 82, 71, 66, '\0', /* sRGB */ - 116, 69, 88, 116, '\0', /* tEXt */ - 116, 73, 77, 69, '\0', /* tIME */ - 122, 84, 88, 116, '\0' /* zTXt */ - }; - - chunk_list = chunks_to_ignore; - num_chunks = (unsigned int)/*SAFE*/(sizeof chunks_to_ignore)/5U; - } - - else /* num_chunks_in > 0 */ - { - if (chunk_list == NULL) - { - /* Prior to 1.6.0 this was silently ignored, now it is an app_error - * which can be switched off. - */ - png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list"); - - return; - } - - num_chunks = (unsigned int)num_chunks_in; - } - - old_num_chunks = png_ptr->num_chunk_list; - if (png_ptr->chunk_list == NULL) - old_num_chunks = 0; - - /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow. - */ - if (num_chunks + old_num_chunks > UINT_MAX/5) - { - png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks"); - - return; - } - - /* If these chunks are being reset to the default then no more memory is - * required because add_one_chunk above doesn't extend the list if the 'keep' - * parameter is the default. - */ - if (keep != 0) - { - new_list = png_voidcast(png_bytep, png_malloc(png_ptr, - 5 * (num_chunks + old_num_chunks))); - - if (old_num_chunks > 0) - memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks); - } - - else if (old_num_chunks > 0) - new_list = png_ptr->chunk_list; - - else - new_list = NULL; - - /* Add the new chunks together with each one's handling code. If the chunk - * already exists the code is updated, otherwise the chunk is added to the - * end. (In libpng 1.6.0 order no longer matters because this code enforces - * the earlier convention that the last setting is the one that is used.) - */ - if (new_list != NULL) - { - png_const_bytep inlist; - png_bytep outlist; - unsigned int i; - - for (i=0; ichunk_list != new_list) - png_free(png_ptr, new_list); - - new_list = NULL; - } - } - - else - num_chunks = 0; - - png_ptr->num_chunk_list = num_chunks; - - if (png_ptr->chunk_list != new_list) - { - if (png_ptr->chunk_list != NULL) - png_free(png_ptr, png_ptr->chunk_list); - - png_ptr->chunk_list = new_list; - } -} -#endif - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -void PNGAPI -png_set_read_user_chunk_fn(png_structrp png_ptr, png_voidp user_chunk_ptr, - png_user_chunk_ptr read_user_chunk_fn) -{ - png_debug(1, "in png_set_read_user_chunk_fn"); - - if (png_ptr == NULL) - return; - - png_ptr->read_user_chunk_fn = read_user_chunk_fn; - png_ptr->user_chunk_ptr = user_chunk_ptr; -} -#endif - -#ifdef PNG_INFO_IMAGE_SUPPORTED -void PNGAPI -png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, - png_bytepp row_pointers) -{ - png_debug1(1, "in %s storage function", "rows"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (info_ptr->row_pointers != NULL && - (info_ptr->row_pointers != row_pointers)) - png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); - - info_ptr->row_pointers = row_pointers; - - if (row_pointers != NULL) - info_ptr->valid |= PNG_INFO_IDAT; -} -#endif - -void PNGAPI -png_set_compression_buffer_size(png_structrp png_ptr, size_t size) -{ - if (png_ptr == NULL) - return; - - if (size == 0 || size > PNG_UINT_31_MAX) - png_error(png_ptr, "invalid compression buffer size"); - -# ifdef PNG_SEQUENTIAL_READ_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) - { - png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */ - return; - } -# endif - -# ifdef PNG_WRITE_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0) - { - if (png_ptr->zowner != 0) - { - png_warning(png_ptr, - "Compression buffer size cannot be changed because it is in use"); - - return; - } - -#ifndef __COVERITY__ - /* Some compilers complain that this is always false. However, it - * can be true when integer overflow happens. - */ - if (size > ZLIB_IO_MAX) - { - png_warning(png_ptr, - "Compression buffer size limited to system maximum"); - size = ZLIB_IO_MAX; /* must fit */ - } -#endif - - if (size < 6) - { - /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH - * if this is permitted. - */ - png_warning(png_ptr, - "Compression buffer size cannot be reduced below 6"); - - return; - } - - if (png_ptr->zbuffer_size != size) - { - png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); - png_ptr->zbuffer_size = (uInt)size; - } - } -# endif -} - -void PNGAPI -png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask) -{ - if (png_ptr != NULL && info_ptr != NULL) - info_ptr->valid &= (unsigned int)(~mask); -} - - -#ifdef PNG_SET_USER_LIMITS_SUPPORTED -/* This function was added to libpng 1.2.6 */ -void PNGAPI -png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max, - png_uint_32 user_height_max) -{ - /* Images with dimensions larger than these limits will be - * rejected by png_set_IHDR(). To accept any PNG datastream - * regardless of dimensions, set both limits to 0x7fffffff. - */ - if (png_ptr == NULL) - return; - - png_ptr->user_width_max = user_width_max; - png_ptr->user_height_max = user_height_max; -} - -/* This function was added to libpng 1.4.0 */ -void PNGAPI -png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max) -{ - if (png_ptr != NULL) - png_ptr->user_chunk_cache_max = user_chunk_cache_max; -} - -/* This function was added to libpng 1.4.1 */ -void PNGAPI -png_set_chunk_malloc_max (png_structrp png_ptr, - png_alloc_size_t user_chunk_malloc_max) -{ - if (png_ptr != NULL) - png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; -} -#endif /* ?SET_USER_LIMITS */ - - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED -void PNGAPI -png_set_benign_errors(png_structrp png_ptr, int allowed) -{ - png_debug(1, "in png_set_benign_errors"); - - /* If allowed is 1, png_benign_error() is treated as a warning. - * - * If allowed is 0, png_benign_error() is treated as an error (which - * is the default behavior if png_set_benign_errors() is not called). - */ - - if (allowed != 0) - png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN | - PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN; - - else - png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN | - PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN); -} -#endif /* BENIGN_ERRORS */ - -#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED - /* Whether to report invalid palette index; added at libng-1.5.10. - * It is possible for an indexed (color-type==3) PNG file to contain - * pixels with invalid (out-of-range) indexes if the PLTE chunk has - * fewer entries than the image's bit-depth would allow. We recover - * from this gracefully by filling any incomplete palette with zeros - * (opaque black). By default, when this occurs libpng will issue - * a benign error. This API can be used to override that behavior. - */ -void PNGAPI -png_set_check_for_invalid_index(png_structrp png_ptr, int allowed) -{ - png_debug(1, "in png_set_check_for_invalid_index"); - - if (allowed > 0) - png_ptr->num_palette_max = 0; - - else - png_ptr->num_palette_max = -1; -} -#endif - -#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) || \ - defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) -/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, - * and if invalid, correct the keyword rather than discarding the entire - * chunk. The PNG 1.0 specification requires keywords 1-79 characters in - * length, forbids leading or trailing whitespace, multiple internal spaces, - * and the non-break space (0x80) from ISO 8859-1. Returns keyword length. - * - * The 'new_key' buffer must be 80 characters in size (for the keyword plus a - * trailing '\0'). If this routine returns 0 then there was no keyword, or a - * valid one could not be generated, and the caller must png_error. - */ -png_uint_32 /* PRIVATE */ -png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key) -{ -#ifdef PNG_WARNINGS_SUPPORTED - png_const_charp orig_key = key; -#endif - png_uint_32 key_len = 0; - int bad_character = 0; - int space = 1; - - png_debug(1, "in png_check_keyword"); - - if (key == NULL) - { - *new_key = 0; - return 0; - } - - while (*key && key_len < 79) - { - png_byte ch = (png_byte)*key++; - - if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/)) - { - *new_key++ = ch; ++key_len; space = 0; - } - - else if (space == 0) - { - /* A space or an invalid character when one wasn't seen immediately - * before; output just a space. - */ - *new_key++ = 32; ++key_len; space = 1; - - /* If the character was not a space then it is invalid. */ - if (ch != 32) - bad_character = ch; - } - - else if (bad_character == 0) - bad_character = ch; /* just skip it, record the first error */ - } - - if (key_len > 0 && space != 0) /* trailing space */ - { - --key_len; --new_key; - if (bad_character == 0) - bad_character = 32; - } - - /* Terminate the keyword */ - *new_key = 0; - - if (key_len == 0) - return 0; - -#ifdef PNG_WARNINGS_SUPPORTED - /* Try to only output one warning per keyword: */ - if (*key != 0) /* keyword too long */ - png_warning(png_ptr, "keyword truncated"); - - else if (bad_character != 0) - { - PNG_WARNING_PARAMETERS(p) - - png_warning_parameter(p, 1, orig_key); - png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character); - - png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'"); - } -#else /* !WARNINGS */ - PNG_UNUSED(png_ptr) -#endif /* !WARNINGS */ - - return key_len; -} -#endif /* TEXT || pCAL || iCCP || sPLT */ -#endif /* READ || WRITE */ diff --git a/extern/libpng/pngstruct.h b/extern/libpng/pngstruct.h deleted file mode 100644 index 8bdc7ce46..000000000 --- a/extern/libpng/pngstruct.h +++ /dev/null @@ -1,489 +0,0 @@ - -/* pngstruct.h - header file for PNG reference library - * - * Copyright (c) 2018-2019 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -/* The structure that holds the information to read and write PNG files. - * The only people who need to care about what is inside of this are the - * people who will be modifying the library for their own special needs. - * It should NOT be accessed directly by an application. - */ - -#ifndef PNGSTRUCT_H -#define PNGSTRUCT_H -/* zlib.h defines the structure z_stream, an instance of which is included - * in this structure and is required for decompressing the LZ compressed - * data in PNG files. - */ -#ifndef ZLIB_CONST - /* We must ensure that zlib uses 'const' in declarations. */ -# define ZLIB_CONST -#endif -#include "zlib.h" -#ifdef const - /* zlib.h sometimes #defines const to nothing, undo this. */ -# undef const -#endif - -/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility - * with older builds. - */ -#if ZLIB_VERNUM < 0x1260 -# define PNGZ_MSG_CAST(s) png_constcast(char*,s) -# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b) -#else -# define PNGZ_MSG_CAST(s) (s) -# define PNGZ_INPUT_CAST(b) (b) -#endif - -/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib - * can handle at once. This type need be no larger than 16 bits (so maximum of - * 65535), this define allows us to discover how big it is, but limited by the - * maximum for size_t. The value can be overridden in a library build - * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably - * lower value (e.g. 255 works). A lower value may help memory usage (slightly) - * and may even improve performance on some systems (and degrade it on others.) - */ -#ifndef ZLIB_IO_MAX -# define ZLIB_IO_MAX ((uInt)-1) -#endif - -#ifdef PNG_WRITE_SUPPORTED -/* The type of a compression buffer list used by the write code. */ -typedef struct png_compression_buffer -{ - struct png_compression_buffer *next; - png_byte output[1]; /* actually zbuf_size */ -} png_compression_buffer, *png_compression_bufferp; - -#define PNG_COMPRESSION_BUFFER_SIZE(pp)\ - (offsetof(png_compression_buffer, output) + (pp)->zbuffer_size) -#endif - -/* Colorspace support; structures used in png_struct, png_info and in internal - * functions to hold and communicate information about the color space. - * - * PNG_COLORSPACE_SUPPORTED is only required if the application will perform - * colorspace corrections, otherwise all the colorspace information can be - * skipped and the size of libpng can be reduced (significantly) by compiling - * out the colorspace support. - */ -#ifdef PNG_COLORSPACE_SUPPORTED -/* The chromaticities of the red, green and blue colorants and the chromaticity - * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)). - */ -typedef struct png_xy -{ - png_fixed_point redx, redy; - png_fixed_point greenx, greeny; - png_fixed_point bluex, bluey; - png_fixed_point whitex, whitey; -} png_xy; - -/* The same data as above but encoded as CIE XYZ values. When this data comes - * from chromaticities the sum of the Y values is assumed to be 1.0 - */ -typedef struct png_XYZ -{ - png_fixed_point red_X, red_Y, red_Z; - png_fixed_point green_X, green_Y, green_Z; - png_fixed_point blue_X, blue_Y, blue_Z; -} png_XYZ; -#endif /* COLORSPACE */ - -#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) -/* A colorspace is all the above plus, potentially, profile information; - * however at present libpng does not use the profile internally so it is only - * stored in the png_info struct (if iCCP is supported.) The rendering intent - * is retained here and is checked. - * - * The file gamma encoding information is also stored here and gamma correction - * is done by libpng, whereas color correction must currently be done by the - * application. - */ -typedef struct png_colorspace -{ -#ifdef PNG_GAMMA_SUPPORTED - png_fixed_point gamma; /* File gamma */ -#endif - -#ifdef PNG_COLORSPACE_SUPPORTED - png_xy end_points_xy; /* End points as chromaticities */ - png_XYZ end_points_XYZ; /* End points as CIE XYZ colorant values */ - png_uint_16 rendering_intent; /* Rendering intent of a profile */ -#endif - - /* Flags are always defined to simplify the code. */ - png_uint_16 flags; /* As defined below */ -} png_colorspace, * PNG_RESTRICT png_colorspacerp; - -typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp; - -/* General flags for the 'flags' field */ -#define PNG_COLORSPACE_HAVE_GAMMA 0x0001 -#define PNG_COLORSPACE_HAVE_ENDPOINTS 0x0002 -#define PNG_COLORSPACE_HAVE_INTENT 0x0004 -#define PNG_COLORSPACE_FROM_gAMA 0x0008 -#define PNG_COLORSPACE_FROM_cHRM 0x0010 -#define PNG_COLORSPACE_FROM_sRGB 0x0020 -#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040 -#define PNG_COLORSPACE_MATCHES_sRGB 0x0080 /* exact match on profile */ -#define PNG_COLORSPACE_INVALID 0x8000 -#define PNG_COLORSPACE_CANCEL(flags) (0xffff ^ (flags)) -#endif /* COLORSPACE || GAMMA */ - -struct png_struct_def -{ -#ifdef PNG_SETJMP_SUPPORTED - jmp_buf jmp_buf_local; /* New name in 1.6.0 for jmp_buf in png_struct */ - png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */ - jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */ - size_t jmp_buf_size; /* size of the above, if allocated */ -#endif - png_error_ptr error_fn; /* function for printing errors and aborting */ -#ifdef PNG_WARNINGS_SUPPORTED - png_error_ptr warning_fn; /* function for printing warnings */ -#endif - png_voidp error_ptr; /* user supplied struct for error functions */ - png_rw_ptr write_data_fn; /* function for writing output data */ - png_rw_ptr read_data_fn; /* function for reading input data */ - png_voidp io_ptr; /* ptr to application struct for I/O functions */ - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - png_user_transform_ptr read_user_transform_fn; /* user read transform */ -#endif - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - png_user_transform_ptr write_user_transform_fn; /* user write transform */ -#endif - -/* These were added in libpng-1.0.2 */ -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) - png_voidp user_transform_ptr; /* user supplied struct for user transform */ - png_byte user_transform_depth; /* bit depth of user transformed pixels */ - png_byte user_transform_channels; /* channels in user transformed pixels */ -#endif -#endif - - png_uint_32 mode; /* tells us where we are in the PNG file */ - png_uint_32 flags; /* flags indicating various things to libpng */ - png_uint_32 transformations; /* which transformations to perform */ - - png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */ - z_stream zstream; /* decompression structure */ - -#ifdef PNG_WRITE_SUPPORTED - png_compression_bufferp zbuffer_list; /* Created on demand during write */ - uInt zbuffer_size; /* size of the actual buffer */ - - int zlib_level; /* holds zlib compression level */ - int zlib_method; /* holds zlib compression method */ - int zlib_window_bits; /* holds zlib compression window bits */ - int zlib_mem_level; /* holds zlib compression memory level */ - int zlib_strategy; /* holds zlib compression strategy */ -#endif -/* Added at libpng 1.5.4 */ -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - int zlib_text_level; /* holds zlib compression level */ - int zlib_text_method; /* holds zlib compression method */ - int zlib_text_window_bits; /* holds zlib compression window bits */ - int zlib_text_mem_level; /* holds zlib compression memory level */ - int zlib_text_strategy; /* holds zlib compression strategy */ -#endif -/* End of material added at libpng 1.5.4 */ -/* Added at libpng 1.6.0 */ -#ifdef PNG_WRITE_SUPPORTED - int zlib_set_level; /* Actual values set into the zstream on write */ - int zlib_set_method; - int zlib_set_window_bits; - int zlib_set_mem_level; - int zlib_set_strategy; -#endif - - png_uint_32 width; /* width of image in pixels */ - png_uint_32 height; /* height of image in pixels */ - png_uint_32 num_rows; /* number of rows in current pass */ - png_uint_32 usr_width; /* width of row at start of write */ - size_t rowbytes; /* size of row in bytes */ - png_uint_32 iwidth; /* width of current interlaced row in pixels */ - png_uint_32 row_number; /* current row in interlace pass */ - png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */ - png_bytep prev_row; /* buffer to save previous (unfiltered) row. - * While reading this is a pointer into - * big_prev_row; while writing it is separately - * allocated if needed. - */ - png_bytep row_buf; /* buffer to save current (unfiltered) row. - * While reading, this is a pointer into - * big_row_buf; while writing it is separately - * allocated. - */ -#ifdef PNG_WRITE_FILTER_SUPPORTED - png_bytep try_row; /* buffer to save trial row when filtering */ - png_bytep tst_row; /* buffer to save best trial row when filtering */ -#endif - size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ - - png_uint_32 idat_size; /* current IDAT size for read */ - png_uint_32 crc; /* current chunk CRC value */ - png_colorp palette; /* palette from the input file */ - png_uint_16 num_palette; /* number of color entries in palette */ - -/* Added at libpng-1.5.10 */ -#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED - int num_palette_max; /* maximum palette index found in IDAT */ -#endif - - png_uint_16 num_trans; /* number of transparency values */ - png_byte compression; /* file compression type (always 0) */ - png_byte filter; /* file filter type (always 0) */ - png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ - png_byte pass; /* current interlace pass (0 - 6) */ - png_byte do_filter; /* row filter flags (see PNG_FILTER_ in png.h ) */ - png_byte color_type; /* color type of file */ - png_byte bit_depth; /* bit depth of file */ - png_byte usr_bit_depth; /* bit depth of users row: write only */ - png_byte pixel_depth; /* number of bits per pixel */ - png_byte channels; /* number of channels in file */ -#ifdef PNG_WRITE_SUPPORTED - png_byte usr_channels; /* channels at start of write: write only */ -#endif - png_byte sig_bytes; /* magic bytes read/written from start of file */ - png_byte maximum_pixel_depth; - /* pixel depth used for the row buffers */ - png_byte transformed_pixel_depth; - /* pixel depth after read/write transforms */ -#if ZLIB_VERNUM >= 0x1240 - png_byte zstream_start; /* at start of an input zlib stream */ -#endif /* Zlib >= 1.2.4 */ -#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) - png_uint_16 filler; /* filler bytes for pixel expansion */ -#endif - -#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) - png_byte background_gamma_type; - png_fixed_point background_gamma; - png_color_16 background; /* background color in screen gamma space */ -#ifdef PNG_READ_GAMMA_SUPPORTED - png_color_16 background_1; /* background normalized to gamma 1.0 */ -#endif -#endif /* bKGD */ - -#ifdef PNG_WRITE_FLUSH_SUPPORTED - png_flush_ptr output_flush_fn; /* Function for flushing output */ - png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ - png_uint_32 flush_rows; /* number of rows written since last flush */ -#endif - -#ifdef PNG_READ_GAMMA_SUPPORTED - int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */ - png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */ - - png_bytep gamma_table; /* gamma table for 8-bit depth files */ - png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - png_bytep gamma_from_1; /* converts from 1.0 to screen */ - png_bytep gamma_to_1; /* converts from file to 1.0 */ - png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ - png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ -#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */ -#endif - -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) - png_color_8 sig_bit; /* significant bits in each available channel */ -#endif - -#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) - png_color_8 shift; /* shift for significant bit transformation */ -#endif - -#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ - || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - png_bytep trans_alpha; /* alpha values for paletted files */ - png_color_16 trans_color; /* transparent color for non-paletted files */ -#endif - - png_read_status_ptr read_row_fn; /* called after each row is decoded */ - png_write_status_ptr write_row_fn; /* called after each row is encoded */ -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED - png_progressive_info_ptr info_fn; /* called after header data fully read */ - png_progressive_row_ptr row_fn; /* called after a prog. row is decoded */ - png_progressive_end_ptr end_fn; /* called after image is complete */ - png_bytep save_buffer_ptr; /* current location in save_buffer */ - png_bytep save_buffer; /* buffer for previously read data */ - png_bytep current_buffer_ptr; /* current location in current_buffer */ - png_bytep current_buffer; /* buffer for recently used data */ - png_uint_32 push_length; /* size of current input chunk */ - png_uint_32 skip_length; /* bytes to skip in input data */ - size_t save_buffer_size; /* amount of data now in save_buffer */ - size_t save_buffer_max; /* total size of save_buffer */ - size_t buffer_size; /* total amount of available input data */ - size_t current_buffer_size; /* amount of data now in current_buffer */ - int process_mode; /* what push library is currently doing */ - int cur_palette; /* current push library palette index */ - -#endif /* PROGRESSIVE_READ */ - -#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) -/* For the Borland special 64K segment handler */ - png_bytepp offset_table_ptr; - png_bytep offset_table; - png_uint_16 offset_table_number; - png_uint_16 offset_table_count; - png_uint_16 offset_table_count_free; -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - png_bytep palette_lookup; /* lookup table for quantizing */ - png_bytep quantize_index; /* index translation for palette files */ -#endif - -/* Options */ -#ifdef PNG_SET_OPTION_SUPPORTED - png_uint_32 options; /* On/off state (up to 16 options) */ -#endif - -#if PNG_LIBPNG_VER < 10700 -/* To do: remove this from libpng-1.7 */ -#ifdef PNG_TIME_RFC1123_SUPPORTED - char time_buffer[29]; /* String to hold RFC 1123 time text */ -#endif -#endif - -/* New members added in libpng-1.0.6 */ - - png_uint_32 free_me; /* flags items libpng is responsible for freeing */ - -#ifdef PNG_USER_CHUNKS_SUPPORTED - png_voidp user_chunk_ptr; -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ -#endif -#endif - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - int unknown_default; /* As PNG_HANDLE_* */ - unsigned int num_chunk_list; /* Number of entries in the list */ - png_bytep chunk_list; /* List of png_byte[5]; the textual chunk name - * followed by a PNG_HANDLE_* byte */ -#endif - -/* New members added in libpng-1.0.3 */ -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - png_byte rgb_to_gray_status; - /* Added in libpng 1.5.5 to record setting of coefficients: */ - png_byte rgb_to_gray_coefficients_set; - /* These were changed from png_byte in libpng-1.0.6 */ - png_uint_16 rgb_to_gray_red_coeff; - png_uint_16 rgb_to_gray_green_coeff; - /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */ -#endif - -/* New member added in libpng-1.6.36 */ -#if defined(PNG_READ_EXPAND_SUPPORTED) && \ - defined(PNG_ARM_NEON_IMPLEMENTATION) - png_bytep riffled_palette; /* buffer for accelerated palette expansion */ -#endif - -/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ -#if defined(PNG_MNG_FEATURES_SUPPORTED) -/* Changed from png_byte to png_uint_32 at version 1.2.0 */ - png_uint_32 mng_features_permitted; -#endif - -/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ -#ifdef PNG_MNG_FEATURES_SUPPORTED - png_byte filter_type; -#endif - -/* New members added in libpng-1.2.0 */ - -/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ -#ifdef PNG_USER_MEM_SUPPORTED - png_voidp mem_ptr; /* user supplied struct for mem functions */ - png_malloc_ptr malloc_fn; /* function for allocating memory */ - png_free_ptr free_fn; /* function for freeing memory */ -#endif - -/* New member added in libpng-1.0.13 and 1.2.0 */ - png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -/* The following three members were added at version 1.0.14 and 1.2.4 */ - png_bytep quantize_sort; /* working sort array */ - png_bytep index_to_palette; /* where the original index currently is - in the palette */ - png_bytep palette_to_index; /* which original index points to this - palette color */ -#endif - -/* New members added in libpng-1.0.16 and 1.2.6 */ - png_byte compression_type; - -#ifdef PNG_USER_LIMITS_SUPPORTED - png_uint_32 user_width_max; - png_uint_32 user_height_max; - - /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown - * chunks that can be stored (0 means unlimited). - */ - png_uint_32 user_chunk_cache_max; - - /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk - * can occupy when decompressed. 0 means unlimited. - */ - png_alloc_size_t user_chunk_malloc_max; -#endif - -/* New member added in libpng-1.0.25 and 1.2.17 */ -#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - /* Temporary storage for unknown chunk that the library doesn't recognize, - * used while reading the chunk. - */ - png_unknown_chunk unknown_chunk; -#endif - -/* New member added in libpng-1.2.26 */ - size_t old_big_row_buf_size; - -#ifdef PNG_READ_SUPPORTED -/* New member added in libpng-1.2.30 */ - png_bytep read_buffer; /* buffer for reading chunk data */ - png_alloc_size_t read_buffer_size; /* current size of the buffer */ -#endif -#ifdef PNG_SEQUENTIAL_READ_SUPPORTED - uInt IDAT_read_size; /* limit on read buffer size for IDAT */ -#endif - -#ifdef PNG_IO_STATE_SUPPORTED -/* New member added in libpng-1.4.0 */ - png_uint_32 io_state; -#endif - -/* New member added in libpng-1.5.6 */ - png_bytep big_prev_row; - -/* New member added in libpng-1.5.7 */ - void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info, - png_bytep row, png_const_bytep prev_row); - -#ifdef PNG_READ_SUPPORTED -#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED) - png_colorspace colorspace; -#endif -#endif -}; -#endif /* PNGSTRUCT_H */ diff --git a/extern/libpng/pngtest.c b/extern/libpng/pngtest.c deleted file mode 100644 index a715ae112..000000000 --- a/extern/libpng/pngtest.c +++ /dev/null @@ -1,2158 +0,0 @@ - -/* pngtest.c - a simple test program to test libpng - * - * Copyright (c) 2018-2019 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This program reads in a PNG image, writes it out again, and then - * compares the two files. If the files are identical, this shows that - * the basic chunk handling, filtering, and (de)compression code is working - * properly. It does not currently test all of the transforms, although - * it probably should. - * - * The program will report "FAIL" in certain legitimate cases: - * 1) when the compression level or filter selection method is changed. - * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192. - * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks - * exist in the input file. - * 4) others not listed here... - * In these cases, it is best to check with another tool such as "pngcheck" - * to see what the differences between the two files are. - * - * If a filename is given on the command-line, then this file is used - * for the input, rather than the default "pngtest.png". This allows - * testing a wide variety of files easily. You can also test a number - * of files at once by typing "pngtest -m file1.png file2.png ..." - */ - -#define _POSIX_SOURCE 1 - -#include -#include -#include - -/* Defined so I can write to a file on gui/windowing platforms */ -/* #define STDERR stderr */ -#define STDERR stdout /* For DOS */ - -#include "png.h" - -/* Known chunks that exist in pngtest.png must be supported or pngtest will fail - * simply as a result of re-ordering them. This may be fixed in 1.7 - * - * pngtest allocates a single row buffer for each row and overwrites it, - * therefore if the write side doesn't support the writing of interlaced images - * nothing can be done for an interlaced image (and the code below will fail - * horribly trying to write extra data after writing garbage). - */ -#if defined PNG_READ_SUPPORTED && /* else nothing can be done */\ - defined PNG_READ_bKGD_SUPPORTED &&\ - defined PNG_READ_cHRM_SUPPORTED &&\ - defined PNG_READ_gAMA_SUPPORTED &&\ - defined PNG_READ_oFFs_SUPPORTED &&\ - defined PNG_READ_pCAL_SUPPORTED &&\ - defined PNG_READ_pHYs_SUPPORTED &&\ - defined PNG_READ_sBIT_SUPPORTED &&\ - defined PNG_READ_sCAL_SUPPORTED &&\ - defined PNG_READ_sRGB_SUPPORTED &&\ - defined PNG_READ_sPLT_SUPPORTED &&\ - defined PNG_READ_tEXt_SUPPORTED &&\ - defined PNG_READ_tIME_SUPPORTED &&\ - defined PNG_READ_zTXt_SUPPORTED &&\ - (defined PNG_WRITE_INTERLACING_SUPPORTED || PNG_LIBPNG_VER >= 10700) - -#ifdef PNG_ZLIB_HEADER -# include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */ -#else -# include "zlib.h" -#endif - -/* Copied from pngpriv.h but only used in error messages below. */ -#ifndef PNG_ZBUF_SIZE -# define PNG_ZBUF_SIZE 8192 -#endif -#define FCLOSE(file) fclose(file) - -#ifndef PNG_STDIO_SUPPORTED -typedef FILE * png_FILE_p; -#endif - -/* Makes pngtest verbose so we can find problems. */ -#ifndef PNG_DEBUG -# define PNG_DEBUG 0 -#endif - -#if PNG_DEBUG > 1 -# define pngtest_debug(m) ((void)fprintf(stderr, m "\n")) -# define pngtest_debug1(m,p1) ((void)fprintf(stderr, m "\n", p1)) -# define pngtest_debug2(m,p1,p2) ((void)fprintf(stderr, m "\n", p1, p2)) -#else -# define pngtest_debug(m) ((void)0) -# define pngtest_debug1(m,p1) ((void)0) -# define pngtest_debug2(m,p1,p2) ((void)0) -#endif - -#if !PNG_DEBUG -# define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */ -#endif - -#ifndef PNG_UNUSED -# define PNG_UNUSED(param) (void)param; -#endif - -/* Turn on CPU timing -#define PNGTEST_TIMING -*/ - -#ifndef PNG_FLOATING_POINT_SUPPORTED -#undef PNGTEST_TIMING -#endif - -#ifdef PNGTEST_TIMING -static float t_start, t_stop, t_decode, t_encode, t_misc; -#include -#endif - -#ifdef PNG_TIME_RFC1123_SUPPORTED -#define PNG_tIME_STRING_LENGTH 29 -static int tIME_chunk_present = 0; -static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present"; - -#if PNG_LIBPNG_VER < 10619 -#define png_convert_to_rfc1123_buffer(ts, t) tIME_to_str(read_ptr, ts, t) - -static int -tIME_to_str(png_structp png_ptr, png_charp ts, png_const_timep t) -{ - png_const_charp str = png_convert_to_rfc1123(png_ptr, t); - - if (str == NULL) - return 0; - - strcpy(ts, str); - return 1; -} -#endif /* older libpng */ -#endif - -static int verbose = 0; -static int strict = 0; -static int relaxed = 0; -static int xfail = 0; -static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */ -static int error_count = 0; /* count calls to png_error */ -static int warning_count = 0; /* count calls to png_warning */ - -/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ -#ifndef png_jmpbuf -# define png_jmpbuf(png_ptr) png_ptr->jmpbuf -#endif - -/* Defines for unknown chunk handling if required. */ -#ifndef PNG_HANDLE_CHUNK_ALWAYS -# define PNG_HANDLE_CHUNK_ALWAYS 3 -#endif -#ifndef PNG_HANDLE_CHUNK_IF_SAFE -# define PNG_HANDLE_CHUNK_IF_SAFE 2 -#endif - -/* Utility to save typing/errors, the argument must be a name */ -#define MEMZERO(var) ((void)memset(&var, 0, sizeof var)) - -/* Example of using row callbacks to make a simple progress meter */ -static int status_pass = 1; -static int status_dots_requested = 0; -static int status_dots = 1; - -static void PNGCBAPI -read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) -{ - if (png_ptr == NULL || row_number > PNG_UINT_31_MAX) - return; - - if (status_pass != pass) - { - fprintf(stdout, "\n Pass %d: ", pass); - status_pass = pass; - status_dots = 31; - } - - status_dots--; - - if (status_dots == 0) - { - fprintf(stdout, "\n "); - status_dots=30; - } - - fprintf(stdout, "r"); -} - -#ifdef PNG_WRITE_SUPPORTED -static void PNGCBAPI -write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) -{ - if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) - return; - - fprintf(stdout, "w"); -} -#endif - - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -/* Example of using a user transform callback (doesn't do anything at present). - */ -static void PNGCBAPI -read_user_callback(png_structp png_ptr, png_row_infop row_info, png_bytep data) -{ - PNG_UNUSED(png_ptr) - PNG_UNUSED(row_info) - PNG_UNUSED(data) -} -#endif - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -/* Example of using user transform callback (we don't transform anything, - * but merely count the zero samples) - */ - -static png_uint_32 zero_samples; - -static void PNGCBAPI -count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) -{ - png_bytep dp = data; - if (png_ptr == NULL) - return; - - /* Contents of row_info: - * png_uint_32 width width of row - * png_uint_32 rowbytes number of bytes in row - * png_byte color_type color type of pixels - * png_byte bit_depth bit depth of samples - * png_byte channels number of channels (1-4) - * png_byte pixel_depth bits per pixel (depth*channels) - */ - - /* Counts the number of zero samples (or zero pixels if color_type is 3 */ - - if (row_info->color_type == 0 || row_info->color_type == 3) - { - int pos = 0; - png_uint_32 n, nstop; - - for (n = 0, nstop=row_info->width; nbit_depth == 1) - { - if (((*dp << pos++ ) & 0x80) == 0) - zero_samples++; - - if (pos == 8) - { - pos = 0; - dp++; - } - } - - if (row_info->bit_depth == 2) - { - if (((*dp << (pos+=2)) & 0xc0) == 0) - zero_samples++; - - if (pos == 8) - { - pos = 0; - dp++; - } - } - - if (row_info->bit_depth == 4) - { - if (((*dp << (pos+=4)) & 0xf0) == 0) - zero_samples++; - - if (pos == 8) - { - pos = 0; - dp++; - } - } - - if (row_info->bit_depth == 8) - if (*dp++ == 0) - zero_samples++; - - if (row_info->bit_depth == 16) - { - if ((*dp | *(dp+1)) == 0) - zero_samples++; - dp+=2; - } - } - } - else /* Other color types */ - { - png_uint_32 n, nstop; - int channel; - int color_channels = row_info->channels; - if (row_info->color_type > 3) - color_channels--; - - for (n = 0, nstop=row_info->width; nbit_depth == 8) - if (*dp++ == 0) - zero_samples++; - - if (row_info->bit_depth == 16) - { - if ((*dp | *(dp+1)) == 0) - zero_samples++; - - dp+=2; - } - } - if (row_info->color_type > 3) - { - dp++; - if (row_info->bit_depth == 16) - dp++; - } - } - } -} -#endif /* WRITE_USER_TRANSFORM */ - -#ifndef PNG_STDIO_SUPPORTED -/* START of code to validate stdio-free compilation */ -/* These copies of the default read/write functions come from pngrio.c and - * pngwio.c. They allow "don't include stdio" testing of the library. - * This is the function that does the actual reading of data. If you are - * not reading from a standard C stream, you should create a replacement - * read_data function and use it at run time with png_set_read_fn(), rather - * than changing the library. - */ - -#ifdef PNG_IO_STATE_SUPPORTED -void -pngtest_check_io_state(png_structp png_ptr, size_t data_length, - png_uint_32 io_op); -void -pngtest_check_io_state(png_structp png_ptr, size_t data_length, - png_uint_32 io_op) -{ - png_uint_32 io_state = png_get_io_state(png_ptr); - int err = 0; - - /* Check if the current operation (reading / writing) is as expected. */ - if ((io_state & PNG_IO_MASK_OP) != io_op) - png_error(png_ptr, "Incorrect operation in I/O state"); - - /* Check if the buffer size specific to the current location - * (file signature / header / data / crc) is as expected. - */ - switch (io_state & PNG_IO_MASK_LOC) - { - case PNG_IO_SIGNATURE: - if (data_length > 8) - err = 1; - break; - case PNG_IO_CHUNK_HDR: - if (data_length != 8) - err = 1; - break; - case PNG_IO_CHUNK_DATA: - break; /* no restrictions here */ - case PNG_IO_CHUNK_CRC: - if (data_length != 4) - err = 1; - break; - default: - err = 1; /* uninitialized */ - } - if (err != 0) - png_error(png_ptr, "Bad I/O state or buffer size"); -} -#endif - -static void PNGCBAPI -pngtest_read_data(png_structp png_ptr, png_bytep data, size_t length) -{ - size_t check = 0; - png_voidp io_ptr; - - /* fread() returns 0 on error, so it is OK to store this in a size_t - * instead of an int, which is what fread() actually returns. - */ - io_ptr = png_get_io_ptr(png_ptr); - if (io_ptr != NULL) - { - check = fread(data, 1, length, (png_FILE_p)io_ptr); - } - - if (check != length) - { - png_error(png_ptr, "Read Error"); - } - -#ifdef PNG_IO_STATE_SUPPORTED - pngtest_check_io_state(png_ptr, length, PNG_IO_READING); -#endif -} - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -static void PNGCBAPI -pngtest_flush(png_structp png_ptr) -{ - /* Do nothing; fflush() is said to be just a waste of energy. */ - PNG_UNUSED(png_ptr) /* Stifle compiler warning */ -} -#endif - -/* This is the function that does the actual writing of data. If you are - * not writing to a standard C stream, you should create a replacement - * write_data function and use it at run time with png_set_write_fn(), rather - * than changing the library. - */ -static void PNGCBAPI -pngtest_write_data(png_structp png_ptr, png_bytep data, size_t length) -{ - size_t check; - - check = fwrite(data, 1, length, (png_FILE_p)png_get_io_ptr(png_ptr)); - - if (check != length) - { - png_error(png_ptr, "Write Error"); - } - -#ifdef PNG_IO_STATE_SUPPORTED - pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING); -#endif -} -#endif /* !STDIO */ - -/* This function is called when there is a warning, but the library thinks - * it can continue anyway. Replacement functions don't have to do anything - * here if you don't want to. In the default configuration, png_ptr is - * not used, but it is passed in case it may be useful. - */ -typedef struct -{ - const char *file_name; -} pngtest_error_parameters; - -static void PNGCBAPI -pngtest_warning(png_structp png_ptr, png_const_charp message) -{ - const char *name = "UNKNOWN (ERROR!)"; - pngtest_error_parameters *test = - (pngtest_error_parameters*)png_get_error_ptr(png_ptr); - - ++warning_count; - - if (test != NULL && test->file_name != NULL) - name = test->file_name; - - fprintf(STDERR, "\n%s: libpng warning: %s\n", name, message); -} - -/* This is the default error handling function. Note that replacements for - * this function MUST NOT RETURN, or the program will likely crash. This - * function is used by default, or if the program supplies NULL for the - * error function pointer in png_set_error_fn(). - */ -static void PNGCBAPI -pngtest_error(png_structp png_ptr, png_const_charp message) -{ - ++error_count; - - pngtest_warning(png_ptr, message); - /* We can return because png_error calls the default handler, which is - * actually OK in this case. - */ -} - -/* END of code to validate stdio-free compilation */ - -/* START of code to validate memory allocation and deallocation */ -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - -/* Allocate memory. For reasonable files, size should never exceed - * 64K. However, zlib may allocate more than 64K if you don't tell - * it not to. See zconf.h and png.h for more information. zlib does - * need to allocate exactly 64K, so whatever you call here must - * have the ability to do that. - * - * This piece of code can be compiled to validate max 64K allocations - * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. - */ -typedef struct memory_information -{ - png_alloc_size_t size; - png_voidp pointer; - struct memory_information *next; -} memory_information; -typedef memory_information *memory_infop; - -static memory_infop pinformation = NULL; -static int current_allocation = 0; -static int maximum_allocation = 0; -static int total_allocation = 0; -static int num_allocations = 0; - -png_voidp PNGCBAPI png_debug_malloc PNGARG((png_structp png_ptr, - png_alloc_size_t size)); -void PNGCBAPI png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr)); - -png_voidp -PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size) -{ - - /* png_malloc has already tested for NULL; png_create_struct calls - * png_debug_malloc directly, with png_ptr == NULL which is OK - */ - - if (size == 0) - return (NULL); - - /* This calls the library allocator twice, once to get the requested - buffer and once to get a new free list entry. */ - { - /* Disable malloc_fn and free_fn */ - memory_infop pinfo; - png_set_mem_fn(png_ptr, NULL, NULL, NULL); - pinfo = (memory_infop)png_malloc(png_ptr, - (sizeof *pinfo)); - pinfo->size = size; - current_allocation += size; - total_allocation += size; - num_allocations ++; - - if (current_allocation > maximum_allocation) - maximum_allocation = current_allocation; - - pinfo->pointer = png_malloc(png_ptr, size); - /* Restore malloc_fn and free_fn */ - - png_set_mem_fn(png_ptr, - NULL, png_debug_malloc, png_debug_free); - - if (size != 0 && pinfo->pointer == NULL) - { - current_allocation -= size; - total_allocation -= size; - png_error(png_ptr, - "out of memory in pngtest->png_debug_malloc"); - } - - pinfo->next = pinformation; - pinformation = pinfo; - /* Make sure the caller isn't assuming zeroed memory. */ - memset(pinfo->pointer, 0xdd, pinfo->size); - - if (verbose != 0) - printf("png_malloc %lu bytes at %p\n", (unsigned long)size, - pinfo->pointer); - - return (png_voidp)(pinfo->pointer); - } -} - -/* Free a pointer. It is removed from the list at the same time. */ -void PNGCBAPI -png_debug_free(png_structp png_ptr, png_voidp ptr) -{ - if (png_ptr == NULL) - fprintf(STDERR, "NULL pointer to png_debug_free.\n"); - - if (ptr == 0) - { -#if 0 /* This happens all the time. */ - fprintf(STDERR, "WARNING: freeing NULL pointer\n"); -#endif - return; - } - - /* Unlink the element from the list. */ - if (pinformation != NULL) - { - memory_infop *ppinfo = &pinformation; - - for (;;) - { - memory_infop pinfo = *ppinfo; - - if (pinfo->pointer == ptr) - { - *ppinfo = pinfo->next; - current_allocation -= pinfo->size; - if (current_allocation < 0) - fprintf(STDERR, "Duplicate free of memory\n"); - /* We must free the list element too, but first kill - the memory that is to be freed. */ - memset(ptr, 0x55, pinfo->size); - free(pinfo); - pinfo = NULL; - break; - } - - if (pinfo->next == NULL) - { - fprintf(STDERR, "Pointer %p not found\n", ptr); - break; - } - - ppinfo = &pinfo->next; - } - } - - /* Finally free the data. */ - if (verbose != 0) - printf("Freeing %p\n", ptr); - - if (ptr != NULL) - free(ptr); - ptr = NULL; -} -#endif /* USER_MEM && DEBUG */ -/* END of code to test memory allocation/deallocation */ - - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED -/* Demonstration of user chunk support of the sTER and vpAg chunks */ - -/* (sTER is a public chunk not yet known by libpng. vpAg is a private -chunk used in ImageMagick to store "virtual page" size). */ - -static struct user_chunk_data -{ - png_const_infop info_ptr; - png_uint_32 vpAg_width, vpAg_height; - png_byte vpAg_units; - png_byte sTER_mode; - int location[2]; -} -user_chunk_data; - -/* Used for location and order; zero means nothing. */ -#define have_sTER 0x01 -#define have_vpAg 0x02 -#define before_PLTE 0x10 -#define before_IDAT 0x20 -#define after_IDAT 0x40 - -static void -init_callback_info(png_const_infop info_ptr) -{ - MEMZERO(user_chunk_data); - user_chunk_data.info_ptr = info_ptr; -} - -static int -set_location(png_structp png_ptr, struct user_chunk_data *data, int what) -{ - int location; - - if ((data->location[0] & what) != 0 || (data->location[1] & what) != 0) - return 0; /* already have one of these */ - - /* Find where we are (the code below zeroes info_ptr to indicate that the - * chunks before the first IDAT have been read.) - */ - if (data->info_ptr == NULL) /* after IDAT */ - location = what | after_IDAT; - - else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE) != 0) - location = what | before_IDAT; - - else - location = what | before_PLTE; - - if (data->location[0] == 0) - data->location[0] = location; - - else - data->location[1] = location; - - return 1; /* handled */ -} - -static int PNGCBAPI -read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk) -{ - struct user_chunk_data *my_user_chunk_data = - (struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr); - - if (my_user_chunk_data == NULL) - png_error(png_ptr, "lost user chunk pointer"); - - /* Return one of the following: - * return (-n); chunk had an error - * return (0); did not recognize - * return (n); success - * - * The unknown chunk structure contains the chunk data: - * png_byte name[5]; - * png_byte *data; - * size_t size; - * - * Note that libpng has already taken care of the CRC handling. - */ - - if (chunk->name[0] == 115 && chunk->name[1] == 84 && /* s T */ - chunk->name[2] == 69 && chunk->name[3] == 82) /* E R */ - { - /* Found sTER chunk */ - if (chunk->size != 1) - return (-1); /* Error return */ - - if (chunk->data[0] != 0 && chunk->data[0] != 1) - return (-1); /* Invalid mode */ - - if (set_location(png_ptr, my_user_chunk_data, have_sTER) != 0) - { - my_user_chunk_data->sTER_mode=chunk->data[0]; - return (1); - } - - else - return (0); /* duplicate sTER - give it to libpng */ - } - - if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */ - chunk->name[2] != 65 || chunk->name[3] != 103) /* A g */ - return (0); /* Did not recognize */ - - /* Found ImageMagick vpAg chunk */ - - if (chunk->size != 9) - return (-1); /* Error return */ - - if (set_location(png_ptr, my_user_chunk_data, have_vpAg) == 0) - return (0); /* duplicate vpAg */ - - my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data); - my_user_chunk_data->vpAg_height = png_get_uint_31(png_ptr, chunk->data + 4); - my_user_chunk_data->vpAg_units = chunk->data[8]; - - return (1); -} - -#ifdef PNG_WRITE_SUPPORTED -static void -write_sTER_chunk(png_structp write_ptr) -{ - png_byte sTER[5] = {115, 84, 69, 82, '\0'}; - - if (verbose != 0) - fprintf(STDERR, "\n stereo mode = %d\n", user_chunk_data.sTER_mode); - - png_write_chunk(write_ptr, sTER, &user_chunk_data.sTER_mode, 1); -} - -static void -write_vpAg_chunk(png_structp write_ptr) -{ - png_byte vpAg[5] = {118, 112, 65, 103, '\0'}; - - png_byte vpag_chunk_data[9]; - - if (verbose != 0) - fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n", - (unsigned long)user_chunk_data.vpAg_width, - (unsigned long)user_chunk_data.vpAg_height, - user_chunk_data.vpAg_units); - - png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width); - png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height); - vpag_chunk_data[8] = user_chunk_data.vpAg_units; - png_write_chunk(write_ptr, vpAg, vpag_chunk_data, 9); -} - -static void -write_chunks(png_structp write_ptr, int location) -{ - int i; - - /* Notice that this preserves the original chunk order, however chunks - * intercepted by the callback will be written *after* chunks passed to - * libpng. This will actually reverse a pair of sTER chunks or a pair of - * vpAg chunks, resulting in an error later. This is not worth worrying - * about - the chunks should not be duplicated! - */ - for (i=0; i<2; ++i) - { - if (user_chunk_data.location[i] == (location | have_sTER)) - write_sTER_chunk(write_ptr); - - else if (user_chunk_data.location[i] == (location | have_vpAg)) - write_vpAg_chunk(write_ptr); - } -} -#endif /* WRITE */ -#else /* !READ_USER_CHUNKS */ -# define write_chunks(pp,loc) ((void)0) -#endif -/* END of code to demonstrate user chunk support */ - -/* START of code to check that libpng has the required text support; this only - * checks for the write support because if read support is missing the chunk - * will simply not be reported back to pngtest. - */ -#ifdef PNG_TEXT_SUPPORTED -static void -pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr, - int num_text) -{ - while (num_text > 0) - { - switch (text_ptr[--num_text].compression) - { - case PNG_TEXT_COMPRESSION_NONE: - break; - - case PNG_TEXT_COMPRESSION_zTXt: -# ifndef PNG_WRITE_zTXt_SUPPORTED - ++unsupported_chunks; - /* In libpng 1.7 this now does an app-error, so stop it: */ - text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE; -# endif - break; - - case PNG_ITXT_COMPRESSION_NONE: - case PNG_ITXT_COMPRESSION_zTXt: -# ifndef PNG_WRITE_iTXt_SUPPORTED - ++unsupported_chunks; - text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE; -# endif - break; - - default: - /* This is an error */ - png_error(png_ptr, "invalid text chunk compression field"); - break; - } - } -} -#endif -/* END of code to check that libpng has the required text support */ - -/* Test one file */ -static int -test_one_file(const char *inname, const char *outname) -{ - static png_FILE_p fpin; - static png_FILE_p fpout; /* "static" prevents setjmp corruption */ - pngtest_error_parameters error_parameters; - png_structp read_ptr; - png_infop read_info_ptr, end_info_ptr; -#ifdef PNG_WRITE_SUPPORTED - png_structp write_ptr; - png_infop write_info_ptr; - png_infop write_end_info_ptr; -#ifdef PNG_WRITE_FILTER_SUPPORTED - int interlace_preserved = 1; -#endif /* WRITE_FILTER */ -#else /* !WRITE */ - png_structp write_ptr = NULL; - png_infop write_info_ptr = NULL; - png_infop write_end_info_ptr = NULL; -#endif /* !WRITE */ - png_bytep row_buf; - png_uint_32 y; - png_uint_32 width, height; - volatile int num_passes; - int pass; - int bit_depth, color_type; - - row_buf = NULL; - error_parameters.file_name = inname; - - if ((fpin = fopen(inname, "rb")) == NULL) - { - fprintf(STDERR, "Could not find input file %s\n", inname); - return (1); - } - - if ((fpout = fopen(outname, "wb")) == NULL) - { - fprintf(STDERR, "Could not open output file %s\n", outname); - FCLOSE(fpin); - return (1); - } - - pngtest_debug("Allocating read and write structures"); -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - read_ptr = - png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL, - NULL, NULL, NULL, png_debug_malloc, png_debug_free); -#else - read_ptr = - png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); -#endif - png_set_error_fn(read_ptr, &error_parameters, pngtest_error, - pngtest_warning); - -#ifdef PNG_WRITE_SUPPORTED -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - write_ptr = - png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL, - NULL, NULL, NULL, png_debug_malloc, png_debug_free); -#else - write_ptr = - png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); -#endif - png_set_error_fn(write_ptr, &error_parameters, pngtest_error, - pngtest_warning); -#endif - pngtest_debug("Allocating read_info, write_info and end_info structures"); - read_info_ptr = png_create_info_struct(read_ptr); - end_info_ptr = png_create_info_struct(read_ptr); -#ifdef PNG_WRITE_SUPPORTED - write_info_ptr = png_create_info_struct(write_ptr); - write_end_info_ptr = png_create_info_struct(write_ptr); -#endif - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - init_callback_info(read_info_ptr); - png_set_read_user_chunk_fn(read_ptr, &user_chunk_data, - read_user_chunk_callback); -#endif - -#ifdef PNG_SETJMP_SUPPORTED - pngtest_debug("Setting jmpbuf for read struct"); - if (setjmp(png_jmpbuf(read_ptr))) - { - fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); - png_free(read_ptr, row_buf); - row_buf = NULL; - if (verbose != 0) - fprintf(STDERR, " destroy read structs\n"); - png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); -#ifdef PNG_WRITE_SUPPORTED - if (verbose != 0) - fprintf(STDERR, " destroy write structs\n"); - png_destroy_info_struct(write_ptr, &write_end_info_ptr); - png_destroy_write_struct(&write_ptr, &write_info_ptr); -#endif - FCLOSE(fpin); - FCLOSE(fpout); - return (1); - } - -#ifdef PNG_WRITE_SUPPORTED - pngtest_debug("Setting jmpbuf for write struct"); - - if (setjmp(png_jmpbuf(write_ptr))) - { - fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); - png_free(read_ptr, row_buf); - row_buf = NULL; - if (verbose != 0) - fprintf(STDERR, " destroying read structs\n"); - png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); - if (verbose != 0) - fprintf(STDERR, " destroying write structs\n"); - png_destroy_info_struct(write_ptr, &write_end_info_ptr); - png_destroy_write_struct(&write_ptr, &write_info_ptr); - FCLOSE(fpin); - FCLOSE(fpout); - return (1); - } -#endif -#endif - -#ifdef PNG_BENIGN_ERRORS_SUPPORTED - if (strict != 0) - { - /* Treat png_benign_error() as errors on read */ - png_set_benign_errors(read_ptr, 0); - -# ifdef PNG_WRITE_SUPPORTED - /* Treat them as errors on write */ - png_set_benign_errors(write_ptr, 0); -# endif - - /* if strict is not set, then app warnings and errors are treated as - * warnings in release builds, but not in unstable builds; this can be - * changed with '--relaxed'. - */ - } - - else if (relaxed != 0) - { - /* Allow application (pngtest) errors and warnings to pass */ - png_set_benign_errors(read_ptr, 1); - - /* Turn off CRC checking while reading */ - png_set_crc_action(read_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); - -#ifdef PNG_IGNORE_ADLER32 - /* Turn off ADLER32 checking while reading */ - png_set_option(read_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON); -#endif - -# ifdef PNG_WRITE_SUPPORTED - png_set_benign_errors(write_ptr, 1); -# endif - - } -#endif /* BENIGN_ERRORS */ - - pngtest_debug("Initializing input and output streams"); -#ifdef PNG_STDIO_SUPPORTED - png_init_io(read_ptr, fpin); -# ifdef PNG_WRITE_SUPPORTED - png_init_io(write_ptr, fpout); -# endif -#else - png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data); -# ifdef PNG_WRITE_SUPPORTED - png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data, -# ifdef PNG_WRITE_FLUSH_SUPPORTED - pngtest_flush); -# else - NULL); -# endif -# endif -#endif - - if (status_dots_requested == 1) - { -#ifdef PNG_WRITE_SUPPORTED - png_set_write_status_fn(write_ptr, write_row_callback); -#endif - png_set_read_status_fn(read_ptr, read_row_callback); - } - - else - { -#ifdef PNG_WRITE_SUPPORTED - png_set_write_status_fn(write_ptr, NULL); -#endif - png_set_read_status_fn(read_ptr, NULL); - } - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - png_set_read_user_transform_fn(read_ptr, read_user_callback); -#endif -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - zero_samples = 0; - png_set_write_user_transform_fn(write_ptr, count_zero_samples); -#endif - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - /* Preserve all the unknown chunks, if possible. If this is disabled then, - * even if the png_{get,set}_unknown_chunks stuff is enabled, we can't use - * libpng to *save* the unknown chunks on read (because we can't switch the - * save option on!) - * - * Notice that if SET_UNKNOWN_CHUNKS is *not* supported read will discard all - * unknown chunks and write will write them all. - */ -#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED - png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS, - NULL, 0); -#endif -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS, - NULL, 0); -#endif -#endif - - pngtest_debug("Reading info struct"); - png_read_info(read_ptr, read_info_ptr); - -#ifdef PNG_READ_USER_CHUNKS_SUPPORTED - /* This is a bit of a hack; there is no obvious way in the callback function - * to determine that the chunks before the first IDAT have been read, so - * remove the info_ptr (which is only used to determine position relative to - * PLTE) here to indicate that we are after the IDAT. - */ - user_chunk_data.info_ptr = NULL; -#endif - - pngtest_debug("Transferring info struct"); - { - int interlace_type, compression_type, filter_type; - - if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth, - &color_type, &interlace_type, &compression_type, &filter_type) != 0) - { - png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth, - color_type, interlace_type, compression_type, filter_type); - /* num_passes may not be available below if interlace support is not - * provided by libpng for both read and write. - */ - switch (interlace_type) - { - case PNG_INTERLACE_NONE: - num_passes = 1; - break; - - case PNG_INTERLACE_ADAM7: - num_passes = 7; - break; - - default: - png_error(read_ptr, "invalid interlace type"); - /*NOT REACHED*/ - } - } - - else - png_error(read_ptr, "png_get_IHDR failed"); - } -#ifdef PNG_FIXED_POINT_SUPPORTED -#ifdef PNG_cHRM_SUPPORTED - { - png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x, - blue_y; - - if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, - &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) - { - png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x, - red_y, green_x, green_y, blue_x, blue_y); - } - } -#endif -#ifdef PNG_gAMA_SUPPORTED - { - png_fixed_point gamma; - - if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0) - png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma); - } -#endif -#else /* Use floating point versions */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -#ifdef PNG_cHRM_SUPPORTED - { - double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, - blue_y; - - if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, - &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) - { - png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x, - red_y, green_x, green_y, blue_x, blue_y); - } - } -#endif -#ifdef PNG_gAMA_SUPPORTED - { - double gamma; - - if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0) - png_set_gAMA(write_ptr, write_info_ptr, gamma); - } -#endif -#endif /* Floating point */ -#endif /* Fixed point */ -#ifdef PNG_iCCP_SUPPORTED - { - png_charp name; - png_bytep profile; - png_uint_32 proflen; - int compression_type; - - if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type, - &profile, &proflen) != 0) - { - png_set_iCCP(write_ptr, write_info_ptr, name, compression_type, - profile, proflen); - } - } -#endif -#ifdef PNG_sRGB_SUPPORTED - { - int intent; - - if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0) - png_set_sRGB(write_ptr, write_info_ptr, intent); - } -#endif - { - png_colorp palette; - int num_palette; - - if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0) - png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); - } -#ifdef PNG_bKGD_SUPPORTED - { - png_color_16p background; - - if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0) - { - png_set_bKGD(write_ptr, write_info_ptr, background); - } - } -#endif -#ifdef PNG_READ_eXIf_SUPPORTED - { - png_bytep exif=NULL; - png_uint_32 exif_length; - - if (png_get_eXIf_1(read_ptr, read_info_ptr, &exif_length, &exif) != 0) - { - if (exif_length > 1) - fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1], - (unsigned long)exif_length); -# ifdef PNG_WRITE_eXIf_SUPPORTED - png_set_eXIf_1(write_ptr, write_info_ptr, exif_length, exif); -# endif - } - } -#endif -#ifdef PNG_hIST_SUPPORTED - { - png_uint_16p hist; - - if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0) - png_set_hIST(write_ptr, write_info_ptr, hist); - } -#endif -#ifdef PNG_oFFs_SUPPORTED - { - png_int_32 offset_x, offset_y; - int unit_type; - - if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y, - &unit_type) != 0) - { - png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type); - } - } -#endif -#ifdef PNG_pCAL_SUPPORTED - { - png_charp purpose, units; - png_charpp params; - png_int_32 X0, X1; - int type, nparams; - - if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, - &nparams, &units, ¶ms) != 0) - { - png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type, - nparams, units, params); - } - } -#endif -#ifdef PNG_pHYs_SUPPORTED - { - png_uint_32 res_x, res_y; - int unit_type; - - if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, - &unit_type) != 0) - png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type); - } -#endif -#ifdef PNG_sBIT_SUPPORTED - { - png_color_8p sig_bit; - - if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0) - png_set_sBIT(write_ptr, write_info_ptr, sig_bit); - } -#endif -#ifdef PNG_sCAL_SUPPORTED -#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ - defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) - { - int unit; - double scal_width, scal_height; - - if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width, - &scal_height) != 0) - { - png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height); - } - } -#else -#ifdef PNG_FIXED_POINT_SUPPORTED - { - int unit; - png_charp scal_width, scal_height; - - if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width, - &scal_height) != 0) - { - png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, - scal_height); - } - } -#endif -#endif -#endif - -#ifdef PNG_sPLT_SUPPORTED - { - png_sPLT_tp entries; - - int num_entries = (int) png_get_sPLT(read_ptr, read_info_ptr, &entries); - if (num_entries) - { - png_set_sPLT(write_ptr, write_info_ptr, entries, num_entries); - } - } -#endif - -#ifdef PNG_TEXT_SUPPORTED - { - png_textp text_ptr; - int num_text; - - if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0) - { - pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); - - pngtest_check_text_support(read_ptr, text_ptr, num_text); - - if (verbose != 0) - { - int i; - - fprintf(STDERR,"\n"); - for (i=0; igray > sample_max) || - (color_type == PNG_COLOR_TYPE_RGB && - ((int)trans_color->red > sample_max || - (int)trans_color->green > sample_max || - (int)trans_color->blue > sample_max)))) - png_set_tRNS(write_ptr, write_info_ptr, trans_alpha, num_trans, - trans_color); - } - } -#endif -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - { - png_unknown_chunkp unknowns; - int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr, - &unknowns); - - if (num_unknowns != 0) - { - png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns, - num_unknowns); -#if PNG_LIBPNG_VER < 10600 - /* Copy the locations from the read_info_ptr. The automatically - * generated locations in write_end_info_ptr are wrong prior to 1.6.0 - * because they are reset from the write pointer (removed in 1.6.0). - */ - { - int i; - for (i = 0; i < num_unknowns; i++) - png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, - unknowns[i].location); - } -#endif - } - } -#endif - -#ifdef PNG_WRITE_SUPPORTED - pngtest_debug("Writing info struct"); - - /* Write the info in two steps so that if we write the 'unknown' chunks here - * they go to the correct place. - */ - png_write_info_before_PLTE(write_ptr, write_info_ptr); - - write_chunks(write_ptr, before_PLTE); /* before PLTE */ - - png_write_info(write_ptr, write_info_ptr); - - write_chunks(write_ptr, before_IDAT); /* after PLTE */ - - png_write_info(write_ptr, write_end_info_ptr); - - write_chunks(write_ptr, after_IDAT); /* after IDAT */ - -#ifdef PNG_COMPRESSION_COMPAT - /* Test the 'compatibility' setting here, if it is available. */ - png_set_compression(write_ptr, PNG_COMPRESSION_COMPAT); -#endif -#endif - -#ifdef SINGLE_ROWBUF_ALLOC - pngtest_debug("Allocating row buffer..."); - row_buf = (png_bytep)png_malloc(read_ptr, - png_get_rowbytes(read_ptr, read_info_ptr)); - - pngtest_debug1("\t%p", row_buf); -#endif /* SINGLE_ROWBUF_ALLOC */ - pngtest_debug("Writing row data"); - -#if defined(PNG_READ_INTERLACING_SUPPORTED) &&\ - defined(PNG_WRITE_INTERLACING_SUPPORTED) - /* Both must be defined for libpng to be able to handle the interlace, - * otherwise it gets handled below by simply reading and writing the passes - * directly. - */ - if (png_set_interlace_handling(read_ptr) != num_passes) - png_error(write_ptr, - "png_set_interlace_handling(read): wrong pass count "); - if (png_set_interlace_handling(write_ptr) != num_passes) - png_error(write_ptr, - "png_set_interlace_handling(write): wrong pass count "); -#else /* png_set_interlace_handling not called on either read or write */ -# define calc_pass_height -#endif /* not using libpng interlace handling */ - -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_misc += (t_stop - t_start); - t_start = t_stop; -#endif - for (pass = 0; pass < num_passes; pass++) - { -# ifdef calc_pass_height - png_uint_32 pass_height; - - if (num_passes == 7) /* interlaced */ - { - if (PNG_PASS_COLS(width, pass) > 0) - pass_height = PNG_PASS_ROWS(height, pass); - - else - pass_height = 0; - } - - else /* not interlaced */ - pass_height = height; -# else -# define pass_height height -# endif - - pngtest_debug1("Writing row data for pass %d", pass); - for (y = 0; y < pass_height; y++) - { -#ifndef SINGLE_ROWBUF_ALLOC - pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y); - - row_buf = (png_bytep)png_malloc(read_ptr, - png_get_rowbytes(read_ptr, read_info_ptr)); - - pngtest_debug2("\t%p (%lu bytes)", row_buf, - (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr)); - -#endif /* !SINGLE_ROWBUF_ALLOC */ - png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1); - -#ifdef PNG_WRITE_SUPPORTED -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_decode += (t_stop - t_start); - t_start = t_stop; -#endif - png_write_rows(write_ptr, (png_bytepp)&row_buf, 1); -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_encode += (t_stop - t_start); - t_start = t_stop; -#endif -#endif /* WRITE */ - -#ifndef SINGLE_ROWBUF_ALLOC - pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y); - png_free(read_ptr, row_buf); - row_buf = NULL; -#endif /* !SINGLE_ROWBUF_ALLOC */ - } - } - -#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED -# ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED - png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1); -# endif -# ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1); -# endif -#endif - - pngtest_debug("Reading and writing end_info data"); - - png_read_end(read_ptr, end_info_ptr); -#ifdef PNG_TEXT_SUPPORTED - { - png_textp text_ptr; - int num_text; - - if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0) - { - pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text); - - pngtest_check_text_support(read_ptr, text_ptr, num_text); - - if (verbose != 0) - { - int i; - - fprintf(STDERR,"\n"); - for (i=0; i 1) - fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1], - (unsigned long)exif_length); -# ifdef PNG_WRITE_eXIf_SUPPORTED - png_set_eXIf_1(write_ptr, write_end_info_ptr, exif_length, exif); -# endif - } - } -#endif -#ifdef PNG_tIME_SUPPORTED - { - png_timep mod_time; - - if (png_get_tIME(read_ptr, end_info_ptr, &mod_time) != 0) - { - png_set_tIME(write_ptr, write_end_info_ptr, mod_time); -#ifdef PNG_TIME_RFC1123_SUPPORTED - if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0) - tIME_string[(sizeof tIME_string) - 1] = '\0'; - - else - { - strncpy(tIME_string, "*** invalid time ***", sizeof tIME_string); - tIME_string[(sizeof tIME_string)-1] = '\0'; - } - - tIME_chunk_present++; -#endif /* TIME_RFC1123 */ - } - } -#endif -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - { - png_unknown_chunkp unknowns; - int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr, - &unknowns); - - if (num_unknowns != 0) - { - png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns, - num_unknowns); -#if PNG_LIBPNG_VER < 10600 - /* Copy the locations from the read_info_ptr. The automatically - * generated locations in write_end_info_ptr are wrong prior to 1.6.0 - * because they are reset from the write pointer (removed in 1.6.0). - */ - { - int i; - for (i = 0; i < num_unknowns; i++) - png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i, - unknowns[i].location); - } -#endif - } - } -#endif - -#ifdef PNG_WRITE_SUPPORTED -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - /* Normally one would use Z_DEFAULT_STRATEGY for text compression. - * This is here just to make pngtest replicate the results from libpng - * versions prior to 1.5.4, and to test this new API. - */ - png_set_text_compression_strategy(write_ptr, Z_FILTERED); -#endif - - /* When the unknown vpAg/sTER chunks are written by pngtest the only way to - * do it is to write them *before* calling png_write_end. When unknown - * chunks are written by libpng, however, they are written just before IEND. - * There seems to be no way round this, however vpAg/sTER are not expected - * after IDAT. - */ - write_chunks(write_ptr, after_IDAT); - - png_write_end(write_ptr, write_end_info_ptr); -#endif - -#ifdef PNG_EASY_ACCESS_SUPPORTED - if (verbose != 0) - { - png_uint_32 iwidth, iheight; - iwidth = png_get_image_width(write_ptr, write_info_ptr); - iheight = png_get_image_height(write_ptr, write_info_ptr); - fprintf(STDERR, "\n Image width = %lu, height = %lu\n", - (unsigned long)iwidth, (unsigned long)iheight); - } -#endif - - pngtest_debug("Destroying data structs"); -#ifdef SINGLE_ROWBUF_ALLOC - pngtest_debug("destroying row_buf for read_ptr"); - png_free(read_ptr, row_buf); - row_buf = NULL; -#endif /* SINGLE_ROWBUF_ALLOC */ - pngtest_debug("destroying read_ptr, read_info_ptr, end_info_ptr"); - png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); -#ifdef PNG_WRITE_SUPPORTED - pngtest_debug("destroying write_end_info_ptr"); - png_destroy_info_struct(write_ptr, &write_end_info_ptr); - pngtest_debug("destroying write_ptr, write_info_ptr"); - png_destroy_write_struct(&write_ptr, &write_info_ptr); -#endif - pngtest_debug("Destruction complete."); - - FCLOSE(fpin); - FCLOSE(fpout); - - /* Summarize any warnings or errors and in 'strict' mode fail the test. - * Unsupported chunks can result in warnings, in that case ignore the strict - * setting, otherwise fail the test on warnings as well as errors. - */ - if (error_count > 0) - { - /* We don't really expect to get here because of the setjmp handling - * above, but this is safe. - */ - fprintf(STDERR, "\n %s: %d libpng errors found (%d warnings)", - inname, error_count, warning_count); - - if (strict != 0) - return (1); - } - -# ifdef PNG_WRITE_SUPPORTED - /* If there is no write support nothing was written! */ - else if (unsupported_chunks > 0) - { - fprintf(STDERR, "\n %s: unsupported chunks (%d)%s", - inname, unsupported_chunks, strict ? ": IGNORED --strict!" : ""); - } -# endif - - else if (warning_count > 0) - { - fprintf(STDERR, "\n %s: %d libpng warnings found", - inname, warning_count); - - if (strict != 0) - return (1); - } - - pngtest_debug("Opening files for comparison"); - if ((fpin = fopen(inname, "rb")) == NULL) - { - fprintf(STDERR, "Could not find file %s\n", inname); - return (1); - } - - if ((fpout = fopen(outname, "rb")) == NULL) - { - fprintf(STDERR, "Could not find file %s\n", outname); - FCLOSE(fpin); - return (1); - } - -#if defined (PNG_WRITE_SUPPORTED) /* else nothing was written */ &&\ - defined (PNG_WRITE_FILTER_SUPPORTED) - if (interlace_preserved != 0) /* else the files will be changed */ - { - for (;;) - { - static int wrote_question = 0; - size_t num_in, num_out; - char inbuf[256], outbuf[256]; - - num_in = fread(inbuf, 1, sizeof inbuf, fpin); - num_out = fread(outbuf, 1, sizeof outbuf, fpout); - - if (num_in != num_out) - { - fprintf(STDERR, "\nFiles %s and %s are of a different size\n", - inname, outname); - - if (wrote_question == 0 && unsupported_chunks == 0) - { - fprintf(STDERR, - " Was %s written with the same maximum IDAT" - " chunk size (%d bytes),", - inname, PNG_ZBUF_SIZE); - fprintf(STDERR, - "\n filtering heuristic (libpng default), compression"); - fprintf(STDERR, - " level (zlib default),\n and zlib version (%s)?\n\n", - ZLIB_VERSION); - wrote_question = 1; - } - - FCLOSE(fpin); - FCLOSE(fpout); - - if (strict != 0 && unsupported_chunks == 0) - return (1); - - else - return (0); - } - - if (num_in == 0) - break; - - if (memcmp(inbuf, outbuf, num_in)) - { - fprintf(STDERR, "\nFiles %s and %s are different\n", inname, - outname); - - if (wrote_question == 0 && unsupported_chunks == 0) - { - fprintf(STDERR, - " Was %s written with the same maximum" - " IDAT chunk size (%d bytes),", - inname, PNG_ZBUF_SIZE); - fprintf(STDERR, - "\n filtering heuristic (libpng default), compression"); - fprintf(STDERR, - " level (zlib default),\n and zlib version (%s)?\n\n", - ZLIB_VERSION); - wrote_question = 1; - } - - FCLOSE(fpin); - FCLOSE(fpout); - - /* NOTE: the unsupported_chunks escape is permitted here because - * unsupported text chunk compression will result in the compression - * mode being changed (to NONE) yet, in the test case, the result - * can be exactly the same size! - */ - if (strict != 0 && unsupported_chunks == 0) - return (1); - - else - return (0); - } - } - } -#endif /* WRITE && WRITE_FILTER */ - - FCLOSE(fpin); - FCLOSE(fpout); - - return (0); -} - -/* Input and output filenames */ -#ifdef RISCOS -static const char *inname = "pngtest/png"; -static const char *outname = "pngout/png"; -#else -static const char *inname = "pngtest.png"; -static const char *outname = "pngout.png"; -#endif - -int -main(int argc, char *argv[]) -{ - int multiple = 0; - int ierror = 0; - - png_structp dummy_ptr; - - fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING); - fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION); - fprintf(STDERR, "%s", png_get_copyright(NULL)); - /* Show the version of libpng used in building the library */ - fprintf(STDERR, " library (%lu):%s", - (unsigned long)png_access_version_number(), - png_get_header_version(NULL)); - - /* Show the version of libpng used in building the application */ - fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER, - PNG_HEADER_VERSION_STRING); - - /* Do some consistency checking on the memory allocation settings, I'm - * not sure this matters, but it is nice to know, the first of these - * tests should be impossible because of the way the macros are set - * in pngconf.h - */ -#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) - fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n"); -#endif - /* I think the following can happen. */ -#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K) - fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n"); -#endif - - if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING)) - { - fprintf(STDERR, - "Warning: versions are different between png.h and png.c\n"); - fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING); - fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver); - ++ierror; - } - - if (argc > 1) - { - if (strcmp(argv[1], "-m") == 0) - { - multiple = 1; - status_dots_requested = 0; - } - - else if (strcmp(argv[1], "-mv") == 0 || - strcmp(argv[1], "-vm") == 0 ) - { - multiple = 1; - verbose = 1; - status_dots_requested = 1; - } - - else if (strcmp(argv[1], "-v") == 0) - { - verbose = 1; - status_dots_requested = 1; - inname = argv[2]; - } - - else if (strcmp(argv[1], "--strict") == 0) - { - status_dots_requested = 0; - verbose = 1; - inname = argv[2]; - strict++; - relaxed = 0; - multiple=1; - } - - else if (strcmp(argv[1], "--relaxed") == 0) - { - status_dots_requested = 0; - verbose = 1; - inname = argv[2]; - strict = 0; - relaxed++; - multiple=1; - } - else if (strcmp(argv[1], "--xfail") == 0) - { - status_dots_requested = 0; - verbose = 1; - inname = argv[2]; - strict = 0; - xfail++; - relaxed++; - multiple=1; - } - - else - { - inname = argv[1]; - status_dots_requested = 0; - } - } - - if (multiple == 0 && argc == 3 + verbose) - outname = argv[2 + verbose]; - - if ((multiple == 0 && argc > 3 + verbose) || - (multiple != 0 && argc < 2)) - { - fprintf(STDERR, - "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", - argv[0], argv[0]); - fprintf(STDERR, - " reads/writes one PNG file (without -m) or multiple files (-m)\n"); - fprintf(STDERR, - " with -m %s is used as a temporary file\n", outname); - exit(1); - } - - if (multiple != 0) - { - int i; -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - int allocation_now = current_allocation; -#endif - for (i=2; i 0 - fprintf(STDERR, "\n"); -#endif - kerror = test_one_file(argv[i], outname); - if (kerror == 0) - { -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - fprintf(STDERR, "\n PASS (%lu zero samples)\n", - (unsigned long)zero_samples); -#else - fprintf(STDERR, " PASS\n"); -#endif -#ifdef PNG_TIME_RFC1123_SUPPORTED - if (tIME_chunk_present != 0) - fprintf(STDERR, " tIME = %s\n", tIME_string); - - tIME_chunk_present = 0; -#endif /* TIME_RFC1123 */ - } - - else - { - if (xfail) - fprintf(STDERR, " XFAIL\n"); - else - { - fprintf(STDERR, " FAIL\n"); - ierror += kerror; - } - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - if (allocation_now != current_allocation) - fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", - current_allocation - allocation_now); - - if (current_allocation != 0) - { - memory_infop pinfo = pinformation; - - fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", - current_allocation); - - while (pinfo != NULL) - { - fprintf(STDERR, " %lu bytes at %p\n", - (unsigned long)pinfo->size, - pinfo->pointer); - pinfo = pinfo->next; - } - } -#endif - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - fprintf(STDERR, " Current memory allocation: %10d bytes\n", - current_allocation); - fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", - maximum_allocation); - fprintf(STDERR, " Total memory allocation: %10d bytes\n", - total_allocation); - fprintf(STDERR, " Number of allocations: %10d\n", - num_allocations); -#endif - } - - else - { - int i; - for (i = 0; i<3; ++i) - { - int kerror; -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - int allocation_now = current_allocation; -#endif - if (i == 1) - status_dots_requested = 1; - - else if (verbose == 0) - status_dots_requested = 0; - - if (i == 0 || verbose == 1 || ierror != 0) - { - fprintf(STDERR, "\n Testing %s:", inname); -#if PNG_DEBUG > 0 - fprintf(STDERR, "\n"); -#endif - } - - kerror = test_one_file(inname, outname); - - if (kerror == 0) - { - if (verbose == 1 || i == 2) - { -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - fprintf(STDERR, "\n PASS (%lu zero samples)\n", - (unsigned long)zero_samples); -#else - fprintf(STDERR, " PASS\n"); -#endif -#ifdef PNG_TIME_RFC1123_SUPPORTED - if (tIME_chunk_present != 0) - fprintf(STDERR, " tIME = %s\n", tIME_string); -#endif /* TIME_RFC1123 */ - } - } - - else - { - if (verbose == 0 && i != 2) - { - fprintf(STDERR, "\n Testing %s:", inname); -#if PNG_DEBUG > 0 - fprintf(STDERR, "\n"); -#endif - } - - if (xfail) - fprintf(STDERR, " XFAIL\n"); - else - { - fprintf(STDERR, " FAIL\n"); - ierror += kerror; - } - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - if (allocation_now != current_allocation) - fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", - current_allocation - allocation_now); - - if (current_allocation != 0) - { - memory_infop pinfo = pinformation; - - fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n", - current_allocation); - - while (pinfo != NULL) - { - fprintf(STDERR, " %lu bytes at %p\n", - (unsigned long)pinfo->size, pinfo->pointer); - pinfo = pinfo->next; - } - } -#endif - } -#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - fprintf(STDERR, " Current memory allocation: %10d bytes\n", - current_allocation); - fprintf(STDERR, " Maximum memory allocation: %10d bytes\n", - maximum_allocation); - fprintf(STDERR, " Total memory allocation: %10d bytes\n", - total_allocation); - fprintf(STDERR, " Number of allocations: %10d\n", - num_allocations); -#endif - } - -#ifdef PNGTEST_TIMING - t_stop = (float)clock(); - t_misc += (t_stop - t_start); - t_start = t_stop; - fprintf(STDERR, " CPU time used = %.3f seconds", - (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC); - fprintf(STDERR, " (decoding %.3f,\n", - t_decode/(float)CLOCKS_PER_SEC); - fprintf(STDERR, " encoding %.3f ,", - t_encode/(float)CLOCKS_PER_SEC); - fprintf(STDERR, " other %.3f seconds)\n\n", - t_misc/(float)CLOCKS_PER_SEC); -#endif - - if (ierror == 0) - fprintf(STDERR, " libpng passes test\n"); - - else - fprintf(STDERR, " libpng FAILS test\n"); - - dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - fprintf(STDERR, " Default limits:\n"); - fprintf(STDERR, " width_max = %lu\n", - (unsigned long) png_get_user_width_max(dummy_ptr)); - fprintf(STDERR, " height_max = %lu\n", - (unsigned long) png_get_user_height_max(dummy_ptr)); - if (png_get_chunk_cache_max(dummy_ptr) == 0) - fprintf(STDERR, " cache_max = unlimited\n"); - else - fprintf(STDERR, " cache_max = %lu\n", - (unsigned long) png_get_chunk_cache_max(dummy_ptr)); - if (png_get_chunk_malloc_max(dummy_ptr) == 0) - fprintf(STDERR, " malloc_max = unlimited\n"); - else - fprintf(STDERR, " malloc_max = %lu\n", - (unsigned long) png_get_chunk_malloc_max(dummy_ptr)); - png_destroy_read_struct(&dummy_ptr, NULL, NULL); - - return (int)(ierror != 0); -} -#else -int -main(void) -{ - fprintf(STDERR, - " test ignored because libpng was not built with read support\n"); - /* And skip this test */ - return PNG_LIBPNG_VER < 10600 ? 0 : 77; -} -#endif - -/* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_37 Your_png_h_is_not_version_1_6_37; diff --git a/extern/libpng/pngtrans.c b/extern/libpng/pngtrans.c deleted file mode 100644 index 1100f46eb..000000000 --- a/extern/libpng/pngtrans.c +++ /dev/null @@ -1,864 +0,0 @@ - -/* pngtrans.c - transforms the data in a row (used by both readers and writers) - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) - -#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -/* Turn on BGR-to-RGB mapping */ -void PNGAPI -png_set_bgr(png_structrp png_ptr) -{ - png_debug(1, "in png_set_bgr"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_BGR; -} -#endif - -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -/* Turn on 16-bit byte swapping */ -void PNGAPI -png_set_swap(png_structrp png_ptr) -{ - png_debug(1, "in png_set_swap"); - - if (png_ptr == NULL) - return; - - if (png_ptr->bit_depth == 16) - png_ptr->transformations |= PNG_SWAP_BYTES; -} -#endif - -#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) -/* Turn on pixel packing */ -void PNGAPI -png_set_packing(png_structrp png_ptr) -{ - png_debug(1, "in png_set_packing"); - - if (png_ptr == NULL) - return; - - if (png_ptr->bit_depth < 8) - { - png_ptr->transformations |= PNG_PACK; -# ifdef PNG_WRITE_SUPPORTED - png_ptr->usr_bit_depth = 8; -# endif - } -} -#endif - -#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) -/* Turn on packed pixel swapping */ -void PNGAPI -png_set_packswap(png_structrp png_ptr) -{ - png_debug(1, "in png_set_packswap"); - - if (png_ptr == NULL) - return; - - if (png_ptr->bit_depth < 8) - png_ptr->transformations |= PNG_PACKSWAP; -} -#endif - -#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) -void PNGAPI -png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits) -{ - png_debug(1, "in png_set_shift"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_SHIFT; - png_ptr->shift = *true_bits; -} -#endif - -#if defined(PNG_READ_INTERLACING_SUPPORTED) || \ - defined(PNG_WRITE_INTERLACING_SUPPORTED) -int PNGAPI -png_set_interlace_handling(png_structrp png_ptr) -{ - png_debug(1, "in png_set_interlace handling"); - - if (png_ptr != 0 && png_ptr->interlaced != 0) - { - png_ptr->transformations |= PNG_INTERLACE; - return (7); - } - - return (1); -} -#endif - -#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) -/* Add a filler byte on read, or remove a filler or alpha byte on write. - * The filler type has changed in v0.95 to allow future 2-byte fillers - * for 48-bit input data, as well as to avoid problems with some compilers - * that don't like bytes as parameters. - */ -void PNGAPI -png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc) -{ - png_debug(1, "in png_set_filler"); - - if (png_ptr == NULL) - return; - - /* In libpng 1.6 it is possible to determine whether this is a read or write - * operation and therefore to do more checking here for a valid call. - */ - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0) - { -# ifdef PNG_READ_FILLER_SUPPORTED - /* On read png_set_filler is always valid, regardless of the base PNG - * format, because other transformations can give a format where the - * filler code can execute (basically an 8 or 16-bit component RGB or G - * format.) - * - * NOTE: usr_channels is not used by the read code! (This has led to - * confusion in the past.) The filler is only used in the read code. - */ - png_ptr->filler = (png_uint_16)filler; -# else - png_app_error(png_ptr, "png_set_filler not supported on read"); - PNG_UNUSED(filler) /* not used in the write case */ - return; -# endif - } - - else /* write */ - { -# ifdef PNG_WRITE_FILLER_SUPPORTED - /* On write the usr_channels parameter must be set correctly at the - * start to record the number of channels in the app-supplied data. - */ - switch (png_ptr->color_type) - { - case PNG_COLOR_TYPE_RGB: - png_ptr->usr_channels = 4; - break; - - case PNG_COLOR_TYPE_GRAY: - if (png_ptr->bit_depth >= 8) - { - png_ptr->usr_channels = 2; - break; - } - - else - { - /* There simply isn't any code in libpng to strip out bits - * from bytes when the components are less than a byte in - * size! - */ - png_app_error(png_ptr, - "png_set_filler is invalid for" - " low bit depth gray output"); - return; - } - - default: - png_app_error(png_ptr, - "png_set_filler: inappropriate color type"); - return; - } -# else - png_app_error(png_ptr, "png_set_filler not supported on write"); - return; -# endif - } - - /* Here on success - libpng supports the operation, set the transformation - * and the flag to say where the filler channel is. - */ - png_ptr->transformations |= PNG_FILLER; - - if (filler_loc == PNG_FILLER_AFTER) - png_ptr->flags |= PNG_FLAG_FILLER_AFTER; - - else - png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; -} - -/* Added to libpng-1.2.7 */ -void PNGAPI -png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc) -{ - png_debug(1, "in png_set_add_alpha"); - - if (png_ptr == NULL) - return; - - png_set_filler(png_ptr, filler, filler_loc); - /* The above may fail to do anything. */ - if ((png_ptr->transformations & PNG_FILLER) != 0) - png_ptr->transformations |= PNG_ADD_ALPHA; -} - -#endif - -#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) -void PNGAPI -png_set_swap_alpha(png_structrp png_ptr) -{ - png_debug(1, "in png_set_swap_alpha"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_SWAP_ALPHA; -} -#endif - -#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ - defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) -void PNGAPI -png_set_invert_alpha(png_structrp png_ptr) -{ - png_debug(1, "in png_set_invert_alpha"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_INVERT_ALPHA; -} -#endif - -#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -void PNGAPI -png_set_invert_mono(png_structrp png_ptr) -{ - png_debug(1, "in png_set_invert_mono"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_INVERT_MONO; -} - -/* Invert monochrome grayscale data */ -void /* PRIVATE */ -png_do_invert(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_invert"); - - /* This test removed from libpng version 1.0.13 and 1.2.0: - * if (row_info->bit_depth == 1 && - */ - if (row_info->color_type == PNG_COLOR_TYPE_GRAY) - { - png_bytep rp = row; - size_t i; - size_t istop = row_info->rowbytes; - - for (i = 0; i < istop; i++) - { - *rp = (png_byte)(~(*rp)); - rp++; - } - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && - row_info->bit_depth == 8) - { - png_bytep rp = row; - size_t i; - size_t istop = row_info->rowbytes; - - for (i = 0; i < istop; i += 2) - { - *rp = (png_byte)(~(*rp)); - rp += 2; - } - } - -#ifdef PNG_16BIT_SUPPORTED - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && - row_info->bit_depth == 16) - { - png_bytep rp = row; - size_t i; - size_t istop = row_info->rowbytes; - - for (i = 0; i < istop; i += 4) - { - *rp = (png_byte)(~(*rp)); - *(rp + 1) = (png_byte)(~(*(rp + 1))); - rp += 4; - } - } -#endif -} -#endif - -#ifdef PNG_16BIT_SUPPORTED -#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -/* Swaps byte order on 16-bit depth images */ -void /* PRIVATE */ -png_do_swap(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_swap"); - - if (row_info->bit_depth == 16) - { - png_bytep rp = row; - png_uint_32 i; - png_uint_32 istop= row_info->width * row_info->channels; - - for (i = 0; i < istop; i++, rp += 2) - { -#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED - /* Feature added to libpng-1.6.11 for testing purposes, not - * enabled by default. - */ - *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp); -#else - png_byte t = *rp; - *rp = *(rp + 1); - *(rp + 1) = t; -#endif - } - } -} -#endif -#endif - -#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) -static const png_byte onebppswaptable[256] = { - 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, - 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, - 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, - 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, - 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, - 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, - 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, - 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, - 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, - 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, - 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, - 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, - 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, - 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, - 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, - 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, - 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, - 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, - 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, - 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, - 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, - 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, - 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, - 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, - 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, - 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, - 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, - 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, - 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, - 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, - 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, - 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF -}; - -static const png_byte twobppswaptable[256] = { - 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, - 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0, - 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4, - 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4, - 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8, - 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8, - 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC, - 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC, - 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1, - 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1, - 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5, - 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5, - 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9, - 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9, - 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD, - 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD, - 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2, - 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2, - 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6, - 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6, - 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA, - 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA, - 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE, - 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE, - 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3, - 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3, - 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7, - 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7, - 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB, - 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB, - 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF, - 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF -}; - -static const png_byte fourbppswaptable[256] = { - 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, - 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, - 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, - 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1, - 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, - 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2, - 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, - 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3, - 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, - 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4, - 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, - 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5, - 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, - 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6, - 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, - 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, - 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, - 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, - 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, - 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, - 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A, - 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA, - 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, - 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB, - 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, - 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, - 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D, - 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, - 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, - 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, - 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, - 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF -}; - -/* Swaps pixel packing order within bytes */ -void /* PRIVATE */ -png_do_packswap(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_packswap"); - - if (row_info->bit_depth < 8) - { - png_bytep rp; - png_const_bytep end, table; - - end = row + row_info->rowbytes; - - if (row_info->bit_depth == 1) - table = onebppswaptable; - - else if (row_info->bit_depth == 2) - table = twobppswaptable; - - else if (row_info->bit_depth == 4) - table = fourbppswaptable; - - else - return; - - for (rp = row; rp < end; rp++) - *rp = table[*rp]; - } -} -#endif /* PACKSWAP || WRITE_PACKSWAP */ - -#if defined(PNG_WRITE_FILLER_SUPPORTED) || \ - defined(PNG_READ_STRIP_ALPHA_SUPPORTED) -/* Remove a channel - this used to be 'png_do_strip_filler' but it used a - * somewhat weird combination of flags to determine what to do. All the calls - * to png_do_strip_filler are changed in 1.5.2 to call this instead with the - * correct arguments. - * - * The routine isn't general - the channel must be the channel at the start or - * end (not in the middle) of each pixel. - */ -void /* PRIVATE */ -png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) -{ - png_bytep sp = row; /* source pointer */ - png_bytep dp = row; /* destination pointer */ - png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */ - - /* At the start sp will point to the first byte to copy and dp to where - * it is copied to. ep always points just beyond the end of the row, so - * the loop simply copies (channels-1) channels until sp reaches ep. - * - * at_start: 0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc. - * nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc. - */ - - /* GA, GX, XG cases */ - if (row_info->channels == 2) - { - if (row_info->bit_depth == 8) - { - if (at_start != 0) /* Skip initial filler */ - ++sp; - else /* Skip initial channel and, for sp, the filler */ - { - sp += 2; ++dp; - } - - /* For a 1 pixel wide image there is nothing to do */ - while (sp < ep) - { - *dp++ = *sp; sp += 2; - } - - row_info->pixel_depth = 8; - } - - else if (row_info->bit_depth == 16) - { - if (at_start != 0) /* Skip initial filler */ - sp += 2; - else /* Skip initial channel and, for sp, the filler */ - { - sp += 4; dp += 2; - } - - while (sp < ep) - { - *dp++ = *sp++; *dp++ = *sp; sp += 3; - } - - row_info->pixel_depth = 16; - } - - else - return; /* bad bit depth */ - - row_info->channels = 1; - - /* Finally fix the color type if it records an alpha channel */ - if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - row_info->color_type = PNG_COLOR_TYPE_GRAY; - } - - /* RGBA, RGBX, XRGB cases */ - else if (row_info->channels == 4) - { - if (row_info->bit_depth == 8) - { - if (at_start != 0) /* Skip initial filler */ - ++sp; - else /* Skip initial channels and, for sp, the filler */ - { - sp += 4; dp += 3; - } - - /* Note that the loop adds 3 to dp and 4 to sp each time. */ - while (sp < ep) - { - *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2; - } - - row_info->pixel_depth = 24; - } - - else if (row_info->bit_depth == 16) - { - if (at_start != 0) /* Skip initial filler */ - sp += 2; - else /* Skip initial channels and, for sp, the filler */ - { - sp += 8; dp += 6; - } - - while (sp < ep) - { - /* Copy 6 bytes, skip 2 */ - *dp++ = *sp++; *dp++ = *sp++; - *dp++ = *sp++; *dp++ = *sp++; - *dp++ = *sp++; *dp++ = *sp; sp += 3; - } - - row_info->pixel_depth = 48; - } - - else - return; /* bad bit depth */ - - row_info->channels = 3; - - /* Finally fix the color type if it records an alpha channel */ - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - row_info->color_type = PNG_COLOR_TYPE_RGB; - } - - else - return; /* The filler channel has gone already */ - - /* Fix the rowbytes value. */ - row_info->rowbytes = (size_t)(dp-row); -} -#endif - -#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -/* Swaps red and blue bytes within a pixel */ -void /* PRIVATE */ -png_do_bgr(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_bgr"); - - if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_uint_32 row_width = row_info->width; - if (row_info->bit_depth == 8) - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - { - png_bytep rp; - png_uint_32 i; - - for (i = 0, rp = row; i < row_width; i++, rp += 3) - { - png_byte save = *rp; - *rp = *(rp + 2); - *(rp + 2) = save; - } - } - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - png_bytep rp; - png_uint_32 i; - - for (i = 0, rp = row; i < row_width; i++, rp += 4) - { - png_byte save = *rp; - *rp = *(rp + 2); - *(rp + 2) = save; - } - } - } - -#ifdef PNG_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - { - png_bytep rp; - png_uint_32 i; - - for (i = 0, rp = row; i < row_width; i++, rp += 6) - { - png_byte save = *rp; - *rp = *(rp + 4); - *(rp + 4) = save; - save = *(rp + 1); - *(rp + 1) = *(rp + 5); - *(rp + 5) = save; - } - } - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - png_bytep rp; - png_uint_32 i; - - for (i = 0, rp = row; i < row_width; i++, rp += 8) - { - png_byte save = *rp; - *rp = *(rp + 4); - *(rp + 4) = save; - save = *(rp + 1); - *(rp + 1) = *(rp + 5); - *(rp + 5) = save; - } - } - } -#endif - } -} -#endif /* READ_BGR || WRITE_BGR */ - -#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \ - defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED) -/* Added at libpng-1.5.10 */ -void /* PRIVATE */ -png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) -{ - if (png_ptr->num_palette < (1 << row_info->bit_depth) && - png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */ - { - /* Calculations moved outside switch in an attempt to stop different - * compiler warnings. 'padding' is in *bits* within the last byte, it is - * an 'int' because pixel_depth becomes an 'int' in the expression below, - * and this calculation is used because it avoids warnings that other - * forms produced on either GCC or MSVC. - */ - int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width); - png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1; - - switch (row_info->bit_depth) - { - case 1: - { - /* in this case, all bytes must be 0 so we don't need - * to unpack the pixels except for the rightmost one. - */ - for (; rp > png_ptr->row_buf; rp--) - { - if ((*rp >> padding) != 0) - png_ptr->num_palette_max = 1; - padding = 0; - } - - break; - } - - case 2: - { - for (; rp > png_ptr->row_buf; rp--) - { - int i = ((*rp >> padding) & 0x03); - - if (i > png_ptr->num_palette_max) - png_ptr->num_palette_max = i; - - i = (((*rp >> padding) >> 2) & 0x03); - - if (i > png_ptr->num_palette_max) - png_ptr->num_palette_max = i; - - i = (((*rp >> padding) >> 4) & 0x03); - - if (i > png_ptr->num_palette_max) - png_ptr->num_palette_max = i; - - i = (((*rp >> padding) >> 6) & 0x03); - - if (i > png_ptr->num_palette_max) - png_ptr->num_palette_max = i; - - padding = 0; - } - - break; - } - - case 4: - { - for (; rp > png_ptr->row_buf; rp--) - { - int i = ((*rp >> padding) & 0x0f); - - if (i > png_ptr->num_palette_max) - png_ptr->num_palette_max = i; - - i = (((*rp >> padding) >> 4) & 0x0f); - - if (i > png_ptr->num_palette_max) - png_ptr->num_palette_max = i; - - padding = 0; - } - - break; - } - - case 8: - { - for (; rp > png_ptr->row_buf; rp--) - { - if (*rp > png_ptr->num_palette_max) - png_ptr->num_palette_max = (int) *rp; - } - - break; - } - - default: - break; - } - } -} -#endif /* CHECK_FOR_INVALID_INDEX */ - -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -void PNGAPI -png_set_user_transform_info(png_structrp png_ptr, png_voidp - user_transform_ptr, int user_transform_depth, int user_transform_channels) -{ - png_debug(1, "in png_set_user_transform_info"); - - if (png_ptr == NULL) - return; - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 && - (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0) - { - png_app_error(png_ptr, - "info change after png_start_read_image or png_read_update_info"); - return; - } -#endif - - png_ptr->user_transform_ptr = user_transform_ptr; - png_ptr->user_transform_depth = (png_byte)user_transform_depth; - png_ptr->user_transform_channels = (png_byte)user_transform_channels; -} -#endif - -/* This function returns a pointer to the user_transform_ptr associated with - * the user transform functions. The application should free any memory - * associated with this pointer before png_write_destroy and png_read_destroy - * are called. - */ -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -png_voidp PNGAPI -png_get_user_transform_ptr(png_const_structrp png_ptr) -{ - if (png_ptr == NULL) - return (NULL); - - return png_ptr->user_transform_ptr; -} -#endif - -#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED -png_uint_32 PNGAPI -png_get_current_row_number(png_const_structrp png_ptr) -{ - /* See the comments in png.h - this is the sub-image row when reading an - * interlaced image. - */ - if (png_ptr != NULL) - return png_ptr->row_number; - - return PNG_UINT_32_MAX; /* help the app not to fail silently */ -} - -png_byte PNGAPI -png_get_current_pass_number(png_const_structrp png_ptr) -{ - if (png_ptr != NULL) - return png_ptr->pass; - return 8; /* invalid */ -} -#endif /* USER_TRANSFORM_INFO */ -#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */ -#endif /* READ || WRITE */ diff --git a/extern/libpng/pngwio.c b/extern/libpng/pngwio.c deleted file mode 100644 index 10e919dd0..000000000 --- a/extern/libpng/pngwio.c +++ /dev/null @@ -1,168 +0,0 @@ - -/* pngwio.c - functions for data output - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2014,2016,2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - * - * This file provides a location for all output. Users who need - * special handling are expected to write functions that have the same - * arguments as these and perform similar functions, but that possibly - * use different output methods. Note that you shouldn't change these - * functions, but rather write replacement functions and then change - * them at run time with png_set_write_fn(...). - */ - -#include "pngpriv.h" - -#ifdef PNG_WRITE_SUPPORTED - -/* Write the data to whatever output you are using. The default routine - * writes to a file pointer. Note that this routine sometimes gets called - * with very small lengths, so you should implement some kind of simple - * buffering if you are using unbuffered writes. This should never be asked - * to write more than 64K on a 16-bit machine. - */ - -void /* PRIVATE */ -png_write_data(png_structrp png_ptr, png_const_bytep data, size_t length) -{ - /* NOTE: write_data_fn must not change the buffer! */ - if (png_ptr->write_data_fn != NULL ) - (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data), - length); - - else - png_error(png_ptr, "Call to NULL write function"); -} - -#ifdef PNG_STDIO_SUPPORTED -/* This is the function that does the actual writing of data. If you are - * not writing to a standard C stream, you should create a replacement - * write_data function and use it at run time with png_set_write_fn(), rather - * than changing the library. - */ -void PNGCBAPI -png_default_write_data(png_structp png_ptr, png_bytep data, size_t length) -{ - size_t check; - - if (png_ptr == NULL) - return; - - check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr)); - - if (check != length) - png_error(png_ptr, "Write Error"); -} -#endif - -/* This function is called to output any data pending writing (normally - * to disk). After png_flush is called, there should be no data pending - * writing in any buffers. - */ -#ifdef PNG_WRITE_FLUSH_SUPPORTED -void /* PRIVATE */ -png_flush(png_structrp png_ptr) -{ - if (png_ptr->output_flush_fn != NULL) - (*(png_ptr->output_flush_fn))(png_ptr); -} - -# ifdef PNG_STDIO_SUPPORTED -void PNGCBAPI -png_default_flush(png_structp png_ptr) -{ - png_FILE_p io_ptr; - - if (png_ptr == NULL) - return; - - io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr)); - fflush(io_ptr); -} -# endif -#endif - -/* This function allows the application to supply new output functions for - * libpng if standard C streams aren't being used. - * - * This function takes as its arguments: - * png_ptr - pointer to a png output data structure - * io_ptr - pointer to user supplied structure containing info about - * the output functions. May be NULL. - * write_data_fn - pointer to a new output function that takes as its - * arguments a pointer to a png_struct, a pointer to - * data to be written, and a 32-bit unsigned int that is - * the number of bytes to be written. The new write - * function should call png_error(png_ptr, "Error msg") - * to exit and output any fatal error messages. May be - * NULL, in which case libpng's default function will - * be used. - * flush_data_fn - pointer to a new flush function that takes as its - * arguments a pointer to a png_struct. After a call to - * the flush function, there should be no data in any buffers - * or pending transmission. If the output method doesn't do - * any buffering of output, a function prototype must still be - * supplied although it doesn't have to do anything. If - * PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile - * time, output_flush_fn will be ignored, although it must be - * supplied for compatibility. May be NULL, in which case - * libpng's default function will be used, if - * PNG_WRITE_FLUSH_SUPPORTED is defined. This is not - * a good idea if io_ptr does not point to a standard - * *FILE structure. - */ -void PNGAPI -png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr, - png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->io_ptr = io_ptr; - -#ifdef PNG_STDIO_SUPPORTED - if (write_data_fn != NULL) - png_ptr->write_data_fn = write_data_fn; - - else - png_ptr->write_data_fn = png_default_write_data; -#else - png_ptr->write_data_fn = write_data_fn; -#endif - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -# ifdef PNG_STDIO_SUPPORTED - - if (output_flush_fn != NULL) - png_ptr->output_flush_fn = output_flush_fn; - - else - png_ptr->output_flush_fn = png_default_flush; - -# else - png_ptr->output_flush_fn = output_flush_fn; -# endif -#else - PNG_UNUSED(output_flush_fn) -#endif /* WRITE_FLUSH */ - -#ifdef PNG_READ_SUPPORTED - /* It is an error to read while writing a png file */ - if (png_ptr->read_data_fn != NULL) - { - png_ptr->read_data_fn = NULL; - - png_warning(png_ptr, - "Can't set both read_data_fn and write_data_fn in the" - " same structure"); - } -#endif -} -#endif /* WRITE */ diff --git a/extern/libpng/pngwrite.c b/extern/libpng/pngwrite.c deleted file mode 100644 index 59377a4dd..000000000 --- a/extern/libpng/pngwrite.c +++ /dev/null @@ -1,2395 +0,0 @@ - -/* pngwrite.c - general routines to write a PNG file - * - * Copyright (c) 2018-2019 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" -#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED -# include -#endif /* SIMPLIFIED_WRITE_STDIO */ - -#ifdef PNG_WRITE_SUPPORTED - -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -/* Write out all the unknown chunks for the current given location */ -static void -write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr, - unsigned int where) -{ - if (info_ptr->unknown_chunks_num != 0) - { - png_const_unknown_chunkp up; - - png_debug(5, "writing extra chunks"); - - for (up = info_ptr->unknown_chunks; - up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; - ++up) - if ((up->location & where) != 0) - { - /* If per-chunk unknown chunk handling is enabled use it, otherwise - * just write the chunks the application has set. - */ -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - int keep = png_handle_as_unknown(png_ptr, up->name); - - /* NOTE: this code is radically different from the read side in the - * matter of handling an ancillary unknown chunk. In the read side - * the default behavior is to discard it, in the code below the default - * behavior is to write it. Critical chunks are, however, only - * written if explicitly listed or if the default is set to write all - * unknown chunks. - * - * The default handling is also slightly weird - it is not possible to - * stop the writing of all unsafe-to-copy chunks! - * - * TODO: REVIEW: this would seem to be a bug. - */ - if (keep != PNG_HANDLE_CHUNK_NEVER && - ((up->name[3] & 0x20) /* safe-to-copy overrides everything */ || - keep == PNG_HANDLE_CHUNK_ALWAYS || - (keep == PNG_HANDLE_CHUNK_AS_DEFAULT && - png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS))) -#endif - { - /* TODO: review, what is wrong with a zero length unknown chunk? */ - if (up->size == 0) - png_warning(png_ptr, "Writing zero-length unknown chunk"); - - png_write_chunk(png_ptr, up->name, up->data, up->size); - } - } - } -} -#endif /* WRITE_UNKNOWN_CHUNKS */ - -/* Writes all the PNG information. This is the suggested way to use the - * library. If you have a new chunk to add, make a function to write it, - * and put it in the correct location here. If you want the chunk written - * after the image data, put it in png_write_end(). I strongly encourage - * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing - * the chunk, as that will keep the code from breaking if you want to just - * write a plain PNG file. If you have long comments, I suggest writing - * them in png_write_end(), and compressing them. - */ -void PNGAPI -png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr) -{ - png_debug(1, "in png_write_info_before_PLTE"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0) - { - /* Write PNG signature */ - png_write_sig(png_ptr); - -#ifdef PNG_MNG_FEATURES_SUPPORTED - if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && \ - png_ptr->mng_features_permitted != 0) - { - png_warning(png_ptr, - "MNG features are not allowed in a PNG datastream"); - png_ptr->mng_features_permitted = 0; - } -#endif - - /* Write IHDR information. */ - png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, - info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, - info_ptr->filter_type, -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - info_ptr->interlace_type -#else - 0 -#endif - ); - - /* The rest of these check to see if the valid field has the appropriate - * flag set, and if it does, writes the chunk. - * - * 1.6.0: COLORSPACE support controls the writing of these chunks too, and - * the chunks will be written if the WRITE routine is there and - * information * is available in the COLORSPACE. (See - * png_colorspace_sync_info in png.c for where the valid flags get set.) - * - * Under certain circumstances the colorspace can be invalidated without - * syncing the info_struct 'valid' flags; this happens if libpng detects - * an error and calls png_error while the color space is being set, yet - * the application continues writing the PNG. So check the 'invalid' - * flag here too. - */ -#ifdef PNG_GAMMA_SUPPORTED -# ifdef PNG_WRITE_gAMA_SUPPORTED - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) != 0 && - (info_ptr->valid & PNG_INFO_gAMA) != 0) - png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma); -# endif -#endif - -#ifdef PNG_COLORSPACE_SUPPORTED - /* Write only one of sRGB or an ICC profile. If a profile was supplied - * and it matches one of the known sRGB ones issue a warning. - */ -# ifdef PNG_WRITE_iCCP_SUPPORTED - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->valid & PNG_INFO_iCCP) != 0) - { -# ifdef PNG_WRITE_sRGB_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sRGB) != 0) - png_app_warning(png_ptr, - "profile matches sRGB but writing iCCP instead"); -# endif - - png_write_iCCP(png_ptr, info_ptr->iccp_name, - info_ptr->iccp_profile); - } -# ifdef PNG_WRITE_sRGB_SUPPORTED - else -# endif -# endif - -# ifdef PNG_WRITE_sRGB_SUPPORTED - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->valid & PNG_INFO_sRGB) != 0) - png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent); -# endif /* WRITE_sRGB */ -#endif /* COLORSPACE */ - -#ifdef PNG_WRITE_sBIT_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sBIT) != 0) - png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); -#endif - -#ifdef PNG_COLORSPACE_SUPPORTED -# ifdef PNG_WRITE_cHRM_SUPPORTED - if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 && - (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0 && - (info_ptr->valid & PNG_INFO_cHRM) != 0) - png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy); -# endif -#endif - -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR); -#endif - - png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; - } -} - -void PNGAPI -png_write_info(png_structrp png_ptr, png_const_inforp info_ptr) -{ -#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) - int i; -#endif - - png_debug(1, "in png_write_info"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - png_write_info_before_PLTE(png_ptr, info_ptr); - - if ((info_ptr->valid & PNG_INFO_PLTE) != 0) - png_write_PLTE(png_ptr, info_ptr->palette, - (png_uint_32)info_ptr->num_palette); - - else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - png_error(png_ptr, "Valid palette required for paletted images"); - -#ifdef PNG_WRITE_tRNS_SUPPORTED - if ((info_ptr->valid & PNG_INFO_tRNS) !=0) - { -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - /* Invert the alpha channel (in tRNS) */ - if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0 && - info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - int j, jend; - - jend = info_ptr->num_trans; - if (jend > PNG_MAX_PALETTE_LENGTH) - jend = PNG_MAX_PALETTE_LENGTH; - - for (j = 0; jtrans_alpha[j] = - (png_byte)(255 - info_ptr->trans_alpha[j]); - } -#endif - png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color), - info_ptr->num_trans, info_ptr->color_type); - } -#endif -#ifdef PNG_WRITE_bKGD_SUPPORTED - if ((info_ptr->valid & PNG_INFO_bKGD) != 0) - png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); -#endif - -#ifdef PNG_WRITE_eXIf_SUPPORTED - if ((info_ptr->valid & PNG_INFO_eXIf) != 0) - png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif); -#endif - -#ifdef PNG_WRITE_hIST_SUPPORTED - if ((info_ptr->valid & PNG_INFO_hIST) != 0) - png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); -#endif - -#ifdef PNG_WRITE_oFFs_SUPPORTED - if ((info_ptr->valid & PNG_INFO_oFFs) != 0) - png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, - info_ptr->offset_unit_type); -#endif - -#ifdef PNG_WRITE_pCAL_SUPPORTED - if ((info_ptr->valid & PNG_INFO_pCAL) != 0) - png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, - info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, - info_ptr->pcal_units, info_ptr->pcal_params); -#endif - -#ifdef PNG_WRITE_sCAL_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sCAL) != 0) - png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, - info_ptr->scal_s_width, info_ptr->scal_s_height); -#endif /* sCAL */ - -#ifdef PNG_WRITE_pHYs_SUPPORTED - if ((info_ptr->valid & PNG_INFO_pHYs) != 0) - png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, - info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); -#endif /* pHYs */ - -#ifdef PNG_WRITE_tIME_SUPPORTED - if ((info_ptr->valid & PNG_INFO_tIME) != 0) - { - png_write_tIME(png_ptr, &(info_ptr->mod_time)); - png_ptr->mode |= PNG_WROTE_tIME; - } -#endif /* tIME */ - -#ifdef PNG_WRITE_sPLT_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sPLT) != 0) - for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) - png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); -#endif /* sPLT */ - -#ifdef PNG_WRITE_TEXT_SUPPORTED - /* Check to see if we need to write text chunks */ - for (i = 0; i < info_ptr->num_text; i++) - { - png_debug2(2, "Writing header text chunk %d, type %d", i, - info_ptr->text[i].compression); - /* An internationalized chunk? */ - if (info_ptr->text[i].compression > 0) - { -#ifdef PNG_WRITE_iTXt_SUPPORTED - /* Write international chunk */ - png_write_iTXt(png_ptr, - info_ptr->text[i].compression, - info_ptr->text[i].key, - info_ptr->text[i].lang, - info_ptr->text[i].lang_key, - info_ptr->text[i].text); - /* Mark this chunk as written */ - if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; - else - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; -#else - png_warning(png_ptr, "Unable to write international text"); -#endif - } - - /* If we want a compressed text chunk */ - else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt) - { -#ifdef PNG_WRITE_zTXt_SUPPORTED - /* Write compressed chunk */ - png_write_zTXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, info_ptr->text[i].compression); - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; -#else - png_warning(png_ptr, "Unable to write compressed text"); -#endif - } - - else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) - { -#ifdef PNG_WRITE_tEXt_SUPPORTED - /* Write uncompressed chunk */ - png_write_tEXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, - 0); - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; -#else - /* Can't get here */ - png_warning(png_ptr, "Unable to write uncompressed text"); -#endif - } - } -#endif /* tEXt */ - -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_PLTE); -#endif -} - -/* Writes the end of the PNG file. If you don't want to write comments or - * time information, you can pass NULL for info. If you already wrote these - * in png_write_info(), do not write them again here. If you have long - * comments, I suggest writing them here, and compressing them. - */ -void PNGAPI -png_write_end(png_structrp png_ptr, png_inforp info_ptr) -{ - png_debug(1, "in png_write_end"); - - if (png_ptr == NULL) - return; - - if ((png_ptr->mode & PNG_HAVE_IDAT) == 0) - png_error(png_ptr, "No IDATs written into file"); - -#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED - if (png_ptr->num_palette_max > png_ptr->num_palette) - png_benign_error(png_ptr, "Wrote palette index exceeding num_palette"); -#endif - - /* See if user wants us to write information chunks */ - if (info_ptr != NULL) - { -#ifdef PNG_WRITE_TEXT_SUPPORTED - int i; /* local index variable */ -#endif -#ifdef PNG_WRITE_tIME_SUPPORTED - /* Check to see if user has supplied a time chunk */ - if ((info_ptr->valid & PNG_INFO_tIME) != 0 && - (png_ptr->mode & PNG_WROTE_tIME) == 0) - png_write_tIME(png_ptr, &(info_ptr->mod_time)); - -#endif -#ifdef PNG_WRITE_TEXT_SUPPORTED - /* Loop through comment chunks */ - for (i = 0; i < info_ptr->num_text; i++) - { - png_debug2(2, "Writing trailer text chunk %d, type %d", i, - info_ptr->text[i].compression); - /* An internationalized chunk? */ - if (info_ptr->text[i].compression > 0) - { -#ifdef PNG_WRITE_iTXt_SUPPORTED - /* Write international chunk */ - png_write_iTXt(png_ptr, - info_ptr->text[i].compression, - info_ptr->text[i].key, - info_ptr->text[i].lang, - info_ptr->text[i].lang_key, - info_ptr->text[i].text); - /* Mark this chunk as written */ - if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; - else - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; -#else - png_warning(png_ptr, "Unable to write international text"); -#endif - } - - else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) - { -#ifdef PNG_WRITE_zTXt_SUPPORTED - /* Write compressed chunk */ - png_write_zTXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, info_ptr->text[i].compression); - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; -#else - png_warning(png_ptr, "Unable to write compressed text"); -#endif - } - - else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) - { -#ifdef PNG_WRITE_tEXt_SUPPORTED - /* Write uncompressed chunk */ - png_write_tEXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, 0); - /* Mark this chunk as written */ - info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; -#else - png_warning(png_ptr, "Unable to write uncompressed text"); -#endif - } - } -#endif - -#ifdef PNG_WRITE_eXIf_SUPPORTED - if ((info_ptr->valid & PNG_INFO_eXIf) != 0) - png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif); -#endif - -#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED - write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT); -#endif - } - - png_ptr->mode |= PNG_AFTER_IDAT; - - /* Write end of PNG file */ - png_write_IEND(png_ptr); - - /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03, - * and restored again in libpng-1.2.30, may cause some applications that - * do not set png_ptr->output_flush_fn to crash. If your application - * experiences a problem, please try building libpng with - * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to - * png-mng-implement at lists.sf.net . - */ -#ifdef PNG_WRITE_FLUSH_SUPPORTED -# ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED - png_flush(png_ptr); -# endif -#endif -} - -#ifdef PNG_CONVERT_tIME_SUPPORTED -void PNGAPI -png_convert_from_struct_tm(png_timep ptime, const struct tm * ttime) -{ - png_debug(1, "in png_convert_from_struct_tm"); - - ptime->year = (png_uint_16)(1900 + ttime->tm_year); - ptime->month = (png_byte)(ttime->tm_mon + 1); - ptime->day = (png_byte)ttime->tm_mday; - ptime->hour = (png_byte)ttime->tm_hour; - ptime->minute = (png_byte)ttime->tm_min; - ptime->second = (png_byte)ttime->tm_sec; -} - -void PNGAPI -png_convert_from_time_t(png_timep ptime, time_t ttime) -{ - struct tm *tbuf; - - png_debug(1, "in png_convert_from_time_t"); - - tbuf = gmtime(&ttime); - png_convert_from_struct_tm(ptime, tbuf); -} -#endif - -/* Initialize png_ptr structure, and allocate any memory needed */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) -{ -#ifndef PNG_USER_MEM_SUPPORTED - png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, NULL, NULL, NULL); -#else - return png_create_write_struct_2(user_png_ver, error_ptr, error_fn, - warn_fn, NULL, NULL, NULL); -} - -/* Alternate initialize png_ptr structure, and allocate any memory needed */ -PNG_FUNCTION(png_structp,PNGAPI -png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) -{ - png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr, - error_fn, warn_fn, mem_ptr, malloc_fn, free_fn); -#endif /* USER_MEM */ - if (png_ptr != NULL) - { - /* Set the zlib control values to defaults; they can be overridden by the - * application after the struct has been created. - */ - png_ptr->zbuffer_size = PNG_ZBUF_SIZE; - - /* The 'zlib_strategy' setting is irrelevant because png_default_claim in - * pngwutil.c defaults it according to whether or not filters will be - * used, and ignores this setting. - */ - png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY; - png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION; - png_ptr->zlib_mem_level = 8; - png_ptr->zlib_window_bits = 15; - png_ptr->zlib_method = 8; - -#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED - png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY; - png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION; - png_ptr->zlib_text_mem_level = 8; - png_ptr->zlib_text_window_bits = 15; - png_ptr->zlib_text_method = 8; -#endif /* WRITE_COMPRESSED_TEXT */ - - /* This is a highly dubious configuration option; by default it is off, - * but it may be appropriate for private builds that are testing - * extensions not conformant to the current specification, or of - * applications that must not fail to write at all costs! - */ -#ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED - /* In stable builds only warn if an application error can be completely - * handled. - */ - png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; -#endif - - /* App warnings are warnings in release (or release candidate) builds but - * are errors during development. - */ -#if PNG_RELEASE_BUILD - png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN; -#endif - - /* TODO: delay this, it can be done in png_init_io() (if the app doesn't - * do it itself) avoiding setting the default function if it is not - * required. - */ - png_set_write_fn(png_ptr, NULL, NULL, NULL); - } - - return png_ptr; -} - - -/* Write a few rows of image data. If the image is interlaced, - * either you will have to write the 7 sub images, or, if you - * have called png_set_interlace_handling(), you will have to - * "write" the image seven times. - */ -void PNGAPI -png_write_rows(png_structrp png_ptr, png_bytepp row, - png_uint_32 num_rows) -{ - png_uint_32 i; /* row counter */ - png_bytepp rp; /* row pointer */ - - png_debug(1, "in png_write_rows"); - - if (png_ptr == NULL) - return; - - /* Loop through the rows */ - for (i = 0, rp = row; i < num_rows; i++, rp++) - { - png_write_row(png_ptr, *rp); - } -} - -/* Write the image. You only need to call this function once, even - * if you are writing an interlaced image. - */ -void PNGAPI -png_write_image(png_structrp png_ptr, png_bytepp image) -{ - png_uint_32 i; /* row index */ - int pass, num_pass; /* pass variables */ - png_bytepp rp; /* points to current row */ - - if (png_ptr == NULL) - return; - - png_debug(1, "in png_write_image"); - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Initialize interlace handling. If image is not interlaced, - * this will set pass to 1 - */ - num_pass = png_set_interlace_handling(png_ptr); -#else - num_pass = 1; -#endif - /* Loop through passes */ - for (pass = 0; pass < num_pass; pass++) - { - /* Loop through image */ - for (i = 0, rp = image; i < png_ptr->height; i++, rp++) - { - png_write_row(png_ptr, *rp); - } - } -} - -#ifdef PNG_MNG_FEATURES_SUPPORTED -/* Performs intrapixel differencing */ -static void -png_do_write_intrapixel(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_write_intrapixel"); - - if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - int bytes_per_pixel; - png_uint_32 row_width = row_info->width; - if (row_info->bit_depth == 8) - { - png_bytep rp; - png_uint_32 i; - - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 3; - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 4; - - else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - *(rp) = (png_byte)(*rp - *(rp + 1)); - *(rp + 2) = (png_byte)(*(rp + 2) - *(rp + 1)); - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else if (row_info->bit_depth == 16) - { - png_bytep rp; - png_uint_32 i; - - if (row_info->color_type == PNG_COLOR_TYPE_RGB) - bytes_per_pixel = 6; - - else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - bytes_per_pixel = 8; - - else - return; - - for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) - { - png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1); - png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3); - png_uint_32 s2 = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5); - png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); - png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); - *(rp ) = (png_byte)(red >> 8); - *(rp + 1) = (png_byte)red; - *(rp + 4) = (png_byte)(blue >> 8); - *(rp + 5) = (png_byte)blue; - } - } -#endif /* WRITE_16BIT */ - } -} -#endif /* MNG_FEATURES */ - -/* Called by user to write a row of image data */ -void PNGAPI -png_write_row(png_structrp png_ptr, png_const_bytep row) -{ - /* 1.5.6: moved from png_struct to be a local structure: */ - png_row_info row_info; - - if (png_ptr == NULL) - return; - - png_debug2(1, "in png_write_row (row %u, pass %d)", - png_ptr->row_number, png_ptr->pass); - - /* Initialize transformations and other stuff if first time */ - if (png_ptr->row_number == 0 && png_ptr->pass == 0) - { - /* Make sure we wrote the header info */ - if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0) - png_error(png_ptr, - "png_write_info was never called before png_write_row"); - - /* Check for transforms that have been set but were defined out */ -#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) - if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) - png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) - if ((png_ptr->transformations & PNG_FILLER) != 0) - png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined"); -#endif -#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ - defined(PNG_READ_PACKSWAP_SUPPORTED) - if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - png_warning(png_ptr, - "PNG_WRITE_PACKSWAP_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) - if ((png_ptr->transformations & PNG_PACK) != 0) - png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) - if ((png_ptr->transformations & PNG_SHIFT) != 0) - png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) - if ((png_ptr->transformations & PNG_BGR) != 0) - png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined"); -#endif - -#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) - if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) - png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined"); -#endif - - png_write_start_row(png_ptr); - } - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* If interlaced and not interested in row, return */ - if (png_ptr->interlaced != 0 && - (png_ptr->transformations & PNG_INTERLACE) != 0) - { - switch (png_ptr->pass) - { - case 0: - if ((png_ptr->row_number & 0x07) != 0) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 1: - if ((png_ptr->row_number & 0x07) != 0 || png_ptr->width < 5) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 2: - if ((png_ptr->row_number & 0x07) != 4) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 3: - if ((png_ptr->row_number & 0x03) != 0 || png_ptr->width < 3) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 4: - if ((png_ptr->row_number & 0x03) != 2) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 5: - if ((png_ptr->row_number & 0x01) != 0 || png_ptr->width < 2) - { - png_write_finish_row(png_ptr); - return; - } - break; - - case 6: - if ((png_ptr->row_number & 0x01) == 0) - { - png_write_finish_row(png_ptr); - return; - } - break; - - default: /* error: ignore it */ - break; - } - } -#endif - - /* Set up row info for transformations */ - row_info.color_type = png_ptr->color_type; - row_info.width = png_ptr->usr_width; - row_info.channels = png_ptr->usr_channels; - row_info.bit_depth = png_ptr->usr_bit_depth; - row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels); - row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); - - png_debug1(3, "row_info->color_type = %d", row_info.color_type); - png_debug1(3, "row_info->width = %u", row_info.width); - png_debug1(3, "row_info->channels = %d", row_info.channels); - png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth); - png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth); - png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes); - - /* Copy user's row into buffer, leaving room for filter byte. */ - memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes); - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Handle interlacing */ - if (png_ptr->interlaced && png_ptr->pass < 6 && - (png_ptr->transformations & PNG_INTERLACE) != 0) - { - png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass); - /* This should always get caught above, but still ... */ - if (row_info.width == 0) - { - png_write_finish_row(png_ptr); - return; - } - } -#endif - -#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED - /* Handle other transformations */ - if (png_ptr->transformations != 0) - png_do_write_transformations(png_ptr, &row_info); -#endif - - /* At this point the row_info pixel depth must match the 'transformed' depth, - * which is also the output depth. - */ - if (row_info.pixel_depth != png_ptr->pixel_depth || - row_info.pixel_depth != png_ptr->transformed_pixel_depth) - png_error(png_ptr, "internal write transform logic error"); - -#ifdef PNG_MNG_FEATURES_SUPPORTED - /* Write filter_method 64 (intrapixel differencing) only if - * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and - * 2. Libpng did not write a PNG signature (this filter_method is only - * used in PNG datastreams that are embedded in MNG datastreams) and - * 3. The application called png_permit_mng_features with a mask that - * included PNG_FLAG_MNG_FILTER_64 and - * 4. The filter_method is 64 and - * 5. The color_type is RGB or RGBA - */ - if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) - { - /* Intrapixel differencing */ - png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1); - } -#endif - -/* Added at libpng-1.5.10 */ -#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED - /* Check for out-of-range palette index */ - if (row_info.color_type == PNG_COLOR_TYPE_PALETTE && - png_ptr->num_palette_max >= 0) - png_do_check_palette_indexes(png_ptr, &row_info); -#endif - - /* Find a filter if necessary, filter the row and write it out. */ - png_write_find_filter(png_ptr, &row_info); - - if (png_ptr->write_row_fn != NULL) - (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass); -} - -#ifdef PNG_WRITE_FLUSH_SUPPORTED -/* Set the automatic flush interval or 0 to turn flushing off */ -void PNGAPI -png_set_flush(png_structrp png_ptr, int nrows) -{ - png_debug(1, "in png_set_flush"); - - if (png_ptr == NULL) - return; - - png_ptr->flush_dist = (nrows < 0 ? 0 : (png_uint_32)nrows); -} - -/* Flush the current output buffers now */ -void PNGAPI -png_write_flush(png_structrp png_ptr) -{ - png_debug(1, "in png_write_flush"); - - if (png_ptr == NULL) - return; - - /* We have already written out all of the data */ - if (png_ptr->row_number >= png_ptr->num_rows) - return; - - png_compress_IDAT(png_ptr, NULL, 0, Z_SYNC_FLUSH); - png_ptr->flush_rows = 0; - png_flush(png_ptr); -} -#endif /* WRITE_FLUSH */ - -/* Free any memory used in png_ptr struct without freeing the struct itself. */ -static void -png_write_destroy(png_structrp png_ptr) -{ - png_debug(1, "in png_write_destroy"); - - /* Free any memory zlib uses */ - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) - deflateEnd(&png_ptr->zstream); - - /* Free our memory. png_free checks NULL for us. */ - png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); - png_free(png_ptr, png_ptr->row_buf); - png_ptr->row_buf = NULL; -#ifdef PNG_WRITE_FILTER_SUPPORTED - png_free(png_ptr, png_ptr->prev_row); - png_free(png_ptr, png_ptr->try_row); - png_free(png_ptr, png_ptr->tst_row); - png_ptr->prev_row = NULL; - png_ptr->try_row = NULL; - png_ptr->tst_row = NULL; -#endif - -#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->chunk_list = NULL; -#endif - - /* The error handling and memory handling information is left intact at this - * point: the jmp_buf may still have to be freed. See png_destroy_png_struct - * for how this happens. - */ -} - -/* Free all memory used by the write. - * In libpng 1.6.0 this API changed quietly to no longer accept a NULL value for - * *png_ptr_ptr. Prior to 1.6.0 it would accept such a value and it would free - * the passed in info_structs but it would quietly fail to free any of the data - * inside them. In 1.6.0 it quietly does nothing (it has to be quiet because it - * has no png_ptr.) - */ -void PNGAPI -png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) -{ - png_debug(1, "in png_destroy_write_struct"); - - if (png_ptr_ptr != NULL) - { - png_structrp png_ptr = *png_ptr_ptr; - - if (png_ptr != NULL) /* added in libpng 1.6.0 */ - { - png_destroy_info_struct(png_ptr, info_ptr_ptr); - - *png_ptr_ptr = NULL; - png_write_destroy(png_ptr); - png_destroy_png_struct(png_ptr); - } - } -} - -/* Allow the application to select one or more row filters to use. */ -void PNGAPI -png_set_filter(png_structrp png_ptr, int method, int filters) -{ - png_debug(1, "in png_set_filter"); - - if (png_ptr == NULL) - return; - -#ifdef PNG_MNG_FEATURES_SUPPORTED - if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - (method == PNG_INTRAPIXEL_DIFFERENCING)) - method = PNG_FILTER_TYPE_BASE; - -#endif - if (method == PNG_FILTER_TYPE_BASE) - { - switch (filters & (PNG_ALL_FILTERS | 0x07)) - { -#ifdef PNG_WRITE_FILTER_SUPPORTED - case 5: - case 6: - case 7: png_app_error(png_ptr, "Unknown row filter for method 0"); -#endif /* WRITE_FILTER */ - /* FALLTHROUGH */ - case PNG_FILTER_VALUE_NONE: - png_ptr->do_filter = PNG_FILTER_NONE; break; - -#ifdef PNG_WRITE_FILTER_SUPPORTED - case PNG_FILTER_VALUE_SUB: - png_ptr->do_filter = PNG_FILTER_SUB; break; - - case PNG_FILTER_VALUE_UP: - png_ptr->do_filter = PNG_FILTER_UP; break; - - case PNG_FILTER_VALUE_AVG: - png_ptr->do_filter = PNG_FILTER_AVG; break; - - case PNG_FILTER_VALUE_PAETH: - png_ptr->do_filter = PNG_FILTER_PAETH; break; - - default: - png_ptr->do_filter = (png_byte)filters; break; -#else - default: - png_app_error(png_ptr, "Unknown row filter for method 0"); -#endif /* WRITE_FILTER */ - } - -#ifdef PNG_WRITE_FILTER_SUPPORTED - /* If we have allocated the row_buf, this means we have already started - * with the image and we should have allocated all of the filter buffers - * that have been selected. If prev_row isn't already allocated, then - * it is too late to start using the filters that need it, since we - * will be missing the data in the previous row. If an application - * wants to start and stop using particular filters during compression, - * it should start out with all of the filters, and then remove them - * or add them back after the start of compression. - * - * NOTE: this is a nasty constraint on the code, because it means that the - * prev_row buffer must be maintained even if there are currently no - * 'prev_row' requiring filters active. - */ - if (png_ptr->row_buf != NULL) - { - int num_filters; - png_alloc_size_t buf_size; - - /* Repeat the checks in png_write_start_row; 1 pixel high or wide - * images cannot benefit from certain filters. If this isn't done here - * the check below will fire on 1 pixel high images. - */ - if (png_ptr->height == 1) - filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); - - if (png_ptr->width == 1) - filters &= ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH); - - if ((filters & (PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH)) != 0 - && png_ptr->prev_row == NULL) - { - /* This is the error case, however it is benign - the previous row - * is not available so the filter can't be used. Just warn here. - */ - png_app_warning(png_ptr, - "png_set_filter: UP/AVG/PAETH cannot be added after start"); - filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); - } - - num_filters = 0; - - if (filters & PNG_FILTER_SUB) - num_filters++; - - if (filters & PNG_FILTER_UP) - num_filters++; - - if (filters & PNG_FILTER_AVG) - num_filters++; - - if (filters & PNG_FILTER_PAETH) - num_filters++; - - /* Allocate needed row buffers if they have not already been - * allocated. - */ - buf_size = PNG_ROWBYTES(png_ptr->usr_channels * png_ptr->usr_bit_depth, - png_ptr->width) + 1; - - if (png_ptr->try_row == NULL) - png_ptr->try_row = png_voidcast(png_bytep, - png_malloc(png_ptr, buf_size)); - - if (num_filters > 1) - { - if (png_ptr->tst_row == NULL) - png_ptr->tst_row = png_voidcast(png_bytep, - png_malloc(png_ptr, buf_size)); - } - } - png_ptr->do_filter = (png_byte)filters; -#endif - } - else - png_error(png_ptr, "Unknown custom filter method"); -} - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */ -/* Provide floating and fixed point APIs */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method, - int num_weights, png_const_doublep filter_weights, - png_const_doublep filter_costs) -{ - PNG_UNUSED(png_ptr) - PNG_UNUSED(heuristic_method) - PNG_UNUSED(num_weights) - PNG_UNUSED(filter_weights) - PNG_UNUSED(filter_costs) -} -#endif /* FLOATING_POINT */ - -#ifdef PNG_FIXED_POINT_SUPPORTED -void PNGAPI -png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method, - int num_weights, png_const_fixed_point_p filter_weights, - png_const_fixed_point_p filter_costs) -{ - PNG_UNUSED(png_ptr) - PNG_UNUSED(heuristic_method) - PNG_UNUSED(num_weights) - PNG_UNUSED(filter_weights) - PNG_UNUSED(filter_costs) -} -#endif /* FIXED_POINT */ -#endif /* WRITE_WEIGHTED_FILTER */ - -#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED -void PNGAPI -png_set_compression_level(png_structrp png_ptr, int level) -{ - png_debug(1, "in png_set_compression_level"); - - if (png_ptr == NULL) - return; - - png_ptr->zlib_level = level; -} - -void PNGAPI -png_set_compression_mem_level(png_structrp png_ptr, int mem_level) -{ - png_debug(1, "in png_set_compression_mem_level"); - - if (png_ptr == NULL) - return; - - png_ptr->zlib_mem_level = mem_level; -} - -void PNGAPI -png_set_compression_strategy(png_structrp png_ptr, int strategy) -{ - png_debug(1, "in png_set_compression_strategy"); - - if (png_ptr == NULL) - return; - - /* The flag setting here prevents the libpng dynamic selection of strategy. - */ - png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; - png_ptr->zlib_strategy = strategy; -} - -/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a - * smaller value of window_bits if it can do so safely. - */ -void PNGAPI -png_set_compression_window_bits(png_structrp png_ptr, int window_bits) -{ - if (png_ptr == NULL) - return; - - /* Prior to 1.6.0 this would warn but then set the window_bits value. This - * meant that negative window bits values could be selected that would cause - * libpng to write a non-standard PNG file with raw deflate or gzip - * compressed IDAT or ancillary chunks. Such files can be read and there is - * no warning on read, so this seems like a very bad idea. - */ - if (window_bits > 15) - { - png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); - window_bits = 15; - } - - else if (window_bits < 8) - { - png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); - window_bits = 8; - } - - png_ptr->zlib_window_bits = window_bits; -} - -void PNGAPI -png_set_compression_method(png_structrp png_ptr, int method) -{ - png_debug(1, "in png_set_compression_method"); - - if (png_ptr == NULL) - return; - - /* This would produce an invalid PNG file if it worked, but it doesn't and - * deflate will fault it, so it is harmless to just warn here. - */ - if (method != 8) - png_warning(png_ptr, "Only compression method 8 is supported by PNG"); - - png_ptr->zlib_method = method; -} -#endif /* WRITE_CUSTOMIZE_COMPRESSION */ - -/* The following were added to libpng-1.5.4 */ -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED -void PNGAPI -png_set_text_compression_level(png_structrp png_ptr, int level) -{ - png_debug(1, "in png_set_text_compression_level"); - - if (png_ptr == NULL) - return; - - png_ptr->zlib_text_level = level; -} - -void PNGAPI -png_set_text_compression_mem_level(png_structrp png_ptr, int mem_level) -{ - png_debug(1, "in png_set_text_compression_mem_level"); - - if (png_ptr == NULL) - return; - - png_ptr->zlib_text_mem_level = mem_level; -} - -void PNGAPI -png_set_text_compression_strategy(png_structrp png_ptr, int strategy) -{ - png_debug(1, "in png_set_text_compression_strategy"); - - if (png_ptr == NULL) - return; - - png_ptr->zlib_text_strategy = strategy; -} - -/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a - * smaller value of window_bits if it can do so safely. - */ -void PNGAPI -png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits) -{ - if (png_ptr == NULL) - return; - - if (window_bits > 15) - { - png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); - window_bits = 15; - } - - else if (window_bits < 8) - { - png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); - window_bits = 8; - } - - png_ptr->zlib_text_window_bits = window_bits; -} - -void PNGAPI -png_set_text_compression_method(png_structrp png_ptr, int method) -{ - png_debug(1, "in png_set_text_compression_method"); - - if (png_ptr == NULL) - return; - - if (method != 8) - png_warning(png_ptr, "Only compression method 8 is supported by PNG"); - - png_ptr->zlib_text_method = method; -} -#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */ -/* end of API added to libpng-1.5.4 */ - -void PNGAPI -png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn) -{ - if (png_ptr == NULL) - return; - - png_ptr->write_row_fn = write_row_fn; -} - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -void PNGAPI -png_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr - write_user_transform_fn) -{ - png_debug(1, "in png_set_write_user_transform_fn"); - - if (png_ptr == NULL) - return; - - png_ptr->transformations |= PNG_USER_TRANSFORM; - png_ptr->write_user_transform_fn = write_user_transform_fn; -} -#endif - - -#ifdef PNG_INFO_IMAGE_SUPPORTED -void PNGAPI -png_write_png(png_structrp png_ptr, png_inforp info_ptr, - int transforms, voidp params) -{ - if (png_ptr == NULL || info_ptr == NULL) - return; - - if ((info_ptr->valid & PNG_INFO_IDAT) == 0) - { - png_app_error(png_ptr, "no rows for png_write_image to write"); - return; - } - - /* Write the file header information. */ - png_write_info(png_ptr, info_ptr); - - /* ------ these transformations don't touch the info structure ------- */ - - /* Invert monochrome pixels */ - if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0) -#ifdef PNG_WRITE_INVERT_SUPPORTED - png_set_invert_mono(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported"); -#endif - - /* Shift the pixels up to a legal bit depth and fill in - * as appropriate to correctly scale the image. - */ - if ((transforms & PNG_TRANSFORM_SHIFT) != 0) -#ifdef PNG_WRITE_SHIFT_SUPPORTED - if ((info_ptr->valid & PNG_INFO_sBIT) != 0) - png_set_shift(png_ptr, &info_ptr->sig_bit); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported"); -#endif - - /* Pack pixels into bytes */ - if ((transforms & PNG_TRANSFORM_PACKING) != 0) -#ifdef PNG_WRITE_PACK_SUPPORTED - png_set_packing(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported"); -#endif - - /* Swap location of alpha bytes from ARGB to RGBA */ - if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0) -#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED - png_set_swap_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported"); -#endif - - /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into - * RGB, note that the code expects the input color type to be G or RGB; no - * alpha channel. - */ - if ((transforms & (PNG_TRANSFORM_STRIP_FILLER_AFTER| - PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0) - { -#ifdef PNG_WRITE_FILLER_SUPPORTED - if ((transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) != 0) - { - if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) - png_app_error(png_ptr, - "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported"); - - /* Continue if ignored - this is the pre-1.6.10 behavior */ - png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); - } - - else if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0) - png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported"); -#endif - } - - /* Flip BGR pixels to RGB */ - if ((transforms & PNG_TRANSFORM_BGR) != 0) -#ifdef PNG_WRITE_BGR_SUPPORTED - png_set_bgr(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported"); -#endif - - /* Swap bytes of 16-bit files to most significant byte first */ - if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0) -#ifdef PNG_WRITE_SWAP_SUPPORTED - png_set_swap(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported"); -#endif - - /* Swap bits of 1-bit, 2-bit, 4-bit packed pixel formats */ - if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0) -#ifdef PNG_WRITE_PACKSWAP_SUPPORTED - png_set_packswap(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported"); -#endif - - /* Invert the alpha channel from opacity to transparency */ - if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0) -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - png_set_invert_alpha(png_ptr); -#else - png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported"); -#endif - - /* ----------------------- end of transformations ------------------- */ - - /* Write the bits */ - png_write_image(png_ptr, info_ptr->row_pointers); - - /* It is REQUIRED to call this to finish writing the rest of the file */ - png_write_end(png_ptr, info_ptr); - - PNG_UNUSED(params) -} -#endif - - -#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED -/* Initialize the write structure - general purpose utility. */ -static int -png_image_write_init(png_imagep image) -{ - png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image, - png_safe_error, png_safe_warning); - - if (png_ptr != NULL) - { - png_infop info_ptr = png_create_info_struct(png_ptr); - - if (info_ptr != NULL) - { - png_controlp control = png_voidcast(png_controlp, - png_malloc_warn(png_ptr, (sizeof *control))); - - if (control != NULL) - { - memset(control, 0, (sizeof *control)); - - control->png_ptr = png_ptr; - control->info_ptr = info_ptr; - control->for_write = 1; - - image->opaque = control; - return 1; - } - - /* Error clean up */ - png_destroy_info_struct(png_ptr, &info_ptr); - } - - png_destroy_write_struct(&png_ptr, NULL); - } - - return png_image_error(image, "png_image_write_: out of memory"); -} - -/* Arguments to png_image_write_main: */ -typedef struct -{ - /* Arguments: */ - png_imagep image; - png_const_voidp buffer; - png_int_32 row_stride; - png_const_voidp colormap; - int convert_to_8bit; - /* Local variables: */ - png_const_voidp first_row; - ptrdiff_t row_bytes; - png_voidp local_row; - /* Byte count for memory writing */ - png_bytep memory; - png_alloc_size_t memory_bytes; /* not used for STDIO */ - png_alloc_size_t output_bytes; /* running total */ -} png_image_write_control; - -/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to - * do any necessary byte swapping. The component order is defined by the - * png_image format value. - */ -static int -png_write_image_16bit(png_voidp argument) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - - png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, - display->first_row); - png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row); - png_uint_16p row_end; - unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? - 3 : 1; - int aindex = 0; - png_uint_32 y = image->height; - - if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) - { -# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED - if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - aindex = -1; - ++input_row; /* To point to the first component */ - ++output_row; - } - else - aindex = (int)channels; -# else - aindex = (int)channels; -# endif - } - - else - png_error(png_ptr, "png_write_image: internal call error"); - - /* Work out the output row end and count over this, note that the increment - * above to 'row' means that row_end can actually be beyond the end of the - * row; this is correct. - */ - row_end = output_row + image->width * (channels+1); - - for (; y > 0; --y) - { - png_const_uint_16p in_ptr = input_row; - png_uint_16p out_ptr = output_row; - - while (out_ptr < row_end) - { - png_uint_16 alpha = in_ptr[aindex]; - png_uint_32 reciprocal = 0; - int c; - - out_ptr[aindex] = alpha; - - /* Calculate a reciprocal. The correct calculation is simply - * component/alpha*65535 << 15. (I.e. 15 bits of precision); this - * allows correct rounding by adding .5 before the shift. 'reciprocal' - * is only initialized when required. - */ - if (alpha > 0 && alpha < 65535) - reciprocal = ((0xffff<<15)+(alpha>>1))/alpha; - - c = (int)channels; - do /* always at least one channel */ - { - png_uint_16 component = *in_ptr++; - - /* The following gives 65535 for an alpha of 0, which is fine, - * otherwise if 0/0 is represented as some other value there is more - * likely to be a discontinuity which will probably damage - * compression when moving from a fully transparent area to a - * nearly transparent one. (The assumption here is that opaque - * areas tend not to be 0 intensity.) - */ - if (component >= alpha) - component = 65535; - - /* component 0 && alpha < 65535) - { - png_uint_32 calc = component * reciprocal; - calc += 16384; /* round to nearest */ - component = (png_uint_16)(calc >> 15); - } - - *out_ptr++ = component; - } - while (--c > 0); - - /* Skip to next component (skip the intervening alpha channel) */ - ++in_ptr; - ++out_ptr; - } - - png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row)); - input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16)); - } - - return 1; -} - -/* Given 16-bit input (1 to 4 channels) write 8-bit output. If an alpha channel - * is present it must be removed from the components, the components are then - * written in sRGB encoding. No components are added or removed. - * - * Calculate an alpha reciprocal to reverse pre-multiplication. As above the - * calculation can be done to 15 bits of accuracy; however, the output needs to - * be scaled in the range 0..255*65535, so include that scaling here. - */ -# define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+((alpha)>>1))/(alpha)) - -static png_byte -png_unpremultiply(png_uint_32 component, png_uint_32 alpha, - png_uint_32 reciprocal/*from the above macro*/) -{ - /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0 - * is represented as some other value there is more likely to be a - * discontinuity which will probably damage compression when moving from a - * fully transparent area to a nearly transparent one. (The assumption here - * is that opaque areas tend not to be 0 intensity.) - * - * There is a rounding problem here; if alpha is less than 128 it will end up - * as 0 when scaled to 8 bits. To avoid introducing spurious colors into the - * output change for this too. - */ - if (component >= alpha || alpha < 128) - return 255; - - /* component 0) - { - /* The test is that alpha/257 (rounded) is less than 255, the first value - * that becomes 255 is 65407. - * NOTE: this must agree with the PNG_DIV257 macro (which must, therefore, - * be exact!) [Could also test reciprocal != 0] - */ - if (alpha < 65407) - { - component *= reciprocal; - component += 64; /* round to nearest */ - component >>= 7; - } - - else - component *= 255; - - /* Convert the component to sRGB. */ - return (png_byte)PNG_sRGB_FROM_LINEAR(component); - } - - else - return 0; -} - -static int -png_write_image_8bit(png_voidp argument) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - - png_const_uint_16p input_row = png_voidcast(png_const_uint_16p, - display->first_row); - png_bytep output_row = png_voidcast(png_bytep, display->local_row); - png_uint_32 y = image->height; - unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? - 3 : 1; - - if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) - { - png_bytep row_end; - int aindex; - -# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED - if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - aindex = -1; - ++input_row; /* To point to the first component */ - ++output_row; - } - - else -# endif - aindex = (int)channels; - - /* Use row_end in place of a loop counter: */ - row_end = output_row + image->width * (channels+1); - - for (; y > 0; --y) - { - png_const_uint_16p in_ptr = input_row; - png_bytep out_ptr = output_row; - - while (out_ptr < row_end) - { - png_uint_16 alpha = in_ptr[aindex]; - png_byte alphabyte = (png_byte)PNG_DIV257(alpha); - png_uint_32 reciprocal = 0; - int c; - - /* Scale and write the alpha channel. */ - out_ptr[aindex] = alphabyte; - - if (alphabyte > 0 && alphabyte < 255) - reciprocal = UNP_RECIPROCAL(alpha); - - c = (int)channels; - do /* always at least one channel */ - *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal); - while (--c > 0); - - /* Skip to next component (skip the intervening alpha channel) */ - ++in_ptr; - ++out_ptr; - } /* while out_ptr < row_end */ - - png_write_row(png_ptr, png_voidcast(png_const_bytep, - display->local_row)); - input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16)); - } /* while y */ - } - - else - { - /* No alpha channel, so the row_end really is the end of the row and it - * is sufficient to loop over the components one by one. - */ - png_bytep row_end = output_row + image->width * channels; - - for (; y > 0; --y) - { - png_const_uint_16p in_ptr = input_row; - png_bytep out_ptr = output_row; - - while (out_ptr < row_end) - { - png_uint_32 component = *in_ptr++; - - component *= 255; - *out_ptr++ = (png_byte)PNG_sRGB_FROM_LINEAR(component); - } - - png_write_row(png_ptr, output_row); - input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16)); - } - } - - return 1; -} - -static void -png_image_set_PLTE(png_image_write_control *display) -{ - png_imagep image = display->image; - const void *cmap = display->colormap; - int entries = image->colormap_entries > 256 ? 256 : - (int)image->colormap_entries; - - /* NOTE: the caller must check for cmap != NULL and entries != 0 */ - png_uint_32 format = image->format; - unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); - -# if defined(PNG_FORMAT_BGR_SUPPORTED) &&\ - defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED) - int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 && - (format & PNG_FORMAT_FLAG_ALPHA) != 0; -# else -# define afirst 0 -# endif - -# ifdef PNG_FORMAT_BGR_SUPPORTED - int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; -# else -# define bgr 0 -# endif - - int i, num_trans; - png_color palette[256]; - png_byte tRNS[256]; - - memset(tRNS, 255, (sizeof tRNS)); - memset(palette, 0, (sizeof palette)); - - for (i=num_trans=0; i= 3) /* RGB */ - { - palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 * - entry[(2 ^ bgr)]); - palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 * - entry[1]); - palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 * - entry[bgr]); - } - - else /* Gray */ - palette[i].blue = palette[i].red = palette[i].green = - (png_byte)PNG_sRGB_FROM_LINEAR(255 * *entry); - } - - else /* alpha */ - { - png_uint_16 alpha = entry[afirst ? 0 : channels-1]; - png_byte alphabyte = (png_byte)PNG_DIV257(alpha); - png_uint_32 reciprocal = 0; - - /* Calculate a reciprocal, as in the png_write_image_8bit code above - * this is designed to produce a value scaled to 255*65535 when - * divided by 128 (i.e. asr 7). - */ - if (alphabyte > 0 && alphabyte < 255) - reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha; - - tRNS[i] = alphabyte; - if (alphabyte < 255) - num_trans = i+1; - - if (channels >= 3) /* RGB */ - { - palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)], - alpha, reciprocal); - palette[i].green = png_unpremultiply(entry[afirst + 1], alpha, - reciprocal); - palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha, - reciprocal); - } - - else /* gray */ - palette[i].blue = palette[i].red = palette[i].green = - png_unpremultiply(entry[afirst], alpha, reciprocal); - } - } - - else /* Color-map has sRGB values */ - { - png_const_bytep entry = png_voidcast(png_const_bytep, cmap); - - entry += (unsigned int)i * channels; - - switch (channels) - { - case 4: - tRNS[i] = entry[afirst ? 0 : 3]; - if (tRNS[i] < 255) - num_trans = i+1; - /* FALLTHROUGH */ - case 3: - palette[i].blue = entry[afirst + (2 ^ bgr)]; - palette[i].green = entry[afirst + 1]; - palette[i].red = entry[afirst + bgr]; - break; - - case 2: - tRNS[i] = entry[1 ^ afirst]; - if (tRNS[i] < 255) - num_trans = i+1; - /* FALLTHROUGH */ - case 1: - palette[i].blue = palette[i].red = palette[i].green = - entry[afirst]; - break; - - default: - break; - } - } - } - -# ifdef afirst -# undef afirst -# endif -# ifdef bgr -# undef bgr -# endif - - png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette, - entries); - - if (num_trans > 0) - png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS, - num_trans, NULL); - - image->colormap_entries = (png_uint_32)entries; -} - -static int -png_image_write_main(png_voidp argument) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); - png_imagep image = display->image; - png_structrp png_ptr = image->opaque->png_ptr; - png_inforp info_ptr = image->opaque->info_ptr; - png_uint_32 format = image->format; - - /* The following four ints are actually booleans */ - int colormap = (format & PNG_FORMAT_FLAG_COLORMAP); - int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */ - int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA); - int write_16bit = linear && (display->convert_to_8bit == 0); - -# ifdef PNG_BENIGN_ERRORS_SUPPORTED - /* Make sure we error out on any bad situation */ - png_set_benign_errors(png_ptr, 0/*error*/); -# endif - - /* Default the 'row_stride' parameter if required, also check the row stride - * and total image size to ensure that they are within the system limits. - */ - { - unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); - - if (image->width <= 0x7fffffffU/channels) /* no overflow */ - { - png_uint_32 check; - png_uint_32 png_row_stride = image->width * channels; - - if (display->row_stride == 0) - display->row_stride = (png_int_32)/*SAFE*/png_row_stride; - - if (display->row_stride < 0) - check = (png_uint_32)(-display->row_stride); - - else - check = (png_uint_32)display->row_stride; - - if (check >= png_row_stride) - { - /* Now check for overflow of the image buffer calculation; this - * limits the whole image size to 32 bits for API compatibility with - * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro. - */ - if (image->height > 0xffffffffU/png_row_stride) - png_error(image->opaque->png_ptr, "memory image too large"); - } - - else - png_error(image->opaque->png_ptr, "supplied row stride too small"); - } - - else - png_error(image->opaque->png_ptr, "image row stride too large"); - } - - /* Set the required transforms then write the rows in the correct order. */ - if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0) - { - if (display->colormap != NULL && image->colormap_entries > 0) - { - png_uint_32 entries = image->colormap_entries; - - png_set_IHDR(png_ptr, info_ptr, image->width, image->height, - entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)), - PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - png_image_set_PLTE(display); - } - - else - png_error(image->opaque->png_ptr, - "no color-map for color-mapped image"); - } - - else - png_set_IHDR(png_ptr, info_ptr, image->width, image->height, - write_16bit ? 16 : 8, - ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) + - ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0), - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - /* Counter-intuitively the data transformations must be called *after* - * png_write_info, not before as in the read code, but the 'set' functions - * must still be called before. Just set the color space information, never - * write an interlaced image. - */ - - if (write_16bit != 0) - { - /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */ - png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR); - - if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) - png_set_cHRM_fixed(png_ptr, info_ptr, - /* color x y */ - /* white */ 31270, 32900, - /* red */ 64000, 33000, - /* green */ 30000, 60000, - /* blue */ 15000, 6000 - ); - } - - else if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0) - png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL); - - /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit - * space must still be gamma encoded. - */ - else - png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE); - - /* Write the file header. */ - png_write_info(png_ptr, info_ptr); - - /* Now set up the data transformations (*after* the header is written), - * remove the handled transformations from the 'format' flags for checking. - * - * First check for a little endian system if writing 16-bit files. - */ - if (write_16bit != 0) - { - png_uint_16 le = 0x0001; - - if ((*(png_const_bytep) & le) != 0) - png_set_swap(png_ptr); - } - -# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED - if ((format & PNG_FORMAT_FLAG_BGR) != 0) - { - if (colormap == 0 && (format & PNG_FORMAT_FLAG_COLOR) != 0) - png_set_bgr(png_ptr); - format &= ~PNG_FORMAT_FLAG_BGR; - } -# endif - -# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED - if ((format & PNG_FORMAT_FLAG_AFIRST) != 0) - { - if (colormap == 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0) - png_set_swap_alpha(png_ptr); - format &= ~PNG_FORMAT_FLAG_AFIRST; - } -# endif - - /* If there are 16 or fewer color-map entries we wrote a lower bit depth - * above, but the application data is still byte packed. - */ - if (colormap != 0 && image->colormap_entries <= 16) - png_set_packing(png_ptr); - - /* That should have handled all (both) the transforms. */ - if ((format & ~(png_uint_32)(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR | - PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0) - png_error(png_ptr, "png_write_image: unsupported transformation"); - - { - png_const_bytep row = png_voidcast(png_const_bytep, display->buffer); - ptrdiff_t row_bytes = display->row_stride; - - if (linear != 0) - row_bytes *= (sizeof (png_uint_16)); - - if (row_bytes < 0) - row += (image->height-1) * (-row_bytes); - - display->first_row = row; - display->row_bytes = row_bytes; - } - - /* Apply 'fast' options if the flag is set. */ - if ((image->flags & PNG_IMAGE_FLAG_FAST) != 0) - { - png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_NO_FILTERS); - /* NOTE: determined by experiment using pngstest, this reflects some - * balance between the time to write the image once and the time to read - * it about 50 times. The speed-up in pngstest was about 10-20% of the - * total (user) time on a heavily loaded system. - */ -# ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED - png_set_compression_level(png_ptr, 3); -# endif - } - - /* Check for the cases that currently require a pre-transform on the row - * before it is written. This only applies when the input is 16-bit and - * either there is an alpha channel or it is converted to 8-bit. - */ - if ((linear != 0 && alpha != 0 ) || - (colormap == 0 && display->convert_to_8bit != 0)) - { - png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr, - png_get_rowbytes(png_ptr, info_ptr))); - int result; - - display->local_row = row; - if (write_16bit != 0) - result = png_safe_execute(image, png_write_image_16bit, display); - else - result = png_safe_execute(image, png_write_image_8bit, display); - display->local_row = NULL; - - png_free(png_ptr, row); - - /* Skip the 'write_end' on error: */ - if (result == 0) - return 0; - } - - /* Otherwise this is the case where the input is in a format currently - * supported by the rest of the libpng write code; call it directly. - */ - else - { - png_const_bytep row = png_voidcast(png_const_bytep, display->first_row); - ptrdiff_t row_bytes = display->row_bytes; - png_uint_32 y = image->height; - - for (; y > 0; --y) - { - png_write_row(png_ptr, row); - row += row_bytes; - } - } - - png_write_end(png_ptr, info_ptr); - return 1; -} - - -static void (PNGCBAPI -image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data, size_t size) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/); - png_alloc_size_t ob = display->output_bytes; - - /* Check for overflow; this should never happen: */ - if (size <= ((png_alloc_size_t)-1) - ob) - { - /* I don't think libpng ever does this, but just in case: */ - if (size > 0) - { - if (display->memory_bytes >= ob+size) /* writing */ - memcpy(display->memory+ob, data, size); - - /* Always update the size: */ - display->output_bytes = ob+size; - } - } - - else - png_error(png_ptr, "png_image_write_to_memory: PNG too big"); -} - -static void (PNGCBAPI -image_memory_flush)(png_structp png_ptr) -{ - PNG_UNUSED(png_ptr) -} - -static int -png_image_write_memory(png_voidp argument) -{ - png_image_write_control *display = png_voidcast(png_image_write_control*, - argument); - - /* The rest of the memory-specific init and write_main in an error protected - * environment. This case needs to use callbacks for the write operations - * since libpng has no built in support for writing to memory. - */ - png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/, - image_memory_write, image_memory_flush); - - return png_image_write_main(display); -} - -int PNGAPI -png_image_write_to_memory(png_imagep image, void *memory, - png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit, - const void *buffer, png_int_32 row_stride, const void *colormap) -{ - /* Write the image to the given buffer, or count the bytes if it is NULL */ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (memory_bytes != NULL && buffer != NULL) - { - /* This is to give the caller an easier error detection in the NULL - * case and guard against uninitialized variable problems: - */ - if (memory == NULL) - *memory_bytes = 0; - - if (png_image_write_init(image) != 0) - { - png_image_write_control display; - int result; - - memset(&display, 0, (sizeof display)); - display.image = image; - display.buffer = buffer; - display.row_stride = row_stride; - display.colormap = colormap; - display.convert_to_8bit = convert_to_8bit; - display.memory = png_voidcast(png_bytep, memory); - display.memory_bytes = *memory_bytes; - display.output_bytes = 0; - - result = png_safe_execute(image, png_image_write_memory, &display); - png_image_free(image); - - /* write_memory returns true even if we ran out of buffer. */ - if (result) - { - /* On out-of-buffer this function returns '0' but still updates - * memory_bytes: - */ - if (memory != NULL && display.output_bytes > *memory_bytes) - result = 0; - - *memory_bytes = display.output_bytes; - } - - return result; - } - - else - return 0; - } - - else - return png_image_error(image, - "png_image_write_to_memory: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION"); - - else - return 0; -} - -#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED -int PNGAPI -png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit, - const void *buffer, png_int_32 row_stride, const void *colormap) -{ - /* Write the image to the given (FILE*). */ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (file != NULL && buffer != NULL) - { - if (png_image_write_init(image) != 0) - { - png_image_write_control display; - int result; - - /* This is slightly evil, but png_init_io doesn't do anything other - * than this and we haven't changed the standard IO functions so - * this saves a 'safe' function. - */ - image->opaque->png_ptr->io_ptr = file; - - memset(&display, 0, (sizeof display)); - display.image = image; - display.buffer = buffer; - display.row_stride = row_stride; - display.colormap = colormap; - display.convert_to_8bit = convert_to_8bit; - - result = png_safe_execute(image, png_image_write_main, &display); - png_image_free(image); - return result; - } - - else - return 0; - } - - else - return png_image_error(image, - "png_image_write_to_stdio: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION"); - - else - return 0; -} - -int PNGAPI -png_image_write_to_file(png_imagep image, const char *file_name, - int convert_to_8bit, const void *buffer, png_int_32 row_stride, - const void *colormap) -{ - /* Write the image to the named file. */ - if (image != NULL && image->version == PNG_IMAGE_VERSION) - { - if (file_name != NULL && buffer != NULL) - { - FILE *fp = fopen(file_name, "wb"); - - if (fp != NULL) - { - if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer, - row_stride, colormap) != 0) - { - int error; /* from fflush/fclose */ - - /* Make sure the file is flushed correctly. */ - if (fflush(fp) == 0 && ferror(fp) == 0) - { - if (fclose(fp) == 0) - return 1; - - error = errno; /* from fclose */ - } - - else - { - error = errno; /* from fflush or ferror */ - (void)fclose(fp); - } - - (void)remove(file_name); - /* The image has already been cleaned up; this is just used to - * set the error (because the original write succeeded). - */ - return png_image_error(image, strerror(error)); - } - - else - { - /* Clean up: just the opened file. */ - (void)fclose(fp); - (void)remove(file_name); - return 0; - } - } - - else - return png_image_error(image, strerror(errno)); - } - - else - return png_image_error(image, - "png_image_write_to_file: invalid argument"); - } - - else if (image != NULL) - return png_image_error(image, - "png_image_write_to_file: incorrect PNG_IMAGE_VERSION"); - - else - return 0; -} -#endif /* SIMPLIFIED_WRITE_STDIO */ -#endif /* SIMPLIFIED_WRITE */ -#endif /* WRITE */ diff --git a/extern/libpng/pngwtran.c b/extern/libpng/pngwtran.c deleted file mode 100644 index 49a13c1e9..000000000 --- a/extern/libpng/pngwtran.c +++ /dev/null @@ -1,575 +0,0 @@ - -/* pngwtran.c - transforms the data in a row for PNG writers - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -#ifdef PNG_WRITE_SUPPORTED -#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED - -#ifdef PNG_WRITE_PACK_SUPPORTED -/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The - * row_info bit depth should be 8 (one pixel per byte). The channels - * should be 1 (this only happens on grayscale and paletted images). - */ -static void -png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) -{ - png_debug(1, "in png_do_pack"); - - if (row_info->bit_depth == 8 && - row_info->channels == 1) - { - switch ((int)bit_depth) - { - case 1: - { - png_bytep sp, dp; - int mask, v; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - sp = row; - dp = row; - mask = 0x80; - v = 0; - - for (i = 0; i < row_width; i++) - { - if (*sp != 0) - v |= mask; - - sp++; - - if (mask > 1) - mask >>= 1; - - else - { - mask = 0x80; - *dp = (png_byte)v; - dp++; - v = 0; - } - } - - if (mask != 0x80) - *dp = (png_byte)v; - - break; - } - - case 2: - { - png_bytep sp, dp; - unsigned int shift; - int v; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - sp = row; - dp = row; - shift = 6; - v = 0; - - for (i = 0; i < row_width; i++) - { - png_byte value; - - value = (png_byte)(*sp & 0x03); - v |= (value << shift); - - if (shift == 0) - { - shift = 6; - *dp = (png_byte)v; - dp++; - v = 0; - } - - else - shift -= 2; - - sp++; - } - - if (shift != 6) - *dp = (png_byte)v; - - break; - } - - case 4: - { - png_bytep sp, dp; - unsigned int shift; - int v; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - sp = row; - dp = row; - shift = 4; - v = 0; - - for (i = 0; i < row_width; i++) - { - png_byte value; - - value = (png_byte)(*sp & 0x0f); - v |= (value << shift); - - if (shift == 0) - { - shift = 4; - *dp = (png_byte)v; - dp++; - v = 0; - } - - else - shift -= 4; - - sp++; - } - - if (shift != 4) - *dp = (png_byte)v; - - break; - } - - default: - break; - } - - row_info->bit_depth = (png_byte)bit_depth; - row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, - row_info->width); - } -} -#endif - -#ifdef PNG_WRITE_SHIFT_SUPPORTED -/* Shift pixel values to take advantage of whole range. Pass the - * true number of bits in bit_depth. The row should be packed - * according to row_info->bit_depth. Thus, if you had a row of - * bit depth 4, but the pixels only had values from 0 to 7, you - * would pass 3 as bit_depth, and this routine would translate the - * data to 0 to 15. - */ -static void -png_do_shift(png_row_infop row_info, png_bytep row, - png_const_color_8p bit_depth) -{ - png_debug(1, "in png_do_shift"); - - if (row_info->color_type != PNG_COLOR_TYPE_PALETTE) - { - int shift_start[4], shift_dec[4]; - unsigned int channels = 0; - - if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) - { - shift_start[channels] = row_info->bit_depth - bit_depth->red; - shift_dec[channels] = bit_depth->red; - channels++; - - shift_start[channels] = row_info->bit_depth - bit_depth->green; - shift_dec[channels] = bit_depth->green; - channels++; - - shift_start[channels] = row_info->bit_depth - bit_depth->blue; - shift_dec[channels] = bit_depth->blue; - channels++; - } - - else - { - shift_start[channels] = row_info->bit_depth - bit_depth->gray; - shift_dec[channels] = bit_depth->gray; - channels++; - } - - if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - shift_start[channels] = row_info->bit_depth - bit_depth->alpha; - shift_dec[channels] = bit_depth->alpha; - channels++; - } - - /* With low row depths, could only be grayscale, so one channel */ - if (row_info->bit_depth < 8) - { - png_bytep bp = row; - size_t i; - unsigned int mask; - size_t row_bytes = row_info->rowbytes; - - if (bit_depth->gray == 1 && row_info->bit_depth == 2) - mask = 0x55; - - else if (row_info->bit_depth == 4 && bit_depth->gray == 3) - mask = 0x11; - - else - mask = 0xff; - - for (i = 0; i < row_bytes; i++, bp++) - { - int j; - unsigned int v, out; - - v = *bp; - out = 0; - - for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) - { - if (j > 0) - out |= v << j; - - else - out |= (v >> (-j)) & mask; - } - - *bp = (png_byte)(out & 0xff); - } - } - - else if (row_info->bit_depth == 8) - { - png_bytep bp = row; - png_uint_32 i; - png_uint_32 istop = channels * row_info->width; - - for (i = 0; i < istop; i++, bp++) - { - unsigned int c = i%channels; - int j; - unsigned int v, out; - - v = *bp; - out = 0; - - for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) - { - if (j > 0) - out |= v << j; - - else - out |= v >> (-j); - } - - *bp = (png_byte)(out & 0xff); - } - } - - else - { - png_bytep bp; - png_uint_32 i; - png_uint_32 istop = channels * row_info->width; - - for (bp = row, i = 0; i < istop; i++) - { - unsigned int c = i%channels; - int j; - unsigned int value, v; - - v = png_get_uint_16(bp); - value = 0; - - for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) - { - if (j > 0) - value |= v << j; - - else - value |= v >> (-j); - } - *bp++ = (png_byte)((value >> 8) & 0xff); - *bp++ = (png_byte)(value & 0xff); - } - } - } -} -#endif - -#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED -static void -png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_write_swap_alpha"); - - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This converts from ARGB to RGBA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - png_byte save = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = save; - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else - { - /* This converts from AARRGGBB to RRGGBBAA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - png_byte save[2]; - save[0] = *(sp++); - save[1] = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = save[0]; - *(dp++) = save[1]; - } - } -#endif /* WRITE_16BIT */ - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This converts from AG to GA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - png_byte save = *(sp++); - *(dp++) = *(sp++); - *(dp++) = save; - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else - { - /* This converts from AAGG to GGAA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - png_byte save[2]; - save[0] = *(sp++); - save[1] = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = save[0]; - *(dp++) = save[1]; - } - } -#endif /* WRITE_16BIT */ - } - } -} -#endif - -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED -static void -png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) -{ - png_debug(1, "in png_do_write_invert_alpha"); - - { - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This inverts the alpha channel in RGBA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - /* Does nothing - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - */ - sp+=3; dp = sp; - *dp = (png_byte)(255 - *(sp++)); - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else - { - /* This inverts the alpha channel in RRGGBBAA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - /* Does nothing - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - *(dp++) = *(sp++); - */ - sp+=6; dp = sp; - *(dp++) = (png_byte)(255 - *(sp++)); - *dp = (png_byte)(255 - *(sp++)); - } - } -#endif /* WRITE_16BIT */ - } - - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - if (row_info->bit_depth == 8) - { - /* This inverts the alpha channel in GA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - *(dp++) = *(sp++); - *(dp++) = (png_byte)(255 - *(sp++)); - } - } - -#ifdef PNG_WRITE_16BIT_SUPPORTED - else - { - /* This inverts the alpha channel in GGAA */ - png_bytep sp, dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - for (i = 0, sp = dp = row; i < row_width; i++) - { - /* Does nothing - *(dp++) = *(sp++); - *(dp++) = *(sp++); - */ - sp+=2; dp = sp; - *(dp++) = (png_byte)(255 - *(sp++)); - *dp = (png_byte)(255 - *(sp++)); - } - } -#endif /* WRITE_16BIT */ - } - } -} -#endif - -/* Transform the data according to the user's wishes. The order of - * transformations is significant. - */ -void /* PRIVATE */ -png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info) -{ - png_debug(1, "in png_do_write_transformations"); - - if (png_ptr == NULL) - return; - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0) - if (png_ptr->write_user_transform_fn != NULL) - (*(png_ptr->write_user_transform_fn)) /* User write transform - function */ - (png_ptr, /* png_ptr */ - row_info, /* row_info: */ - /* png_uint_32 width; width of row */ - /* size_t rowbytes; number of bytes in row */ - /* png_byte color_type; color type of pixels */ - /* png_byte bit_depth; bit depth of samples */ - /* png_byte channels; number of channels (1-4) */ - /* png_byte pixel_depth; bits per pixel (depth*channels) */ - png_ptr->row_buf + 1); /* start of pixel data for row */ -#endif - -#ifdef PNG_WRITE_FILLER_SUPPORTED - if ((png_ptr->transformations & PNG_FILLER) != 0) - png_do_strip_channel(row_info, png_ptr->row_buf + 1, - !(png_ptr->flags & PNG_FLAG_FILLER_AFTER)); -#endif - -#ifdef PNG_WRITE_PACKSWAP_SUPPORTED - if ((png_ptr->transformations & PNG_PACKSWAP) != 0) - png_do_packswap(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_PACK_SUPPORTED - if ((png_ptr->transformations & PNG_PACK) != 0) - png_do_pack(row_info, png_ptr->row_buf + 1, - (png_uint_32)png_ptr->bit_depth); -#endif - -#ifdef PNG_WRITE_SWAP_SUPPORTED -# ifdef PNG_16BIT_SUPPORTED - if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0) - png_do_swap(row_info, png_ptr->row_buf + 1); -# endif -#endif - -#ifdef PNG_WRITE_SHIFT_SUPPORTED - if ((png_ptr->transformations & PNG_SHIFT) != 0) - png_do_shift(row_info, png_ptr->row_buf + 1, - &(png_ptr->shift)); -#endif - -#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0) - png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) - png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_BGR_SUPPORTED - if ((png_ptr->transformations & PNG_BGR) != 0) - png_do_bgr(row_info, png_ptr->row_buf + 1); -#endif - -#ifdef PNG_WRITE_INVERT_SUPPORTED - if ((png_ptr->transformations & PNG_INVERT_MONO) != 0) - png_do_invert(row_info, png_ptr->row_buf + 1); -#endif -} -#endif /* WRITE_TRANSFORMS */ -#endif /* WRITE */ diff --git a/extern/libpng/pngwutil.c b/extern/libpng/pngwutil.c deleted file mode 100644 index 16345e4c0..000000000 --- a/extern/libpng/pngwutil.c +++ /dev/null @@ -1,2781 +0,0 @@ - -/* pngwutil.c - utilities to write a PNG file - * - * Copyright (c) 2018 Cosmin Truta - * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * Copyright (c) 1996-1997 Andreas Dilger - * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. - * - * This code is released under the libpng license. - * For conditions of distribution and use, see the disclaimer - * and license in png.h - */ - -#include "pngpriv.h" - -#ifdef PNG_WRITE_SUPPORTED - -#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED -/* Place a 32-bit number into a buffer in PNG byte order. We work - * with unsigned numbers for convenience, although one supported - * ancillary chunk uses signed (two's complement) numbers. - */ -void PNGAPI -png_save_uint_32(png_bytep buf, png_uint_32 i) -{ - buf[0] = (png_byte)((i >> 24) & 0xffU); - buf[1] = (png_byte)((i >> 16) & 0xffU); - buf[2] = (png_byte)((i >> 8) & 0xffU); - buf[3] = (png_byte)( i & 0xffU); -} - -/* Place a 16-bit number into a buffer in PNG byte order. - * The parameter is declared unsigned int, not png_uint_16, - * just to avoid potential problems on pre-ANSI C compilers. - */ -void PNGAPI -png_save_uint_16(png_bytep buf, unsigned int i) -{ - buf[0] = (png_byte)((i >> 8) & 0xffU); - buf[1] = (png_byte)( i & 0xffU); -} -#endif - -/* Simple function to write the signature. If we have already written - * the magic bytes of the signature, or more likely, the PNG stream is - * being embedded into another stream and doesn't need its own signature, - * we should call png_set_sig_bytes() to tell libpng how many of the - * bytes have already been written. - */ -void PNGAPI -png_write_sig(png_structrp png_ptr) -{ - png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that the signature is being written */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE; -#endif - - /* Write the rest of the 8 byte signature */ - png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], - (size_t)(8 - png_ptr->sig_bytes)); - - if (png_ptr->sig_bytes < 3) - png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; -} - -/* Write the start of a PNG chunk. The type is the chunk type. - * The total_length is the sum of the lengths of all the data you will be - * passing in png_write_chunk_data(). - */ -static void -png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name, - png_uint_32 length) -{ - png_byte buf[8]; - -#if defined(PNG_DEBUG) && (PNG_DEBUG > 0) - PNG_CSTRING_FROM_CHUNK(buf, chunk_name); - png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length); -#endif - - if (png_ptr == NULL) - return; - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that the chunk header is being written. - * PNG_IO_CHUNK_HDR requires a single I/O call. - */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR; -#endif - - /* Write the length and the chunk name */ - png_save_uint_32(buf, length); - png_save_uint_32(buf + 4, chunk_name); - png_write_data(png_ptr, buf, 8); - - /* Put the chunk name into png_ptr->chunk_name */ - png_ptr->chunk_name = chunk_name; - - /* Reset the crc and run it over the chunk name */ - png_reset_crc(png_ptr); - - png_calculate_crc(png_ptr, buf + 4, 4); - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that chunk data will (possibly) be written. - * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. - */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA; -#endif -} - -void PNGAPI -png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string, - png_uint_32 length) -{ - png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length); -} - -/* Write the data of a PNG chunk started with png_write_chunk_header(). - * Note that multiple calls to this function are allowed, and that the - * sum of the lengths from these calls *must* add up to the total_length - * given to png_write_chunk_header(). - */ -void PNGAPI -png_write_chunk_data(png_structrp png_ptr, png_const_bytep data, size_t length) -{ - /* Write the data, and run the CRC over it */ - if (png_ptr == NULL) - return; - - if (data != NULL && length > 0) - { - png_write_data(png_ptr, data, length); - - /* Update the CRC after writing the data, - * in case the user I/O routine alters it. - */ - png_calculate_crc(png_ptr, data, length); - } -} - -/* Finish a chunk started with png_write_chunk_header(). */ -void PNGAPI -png_write_chunk_end(png_structrp png_ptr) -{ - png_byte buf[4]; - - if (png_ptr == NULL) return; - -#ifdef PNG_IO_STATE_SUPPORTED - /* Inform the I/O callback that the chunk CRC is being written. - * PNG_IO_CHUNK_CRC requires a single I/O function call. - */ - png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC; -#endif - - /* Write the crc in a single operation */ - png_save_uint_32(buf, png_ptr->crc); - - png_write_data(png_ptr, buf, 4); -} - -/* Write a PNG chunk all at once. The type is an array of ASCII characters - * representing the chunk name. The array must be at least 4 bytes in - * length, and does not need to be null terminated. To be safe, pass the - * pre-defined chunk names here, and if you need a new one, define it - * where the others are defined. The length is the length of the data. - * All the data must be present. If that is not possible, use the - * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end() - * functions instead. - */ -static void -png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name, - png_const_bytep data, size_t length) -{ - if (png_ptr == NULL) - return; - - /* On 64-bit architectures 'length' may not fit in a png_uint_32. */ - if (length > PNG_UINT_31_MAX) - png_error(png_ptr, "length exceeds PNG maximum"); - - png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length); - png_write_chunk_data(png_ptr, data, length); - png_write_chunk_end(png_ptr); -} - -/* This is the API that calls the internal function above. */ -void PNGAPI -png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string, - png_const_bytep data, size_t length) -{ - png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, - length); -} - -/* This is used below to find the size of an image to pass to png_deflate_claim, - * so it only needs to be accurate if the size is less than 16384 bytes (the - * point at which a lower LZ window size can be used.) - */ -static png_alloc_size_t -png_image_size(png_structrp png_ptr) -{ - /* Only return sizes up to the maximum of a png_uint_32; do this by limiting - * the width and height used to 15 bits. - */ - png_uint_32 h = png_ptr->height; - - if (png_ptr->rowbytes < 32768 && h < 32768) - { - if (png_ptr->interlaced != 0) - { - /* Interlacing makes the image larger because of the replication of - * both the filter byte and the padding to a byte boundary. - */ - png_uint_32 w = png_ptr->width; - unsigned int pd = png_ptr->pixel_depth; - png_alloc_size_t cb_base; - int pass; - - for (cb_base=0, pass=0; pass<=6; ++pass) - { - png_uint_32 pw = PNG_PASS_COLS(w, pass); - - if (pw > 0) - cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass); - } - - return cb_base; - } - - else - return (png_ptr->rowbytes+1) * h; - } - - else - return 0xffffffffU; -} - -#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED - /* This is the code to hack the first two bytes of the deflate stream (the - * deflate header) to correct the windowBits value to match the actual data - * size. Note that the second argument is the *uncompressed* size but the - * first argument is the *compressed* data (and it must be deflate - * compressed.) - */ -static void -optimize_cmf(png_bytep data, png_alloc_size_t data_size) -{ - /* Optimize the CMF field in the zlib stream. The resultant zlib stream is - * still compliant to the stream specification. - */ - if (data_size <= 16384) /* else windowBits must be 15 */ - { - unsigned int z_cmf = data[0]; /* zlib compression method and flags */ - - if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) - { - unsigned int z_cinfo; - unsigned int half_z_window_size; - - z_cinfo = z_cmf >> 4; - half_z_window_size = 1U << (z_cinfo + 7); - - if (data_size <= half_z_window_size) /* else no change */ - { - unsigned int tmp; - - do - { - half_z_window_size >>= 1; - --z_cinfo; - } - while (z_cinfo > 0 && data_size <= half_z_window_size); - - z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); - - data[0] = (png_byte)z_cmf; - tmp = data[1] & 0xe0; - tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; - data[1] = (png_byte)tmp; - } - } - } -} -#endif /* WRITE_OPTIMIZE_CMF */ - -/* Initialize the compressor for the appropriate type of compression. */ -static int -png_deflate_claim(png_structrp png_ptr, png_uint_32 owner, - png_alloc_size_t data_size) -{ - if (png_ptr->zowner != 0) - { -#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) - char msg[64]; - - PNG_STRING_FROM_CHUNK(msg, owner); - msg[4] = ':'; - msg[5] = ' '; - PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner); - /* So the message that results is " using zstream"; this is an - * internal error, but is very useful for debugging. i18n requirements - * are minimal. - */ - (void)png_safecat(msg, (sizeof msg), 10, " using zstream"); -#endif -#if PNG_RELEASE_BUILD - png_warning(png_ptr, msg); - - /* Attempt sane error recovery */ - if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */ - { - png_ptr->zstream.msg = PNGZ_MSG_CAST("in use by IDAT"); - return Z_STREAM_ERROR; - } - - png_ptr->zowner = 0; -#else - png_error(png_ptr, msg); -#endif - } - - { - int level = png_ptr->zlib_level; - int method = png_ptr->zlib_method; - int windowBits = png_ptr->zlib_window_bits; - int memLevel = png_ptr->zlib_mem_level; - int strategy; /* set below */ - int ret; /* zlib return code */ - - if (owner == png_IDAT) - { - if ((png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) != 0) - strategy = png_ptr->zlib_strategy; - - else if (png_ptr->do_filter != PNG_FILTER_NONE) - strategy = PNG_Z_DEFAULT_STRATEGY; - - else - strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY; - } - - else - { -#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED - level = png_ptr->zlib_text_level; - method = png_ptr->zlib_text_method; - windowBits = png_ptr->zlib_text_window_bits; - memLevel = png_ptr->zlib_text_mem_level; - strategy = png_ptr->zlib_text_strategy; -#else - /* If customization is not supported the values all come from the - * IDAT values except for the strategy, which is fixed to the - * default. (This is the pre-1.6.0 behavior too, although it was - * implemented in a very different way.) - */ - strategy = Z_DEFAULT_STRATEGY; -#endif - } - - /* Adjust 'windowBits' down if larger than 'data_size'; to stop this - * happening just pass 32768 as the data_size parameter. Notice that zlib - * requires an extra 262 bytes in the window in addition to the data to be - * able to see the whole of the data, so if data_size+262 takes us to the - * next windowBits size we need to fix up the value later. (Because even - * though deflate needs the extra window, inflate does not!) - */ - if (data_size <= 16384) - { - /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to - * work round a Microsoft Visual C misbehavior which, contrary to C-90, - * widens the result of the following shift to 64-bits if (and, - * apparently, only if) it is used in a test. - */ - unsigned int half_window_size = 1U << (windowBits-1); - - while (data_size + 262 <= half_window_size) - { - half_window_size >>= 1; - --windowBits; - } - } - - /* Check against the previous initialized values, if any. */ - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0 && - (png_ptr->zlib_set_level != level || - png_ptr->zlib_set_method != method || - png_ptr->zlib_set_window_bits != windowBits || - png_ptr->zlib_set_mem_level != memLevel || - png_ptr->zlib_set_strategy != strategy)) - { - if (deflateEnd(&png_ptr->zstream) != Z_OK) - png_warning(png_ptr, "deflateEnd failed (ignored)"); - - png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED; - } - - /* For safety clear out the input and output pointers (currently zlib - * doesn't use them on Init, but it might in the future). - */ - png_ptr->zstream.next_in = NULL; - png_ptr->zstream.avail_in = 0; - png_ptr->zstream.next_out = NULL; - png_ptr->zstream.avail_out = 0; - - /* Now initialize if required, setting the new parameters, otherwise just - * do a simple reset to the previous parameters. - */ - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0) - ret = deflateReset(&png_ptr->zstream); - - else - { - ret = deflateInit2(&png_ptr->zstream, level, method, windowBits, - memLevel, strategy); - - if (ret == Z_OK) - png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; - } - - /* The return code is from either deflateReset or deflateInit2; they have - * pretty much the same set of error codes. - */ - if (ret == Z_OK) - png_ptr->zowner = owner; - - else - png_zstream_error(png_ptr, ret); - - return ret; - } -} - -/* Clean up (or trim) a linked list of compression buffers. */ -void /* PRIVATE */ -png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp) -{ - png_compression_bufferp list = *listp; - - if (list != NULL) - { - *listp = NULL; - - do - { - png_compression_bufferp next = list->next; - - png_free(png_ptr, list); - list = next; - } - while (list != NULL); - } -} - -#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED -/* This pair of functions encapsulates the operation of (a) compressing a - * text string, and (b) issuing it later as a series of chunk data writes. - * The compression_state structure is shared context for these functions - * set up by the caller to allow access to the relevant local variables. - * - * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size - * temporary buffers. From 1.6.0 it is retained in png_struct so that it will - * be correctly freed in the event of a write error (previous implementations - * just leaked memory.) - */ -typedef struct -{ - png_const_bytep input; /* The uncompressed input data */ - png_alloc_size_t input_len; /* Its length */ - png_uint_32 output_len; /* Final compressed length */ - png_byte output[1024]; /* First block of output */ -} compression_state; - -static void -png_text_compress_init(compression_state *comp, png_const_bytep input, - png_alloc_size_t input_len) -{ - comp->input = input; - comp->input_len = input_len; - comp->output_len = 0; -} - -/* Compress the data in the compression state input */ -static int -png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name, - compression_state *comp, png_uint_32 prefix_len) -{ - int ret; - - /* To find the length of the output it is necessary to first compress the - * input. The result is buffered rather than using the two-pass algorithm - * that is used on the inflate side; deflate is assumed to be slower and a - * PNG writer is assumed to have more memory available than a PNG reader. - * - * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an - * upper limit on the output size, but it is always bigger than the input - * size so it is likely to be more efficient to use this linked-list - * approach. - */ - ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len); - - if (ret != Z_OK) - return ret; - - /* Set up the compression buffers, we need a loop here to avoid overflowing a - * uInt. Use ZLIB_IO_MAX to limit the input. The output is always limited - * by the output buffer size, so there is no need to check that. Since this - * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits - * in size. - */ - { - png_compression_bufferp *end = &png_ptr->zbuffer_list; - png_alloc_size_t input_len = comp->input_len; /* may be zero! */ - png_uint_32 output_len; - - /* zlib updates these for us: */ - png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input); - png_ptr->zstream.avail_in = 0; /* Set below */ - png_ptr->zstream.next_out = comp->output; - png_ptr->zstream.avail_out = (sizeof comp->output); - - output_len = png_ptr->zstream.avail_out; - - do - { - uInt avail_in = ZLIB_IO_MAX; - - if (avail_in > input_len) - avail_in = (uInt)input_len; - - input_len -= avail_in; - - png_ptr->zstream.avail_in = avail_in; - - if (png_ptr->zstream.avail_out == 0) - { - png_compression_buffer *next; - - /* Chunk data is limited to 2^31 bytes in length, so the prefix - * length must be counted here. - */ - if (output_len + prefix_len > PNG_UINT_31_MAX) - { - ret = Z_MEM_ERROR; - break; - } - - /* Need a new (malloc'ed) buffer, but there may be one present - * already. - */ - next = *end; - if (next == NULL) - { - next = png_voidcast(png_compression_bufferp, png_malloc_base - (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); - - if (next == NULL) - { - ret = Z_MEM_ERROR; - break; - } - - /* Link in this buffer (so that it will be freed later) */ - next->next = NULL; - *end = next; - } - - png_ptr->zstream.next_out = next->output; - png_ptr->zstream.avail_out = png_ptr->zbuffer_size; - output_len += png_ptr->zstream.avail_out; - - /* Move 'end' to the next buffer pointer. */ - end = &next->next; - } - - /* Compress the data */ - ret = deflate(&png_ptr->zstream, - input_len > 0 ? Z_NO_FLUSH : Z_FINISH); - - /* Claw back input data that was not consumed (because avail_in is - * reset above every time round the loop). - */ - input_len += png_ptr->zstream.avail_in; - png_ptr->zstream.avail_in = 0; /* safety */ - } - while (ret == Z_OK); - - /* There may be some space left in the last output buffer. This needs to - * be subtracted from output_len. - */ - output_len -= png_ptr->zstream.avail_out; - png_ptr->zstream.avail_out = 0; /* safety */ - comp->output_len = output_len; - - /* Now double check the output length, put in a custom message if it is - * too long. Otherwise ensure the z_stream::msg pointer is set to - * something. - */ - if (output_len + prefix_len >= PNG_UINT_31_MAX) - { - png_ptr->zstream.msg = PNGZ_MSG_CAST("compressed data too long"); - ret = Z_MEM_ERROR; - } - - else - png_zstream_error(png_ptr, ret); - - /* Reset zlib for another zTXt/iTXt or image data */ - png_ptr->zowner = 0; - - /* The only success case is Z_STREAM_END, input_len must be 0; if not this - * is an internal error. - */ - if (ret == Z_STREAM_END && input_len == 0) - { -#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED - /* Fix up the deflate header, if required */ - optimize_cmf(comp->output, comp->input_len); -#endif - /* But Z_OK is returned, not Z_STREAM_END; this allows the claim - * function above to return Z_STREAM_END on an error (though it never - * does in the current versions of zlib.) - */ - return Z_OK; - } - - else - return ret; - } -} - -/* Ship the compressed text out via chunk writes */ -static void -png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp) -{ - png_uint_32 output_len = comp->output_len; - png_const_bytep output = comp->output; - png_uint_32 avail = (sizeof comp->output); - png_compression_buffer *next = png_ptr->zbuffer_list; - - for (;;) - { - if (avail > output_len) - avail = output_len; - - png_write_chunk_data(png_ptr, output, avail); - - output_len -= avail; - - if (output_len == 0 || next == NULL) - break; - - avail = png_ptr->zbuffer_size; - output = next->output; - next = next->next; - } - - /* This is an internal error; 'next' must have been NULL! */ - if (output_len > 0) - png_error(png_ptr, "error writing ancillary chunked compressed data"); -} -#endif /* WRITE_COMPRESSED_TEXT */ - -/* Write the IHDR chunk, and update the png_struct with the necessary - * information. Note that the rest of this code depends upon this - * information being correct. - */ -void /* PRIVATE */ -png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height, - int bit_depth, int color_type, int compression_type, int filter_type, - int interlace_type) -{ - png_byte buf[13]; /* Buffer to store the IHDR info */ - int is_invalid_depth; - - png_debug(1, "in png_write_IHDR"); - - /* Check that we have valid input data from the application info */ - switch (color_type) - { - case PNG_COLOR_TYPE_GRAY: - switch (bit_depth) - { - case 1: - case 2: - case 4: - case 8: -#ifdef PNG_WRITE_16BIT_SUPPORTED - case 16: -#endif - png_ptr->channels = 1; break; - - default: - png_error(png_ptr, - "Invalid bit depth for grayscale image"); - } - break; - - case PNG_COLOR_TYPE_RGB: - is_invalid_depth = (bit_depth != 8); -#ifdef PNG_WRITE_16BIT_SUPPORTED - is_invalid_depth = (is_invalid_depth && bit_depth != 16); -#endif - if (is_invalid_depth) - png_error(png_ptr, "Invalid bit depth for RGB image"); - - png_ptr->channels = 3; - break; - - case PNG_COLOR_TYPE_PALETTE: - switch (bit_depth) - { - case 1: - case 2: - case 4: - case 8: - png_ptr->channels = 1; - break; - - default: - png_error(png_ptr, "Invalid bit depth for paletted image"); - } - break; - - case PNG_COLOR_TYPE_GRAY_ALPHA: - is_invalid_depth = (bit_depth != 8); -#ifdef PNG_WRITE_16BIT_SUPPORTED - is_invalid_depth = (is_invalid_depth && bit_depth != 16); -#endif - if (is_invalid_depth) - png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); - - png_ptr->channels = 2; - break; - - case PNG_COLOR_TYPE_RGB_ALPHA: - is_invalid_depth = (bit_depth != 8); -#ifdef PNG_WRITE_16BIT_SUPPORTED - is_invalid_depth = (is_invalid_depth && bit_depth != 16); -#endif - if (is_invalid_depth) - png_error(png_ptr, "Invalid bit depth for RGBA image"); - - png_ptr->channels = 4; - break; - - default: - png_error(png_ptr, "Invalid image color type specified"); - } - - if (compression_type != PNG_COMPRESSION_TYPE_BASE) - { - png_warning(png_ptr, "Invalid compression type specified"); - compression_type = PNG_COMPRESSION_TYPE_BASE; - } - - /* Write filter_method 64 (intrapixel differencing) only if - * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and - * 2. Libpng did not write a PNG signature (this filter_method is only - * used in PNG datastreams that are embedded in MNG datastreams) and - * 3. The application called png_permit_mng_features with a mask that - * included PNG_FLAG_MNG_FILTER_64 and - * 4. The filter_method is 64 and - * 5. The color_type is RGB or RGBA - */ - if ( -#ifdef PNG_MNG_FEATURES_SUPPORTED - !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 && - ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && - (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_RGB_ALPHA) && - (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && -#endif - filter_type != PNG_FILTER_TYPE_BASE) - { - png_warning(png_ptr, "Invalid filter type specified"); - filter_type = PNG_FILTER_TYPE_BASE; - } - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - if (interlace_type != PNG_INTERLACE_NONE && - interlace_type != PNG_INTERLACE_ADAM7) - { - png_warning(png_ptr, "Invalid interlace type specified"); - interlace_type = PNG_INTERLACE_ADAM7; - } -#else - interlace_type=PNG_INTERLACE_NONE; -#endif - - /* Save the relevant information */ - png_ptr->bit_depth = (png_byte)bit_depth; - png_ptr->color_type = (png_byte)color_type; - png_ptr->interlaced = (png_byte)interlace_type; -#ifdef PNG_MNG_FEATURES_SUPPORTED - png_ptr->filter_type = (png_byte)filter_type; -#endif - png_ptr->compression_type = (png_byte)compression_type; - png_ptr->width = width; - png_ptr->height = height; - - png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels); - png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); - /* Set the usr info, so any transformations can modify it */ - png_ptr->usr_width = png_ptr->width; - png_ptr->usr_bit_depth = png_ptr->bit_depth; - png_ptr->usr_channels = png_ptr->channels; - - /* Pack the header information into the buffer */ - png_save_uint_32(buf, width); - png_save_uint_32(buf + 4, height); - buf[8] = (png_byte)bit_depth; - buf[9] = (png_byte)color_type; - buf[10] = (png_byte)compression_type; - buf[11] = (png_byte)filter_type; - buf[12] = (png_byte)interlace_type; - - /* Write the chunk */ - png_write_complete_chunk(png_ptr, png_IHDR, buf, 13); - - if ((png_ptr->do_filter) == PNG_NO_FILTERS) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || - png_ptr->bit_depth < 8) - png_ptr->do_filter = PNG_FILTER_NONE; - - else - png_ptr->do_filter = PNG_ALL_FILTERS; - } - - png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */ -} - -/* Write the palette. We are careful not to trust png_color to be in the - * correct order for PNG, so people can redefine it to any convenient - * structure. - */ -void /* PRIVATE */ -png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, - png_uint_32 num_pal) -{ - png_uint_32 max_palette_length, i; - png_const_colorp pal_ptr; - png_byte buf[3]; - - png_debug(1, "in png_write_PLTE"); - - max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? - (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; - - if (( -#ifdef PNG_MNG_FEATURES_SUPPORTED - (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 && -#endif - num_pal == 0) || num_pal > max_palette_length) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - png_error(png_ptr, "Invalid number of colors in palette"); - } - - else - { - png_warning(png_ptr, "Invalid number of colors in palette"); - return; - } - } - - if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) - { - png_warning(png_ptr, - "Ignoring request to write a PLTE chunk in grayscale PNG"); - - return; - } - - png_ptr->num_palette = (png_uint_16)num_pal; - png_debug1(3, "num_palette = %d", png_ptr->num_palette); - - png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); -#ifdef PNG_POINTER_INDEXING_SUPPORTED - - for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) - { - buf[0] = pal_ptr->red; - buf[1] = pal_ptr->green; - buf[2] = pal_ptr->blue; - png_write_chunk_data(png_ptr, buf, 3); - } - -#else - /* This is a little slower but some buggy compilers need to do this - * instead - */ - pal_ptr=palette; - - for (i = 0; i < num_pal; i++) - { - buf[0] = pal_ptr[i].red; - buf[1] = pal_ptr[i].green; - buf[2] = pal_ptr[i].blue; - png_write_chunk_data(png_ptr, buf, 3); - } - -#endif - png_write_chunk_end(png_ptr); - png_ptr->mode |= PNG_HAVE_PLTE; -} - -/* This is similar to png_text_compress, above, except that it does not require - * all of the data at once and, instead of buffering the compressed result, - * writes it as IDAT chunks. Unlike png_text_compress it *can* png_error out - * because it calls the write interface. As a result it does its own error - * reporting and does not return an error code. In the event of error it will - * just call png_error. The input data length may exceed 32-bits. The 'flush' - * parameter is exactly the same as that to deflate, with the following - * meanings: - * - * Z_NO_FLUSH: normal incremental output of compressed data - * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush - * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up - * - * The routine manages the acquire and release of the png_ptr->zstream by - * checking and (at the end) clearing png_ptr->zowner; it does some sanity - * checks on the 'mode' flags while doing this. - */ -void /* PRIVATE */ -png_compress_IDAT(png_structrp png_ptr, png_const_bytep input, - png_alloc_size_t input_len, int flush) -{ - if (png_ptr->zowner != png_IDAT) - { - /* First time. Ensure we have a temporary buffer for compression and - * trim the buffer list if it has more than one entry to free memory. - * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been - * created at this point, but the check here is quick and safe. - */ - if (png_ptr->zbuffer_list == NULL) - { - png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp, - png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr))); - png_ptr->zbuffer_list->next = NULL; - } - - else - png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next); - - /* It is a terminal error if we can't claim the zstream. */ - if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK) - png_error(png_ptr, png_ptr->zstream.msg); - - /* The output state is maintained in png_ptr->zstream, so it must be - * initialized here after the claim. - */ - png_ptr->zstream.next_out = png_ptr->zbuffer_list->output; - png_ptr->zstream.avail_out = png_ptr->zbuffer_size; - } - - /* Now loop reading and writing until all the input is consumed or an error - * terminates the operation. The _out values are maintained across calls to - * this function, but the input must be reset each time. - */ - png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input); - png_ptr->zstream.avail_in = 0; /* set below */ - for (;;) - { - int ret; - - /* INPUT: from the row data */ - uInt avail = ZLIB_IO_MAX; - - if (avail > input_len) - avail = (uInt)input_len; /* safe because of the check */ - - png_ptr->zstream.avail_in = avail; - input_len -= avail; - - ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush); - - /* Include as-yet unconsumed input */ - input_len += png_ptr->zstream.avail_in; - png_ptr->zstream.avail_in = 0; - - /* OUTPUT: write complete IDAT chunks when avail_out drops to zero. Note - * that these two zstream fields are preserved across the calls, therefore - * there is no need to set these up on entry to the loop. - */ - if (png_ptr->zstream.avail_out == 0) - { - png_bytep data = png_ptr->zbuffer_list->output; - uInt size = png_ptr->zbuffer_size; - - /* Write an IDAT containing the data then reset the buffer. The - * first IDAT may need deflate header optimization. - */ -#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED - if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && - png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) - optimize_cmf(data, png_image_size(png_ptr)); -#endif - - if (size > 0) - png_write_complete_chunk(png_ptr, png_IDAT, data, size); - png_ptr->mode |= PNG_HAVE_IDAT; - - png_ptr->zstream.next_out = data; - png_ptr->zstream.avail_out = size; - - /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with - * the same flush parameter until it has finished output, for NO_FLUSH - * it doesn't matter. - */ - if (ret == Z_OK && flush != Z_NO_FLUSH) - continue; - } - - /* The order of these checks doesn't matter much; it just affects which - * possible error might be detected if multiple things go wrong at once. - */ - if (ret == Z_OK) /* most likely return code! */ - { - /* If all the input has been consumed then just return. If Z_FINISH - * was used as the flush parameter something has gone wrong if we get - * here. - */ - if (input_len == 0) - { - if (flush == Z_FINISH) - png_error(png_ptr, "Z_OK on Z_FINISH with output space"); - - return; - } - } - - else if (ret == Z_STREAM_END && flush == Z_FINISH) - { - /* This is the end of the IDAT data; any pending output must be - * flushed. For small PNG files we may still be at the beginning. - */ - png_bytep data = png_ptr->zbuffer_list->output; - uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out; - -#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED - if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 && - png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) - optimize_cmf(data, png_image_size(png_ptr)); -#endif - - if (size > 0) - png_write_complete_chunk(png_ptr, png_IDAT, data, size); - png_ptr->zstream.avail_out = 0; - png_ptr->zstream.next_out = NULL; - png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT; - - png_ptr->zowner = 0; /* Release the stream */ - return; - } - - else - { - /* This is an error condition. */ - png_zstream_error(png_ptr, ret); - png_error(png_ptr, png_ptr->zstream.msg); - } - } -} - -/* Write an IEND chunk */ -void /* PRIVATE */ -png_write_IEND(png_structrp png_ptr) -{ - png_debug(1, "in png_write_IEND"); - - png_write_complete_chunk(png_ptr, png_IEND, NULL, 0); - png_ptr->mode |= PNG_HAVE_IEND; -} - -#ifdef PNG_WRITE_gAMA_SUPPORTED -/* Write a gAMA chunk */ -void /* PRIVATE */ -png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma) -{ - png_byte buf[4]; - - png_debug(1, "in png_write_gAMA"); - - /* file_gamma is saved in 1/100,000ths */ - png_save_uint_32(buf, (png_uint_32)file_gamma); - png_write_complete_chunk(png_ptr, png_gAMA, buf, 4); -} -#endif - -#ifdef PNG_WRITE_sRGB_SUPPORTED -/* Write a sRGB chunk */ -void /* PRIVATE */ -png_write_sRGB(png_structrp png_ptr, int srgb_intent) -{ - png_byte buf[1]; - - png_debug(1, "in png_write_sRGB"); - - if (srgb_intent >= PNG_sRGB_INTENT_LAST) - png_warning(png_ptr, - "Invalid sRGB rendering intent specified"); - - buf[0]=(png_byte)srgb_intent; - png_write_complete_chunk(png_ptr, png_sRGB, buf, 1); -} -#endif - -#ifdef PNG_WRITE_iCCP_SUPPORTED -/* Write an iCCP chunk */ -void /* PRIVATE */ -png_write_iCCP(png_structrp png_ptr, png_const_charp name, - png_const_bytep profile) -{ - png_uint_32 name_len; - png_uint_32 profile_len; - png_byte new_name[81]; /* 1 byte for the compression byte */ - compression_state comp; - png_uint_32 temp; - - png_debug(1, "in png_write_iCCP"); - - /* These are all internal problems: the profile should have been checked - * before when it was stored. - */ - if (profile == NULL) - png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */ - - profile_len = png_get_uint_32(profile); - - if (profile_len < 132) - png_error(png_ptr, "ICC profile too short"); - - temp = (png_uint_32) (*(profile+8)); - if (temp > 3 && (profile_len & 0x03)) - png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)"); - - { - png_uint_32 embedded_profile_len = png_get_uint_32(profile); - - if (profile_len != embedded_profile_len) - png_error(png_ptr, "Profile length does not match profile"); - } - - name_len = png_check_keyword(png_ptr, name, new_name); - - if (name_len == 0) - png_error(png_ptr, "iCCP: invalid keyword"); - - new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE; - - /* Make sure we include the NULL after the name and the compression type */ - ++name_len; - - png_text_compress_init(&comp, profile, profile_len); - - /* Allow for keyword terminator and compression byte */ - if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK) - png_error(png_ptr, png_ptr->zstream.msg); - - png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len); - - png_write_chunk_data(png_ptr, new_name, name_len); - - png_write_compressed_data_out(png_ptr, &comp); - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_sPLT_SUPPORTED -/* Write a sPLT chunk */ -void /* PRIVATE */ -png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette) -{ - png_uint_32 name_len; - png_byte new_name[80]; - png_byte entrybuf[10]; - size_t entry_size = (spalette->depth == 8 ? 6 : 10); - size_t palette_size = entry_size * (size_t)spalette->nentries; - png_sPLT_entryp ep; -#ifndef PNG_POINTER_INDEXING_SUPPORTED - int i; -#endif - - png_debug(1, "in png_write_sPLT"); - - name_len = png_check_keyword(png_ptr, spalette->name, new_name); - - if (name_len == 0) - png_error(png_ptr, "sPLT: invalid keyword"); - - /* Make sure we include the NULL after the name */ - png_write_chunk_header(png_ptr, png_sPLT, - (png_uint_32)(name_len + 2 + palette_size)); - - png_write_chunk_data(png_ptr, (png_bytep)new_name, (size_t)(name_len + 1)); - - png_write_chunk_data(png_ptr, &spalette->depth, 1); - - /* Loop through each palette entry, writing appropriately */ -#ifdef PNG_POINTER_INDEXING_SUPPORTED - for (ep = spalette->entries; epentries + spalette->nentries; ep++) - { - if (spalette->depth == 8) - { - entrybuf[0] = (png_byte)ep->red; - entrybuf[1] = (png_byte)ep->green; - entrybuf[2] = (png_byte)ep->blue; - entrybuf[3] = (png_byte)ep->alpha; - png_save_uint_16(entrybuf + 4, ep->frequency); - } - - else - { - png_save_uint_16(entrybuf + 0, ep->red); - png_save_uint_16(entrybuf + 2, ep->green); - png_save_uint_16(entrybuf + 4, ep->blue); - png_save_uint_16(entrybuf + 6, ep->alpha); - png_save_uint_16(entrybuf + 8, ep->frequency); - } - - png_write_chunk_data(png_ptr, entrybuf, entry_size); - } -#else - ep=spalette->entries; - for (i = 0; i>spalette->nentries; i++) - { - if (spalette->depth == 8) - { - entrybuf[0] = (png_byte)ep[i].red; - entrybuf[1] = (png_byte)ep[i].green; - entrybuf[2] = (png_byte)ep[i].blue; - entrybuf[3] = (png_byte)ep[i].alpha; - png_save_uint_16(entrybuf + 4, ep[i].frequency); - } - - else - { - png_save_uint_16(entrybuf + 0, ep[i].red); - png_save_uint_16(entrybuf + 2, ep[i].green); - png_save_uint_16(entrybuf + 4, ep[i].blue); - png_save_uint_16(entrybuf + 6, ep[i].alpha); - png_save_uint_16(entrybuf + 8, ep[i].frequency); - } - - png_write_chunk_data(png_ptr, entrybuf, entry_size); - } -#endif - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_sBIT_SUPPORTED -/* Write the sBIT chunk */ -void /* PRIVATE */ -png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type) -{ - png_byte buf[4]; - size_t size; - - png_debug(1, "in png_write_sBIT"); - - /* Make sure we don't depend upon the order of PNG_COLOR_8 */ - if ((color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_byte maxbits; - - maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 : - png_ptr->usr_bit_depth); - - if (sbit->red == 0 || sbit->red > maxbits || - sbit->green == 0 || sbit->green > maxbits || - sbit->blue == 0 || sbit->blue > maxbits) - { - png_warning(png_ptr, "Invalid sBIT depth specified"); - return; - } - - buf[0] = sbit->red; - buf[1] = sbit->green; - buf[2] = sbit->blue; - size = 3; - } - - else - { - if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth) - { - png_warning(png_ptr, "Invalid sBIT depth specified"); - return; - } - - buf[0] = sbit->gray; - size = 1; - } - - if ((color_type & PNG_COLOR_MASK_ALPHA) != 0) - { - if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth) - { - png_warning(png_ptr, "Invalid sBIT depth specified"); - return; - } - - buf[size++] = sbit->alpha; - } - - png_write_complete_chunk(png_ptr, png_sBIT, buf, size); -} -#endif - -#ifdef PNG_WRITE_cHRM_SUPPORTED -/* Write the cHRM chunk */ -void /* PRIVATE */ -png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy) -{ - png_byte buf[32]; - - png_debug(1, "in png_write_cHRM"); - - /* Each value is saved in 1/100,000ths */ - png_save_int_32(buf, xy->whitex); - png_save_int_32(buf + 4, xy->whitey); - - png_save_int_32(buf + 8, xy->redx); - png_save_int_32(buf + 12, xy->redy); - - png_save_int_32(buf + 16, xy->greenx); - png_save_int_32(buf + 20, xy->greeny); - - png_save_int_32(buf + 24, xy->bluex); - png_save_int_32(buf + 28, xy->bluey); - - png_write_complete_chunk(png_ptr, png_cHRM, buf, 32); -} -#endif - -#ifdef PNG_WRITE_tRNS_SUPPORTED -/* Write the tRNS chunk */ -void /* PRIVATE */ -png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, - png_const_color_16p tran, int num_trans, int color_type) -{ - png_byte buf[6]; - - png_debug(1, "in png_write_tRNS"); - - if (color_type == PNG_COLOR_TYPE_PALETTE) - { - if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) - { - png_app_warning(png_ptr, - "Invalid number of transparent colors specified"); - return; - } - - /* Write the chunk out as it is */ - png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, - (size_t)num_trans); - } - - else if (color_type == PNG_COLOR_TYPE_GRAY) - { - /* One 16-bit value */ - if (tran->gray >= (1 << png_ptr->bit_depth)) - { - png_app_warning(png_ptr, - "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); - - return; - } - - png_save_uint_16(buf, tran->gray); - png_write_complete_chunk(png_ptr, png_tRNS, buf, 2); - } - - else if (color_type == PNG_COLOR_TYPE_RGB) - { - /* Three 16-bit values */ - png_save_uint_16(buf, tran->red); - png_save_uint_16(buf + 2, tran->green); - png_save_uint_16(buf + 4, tran->blue); -#ifdef PNG_WRITE_16BIT_SUPPORTED - if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) -#else - if ((buf[0] | buf[2] | buf[4]) != 0) -#endif - { - png_app_warning(png_ptr, - "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); - return; - } - - png_write_complete_chunk(png_ptr, png_tRNS, buf, 6); - } - - else - { - png_app_warning(png_ptr, "Can't write tRNS with an alpha channel"); - } -} -#endif - -#ifdef PNG_WRITE_bKGD_SUPPORTED -/* Write the background chunk */ -void /* PRIVATE */ -png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type) -{ - png_byte buf[6]; - - png_debug(1, "in png_write_bKGD"); - - if (color_type == PNG_COLOR_TYPE_PALETTE) - { - if ( -#ifdef PNG_MNG_FEATURES_SUPPORTED - (png_ptr->num_palette != 0 || - (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0) && -#endif - back->index >= png_ptr->num_palette) - { - png_warning(png_ptr, "Invalid background palette index"); - return; - } - - buf[0] = back->index; - png_write_complete_chunk(png_ptr, png_bKGD, buf, 1); - } - - else if ((color_type & PNG_COLOR_MASK_COLOR) != 0) - { - png_save_uint_16(buf, back->red); - png_save_uint_16(buf + 2, back->green); - png_save_uint_16(buf + 4, back->blue); -#ifdef PNG_WRITE_16BIT_SUPPORTED - if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0) -#else - if ((buf[0] | buf[2] | buf[4]) != 0) -#endif - { - png_warning(png_ptr, - "Ignoring attempt to write 16-bit bKGD chunk " - "when bit_depth is 8"); - - return; - } - - png_write_complete_chunk(png_ptr, png_bKGD, buf, 6); - } - - else - { - if (back->gray >= (1 << png_ptr->bit_depth)) - { - png_warning(png_ptr, - "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); - - return; - } - - png_save_uint_16(buf, back->gray); - png_write_complete_chunk(png_ptr, png_bKGD, buf, 2); - } -} -#endif - -#ifdef PNG_WRITE_eXIf_SUPPORTED -/* Write the Exif data */ -void /* PRIVATE */ -png_write_eXIf(png_structrp png_ptr, png_bytep exif, int num_exif) -{ - int i; - png_byte buf[1]; - - png_debug(1, "in png_write_eXIf"); - - png_write_chunk_header(png_ptr, png_eXIf, (png_uint_32)(num_exif)); - - for (i = 0; i < num_exif; i++) - { - buf[0] = exif[i]; - png_write_chunk_data(png_ptr, buf, 1); - } - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_hIST_SUPPORTED -/* Write the histogram */ -void /* PRIVATE */ -png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist) -{ - int i; - png_byte buf[3]; - - png_debug(1, "in png_write_hIST"); - - if (num_hist > (int)png_ptr->num_palette) - { - png_debug2(3, "num_hist = %d, num_palette = %d", num_hist, - png_ptr->num_palette); - - png_warning(png_ptr, "Invalid number of histogram entries specified"); - return; - } - - png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); - - for (i = 0; i < num_hist; i++) - { - png_save_uint_16(buf, hist[i]); - png_write_chunk_data(png_ptr, buf, 2); - } - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_tEXt_SUPPORTED -/* Write a tEXt chunk */ -void /* PRIVATE */ -png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, - size_t text_len) -{ - png_uint_32 key_len; - png_byte new_key[80]; - - png_debug(1, "in png_write_tEXt"); - - key_len = png_check_keyword(png_ptr, key, new_key); - - if (key_len == 0) - png_error(png_ptr, "tEXt: invalid keyword"); - - if (text == NULL || *text == '\0') - text_len = 0; - - else - text_len = strlen(text); - - if (text_len > PNG_UINT_31_MAX - (key_len+1)) - png_error(png_ptr, "tEXt: text too long"); - - /* Make sure we include the 0 after the key */ - png_write_chunk_header(png_ptr, png_tEXt, - (png_uint_32)/*checked above*/(key_len + text_len + 1)); - /* - * We leave it to the application to meet PNG-1.0 requirements on the - * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of - * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. - * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. - */ - png_write_chunk_data(png_ptr, new_key, key_len + 1); - - if (text_len != 0) - png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len); - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_zTXt_SUPPORTED -/* Write a compressed text chunk */ -void /* PRIVATE */ -png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, - int compression) -{ - png_uint_32 key_len; - png_byte new_key[81]; - compression_state comp; - - png_debug(1, "in png_write_zTXt"); - - if (compression == PNG_TEXT_COMPRESSION_NONE) - { - png_write_tEXt(png_ptr, key, text, 0); - return; - } - - if (compression != PNG_TEXT_COMPRESSION_zTXt) - png_error(png_ptr, "zTXt: invalid compression type"); - - key_len = png_check_keyword(png_ptr, key, new_key); - - if (key_len == 0) - png_error(png_ptr, "zTXt: invalid keyword"); - - /* Add the compression method and 1 for the keyword separator. */ - new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; - ++key_len; - - /* Compute the compressed data; do it now for the length */ - png_text_compress_init(&comp, (png_const_bytep)text, - text == NULL ? 0 : strlen(text)); - - if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK) - png_error(png_ptr, png_ptr->zstream.msg); - - /* Write start of chunk */ - png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len); - - /* Write key */ - png_write_chunk_data(png_ptr, new_key, key_len); - - /* Write the compressed data */ - png_write_compressed_data_out(png_ptr, &comp); - - /* Close the chunk */ - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_iTXt_SUPPORTED -/* Write an iTXt chunk */ -void /* PRIVATE */ -png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key, - png_const_charp lang, png_const_charp lang_key, png_const_charp text) -{ - png_uint_32 key_len, prefix_len; - size_t lang_len, lang_key_len; - png_byte new_key[82]; - compression_state comp; - - png_debug(1, "in png_write_iTXt"); - - key_len = png_check_keyword(png_ptr, key, new_key); - - if (key_len == 0) - png_error(png_ptr, "iTXt: invalid keyword"); - - /* Set the compression flag */ - switch (compression) - { - case PNG_ITXT_COMPRESSION_NONE: - case PNG_TEXT_COMPRESSION_NONE: - compression = new_key[++key_len] = 0; /* no compression */ - break; - - case PNG_TEXT_COMPRESSION_zTXt: - case PNG_ITXT_COMPRESSION_zTXt: - compression = new_key[++key_len] = 1; /* compressed */ - break; - - default: - png_error(png_ptr, "iTXt: invalid compression"); - } - - new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE; - ++key_len; /* for the keywod separator */ - - /* We leave it to the application to meet PNG-1.0 requirements on the - * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of - * any non-Latin-1 characters except for NEWLINE. ISO PNG, however, - * specifies that the text is UTF-8 and this really doesn't require any - * checking. - * - * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. - * - * TODO: validate the language tag correctly (see the spec.) - */ - if (lang == NULL) lang = ""; /* empty language is valid */ - lang_len = strlen(lang)+1; - if (lang_key == NULL) lang_key = ""; /* may be empty */ - lang_key_len = strlen(lang_key)+1; - if (text == NULL) text = ""; /* may be empty */ - - prefix_len = key_len; - if (lang_len > PNG_UINT_31_MAX-prefix_len) - prefix_len = PNG_UINT_31_MAX; - else - prefix_len = (png_uint_32)(prefix_len + lang_len); - - if (lang_key_len > PNG_UINT_31_MAX-prefix_len) - prefix_len = PNG_UINT_31_MAX; - else - prefix_len = (png_uint_32)(prefix_len + lang_key_len); - - png_text_compress_init(&comp, (png_const_bytep)text, strlen(text)); - - if (compression != 0) - { - if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK) - png_error(png_ptr, png_ptr->zstream.msg); - } - - else - { - if (comp.input_len > PNG_UINT_31_MAX-prefix_len) - png_error(png_ptr, "iTXt: uncompressed text too long"); - - /* So the string will fit in a chunk: */ - comp.output_len = (png_uint_32)/*SAFE*/comp.input_len; - } - - png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len); - - png_write_chunk_data(png_ptr, new_key, key_len); - - png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len); - - png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len); - - if (compression != 0) - png_write_compressed_data_out(png_ptr, &comp); - - else - png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.output_len); - - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_oFFs_SUPPORTED -/* Write the oFFs chunk */ -void /* PRIVATE */ -png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset, - int unit_type) -{ - png_byte buf[9]; - - png_debug(1, "in png_write_oFFs"); - - if (unit_type >= PNG_OFFSET_LAST) - png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); - - png_save_int_32(buf, x_offset); - png_save_int_32(buf + 4, y_offset); - buf[8] = (png_byte)unit_type; - - png_write_complete_chunk(png_ptr, png_oFFs, buf, 9); -} -#endif -#ifdef PNG_WRITE_pCAL_SUPPORTED -/* Write the pCAL chunk (described in the PNG extensions document) */ -void /* PRIVATE */ -png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0, - png_int_32 X1, int type, int nparams, png_const_charp units, - png_charpp params) -{ - png_uint_32 purpose_len; - size_t units_len, total_len; - png_size_tp params_len; - png_byte buf[10]; - png_byte new_purpose[80]; - int i; - - png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); - - if (type >= PNG_EQUATION_LAST) - png_error(png_ptr, "Unrecognized equation type for pCAL chunk"); - - purpose_len = png_check_keyword(png_ptr, purpose, new_purpose); - - if (purpose_len == 0) - png_error(png_ptr, "pCAL: invalid keyword"); - - ++purpose_len; /* terminator */ - - png_debug1(3, "pCAL purpose length = %d", (int)purpose_len); - units_len = strlen(units) + (nparams == 0 ? 0 : 1); - png_debug1(3, "pCAL units length = %d", (int)units_len); - total_len = purpose_len + units_len + 10; - - params_len = (png_size_tp)png_malloc(png_ptr, - (png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (size_t)))); - - /* Find the length of each parameter, making sure we don't count the - * null terminator for the last parameter. - */ - for (i = 0; i < nparams; i++) - { - params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1); - png_debug2(3, "pCAL parameter %d length = %lu", i, - (unsigned long)params_len[i]); - total_len += params_len[i]; - } - - png_debug1(3, "pCAL total length = %d", (int)total_len); - png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len); - png_write_chunk_data(png_ptr, new_purpose, purpose_len); - png_save_int_32(buf, X0); - png_save_int_32(buf + 4, X1); - buf[8] = (png_byte)type; - buf[9] = (png_byte)nparams; - png_write_chunk_data(png_ptr, buf, 10); - png_write_chunk_data(png_ptr, (png_const_bytep)units, (size_t)units_len); - - for (i = 0; i < nparams; i++) - { - png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]); - } - - png_free(png_ptr, params_len); - png_write_chunk_end(png_ptr); -} -#endif - -#ifdef PNG_WRITE_sCAL_SUPPORTED -/* Write the sCAL chunk */ -void /* PRIVATE */ -png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width, - png_const_charp height) -{ - png_byte buf[64]; - size_t wlen, hlen, total_len; - - png_debug(1, "in png_write_sCAL_s"); - - wlen = strlen(width); - hlen = strlen(height); - total_len = wlen + hlen + 2; - - if (total_len > 64) - { - png_warning(png_ptr, "Can't write sCAL (buffer too small)"); - return; - } - - buf[0] = (png_byte)unit; - memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ - memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ - - png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); - png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len); -} -#endif - -#ifdef PNG_WRITE_pHYs_SUPPORTED -/* Write the pHYs chunk */ -void /* PRIVATE */ -png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit, - png_uint_32 y_pixels_per_unit, - int unit_type) -{ - png_byte buf[9]; - - png_debug(1, "in png_write_pHYs"); - - if (unit_type >= PNG_RESOLUTION_LAST) - png_warning(png_ptr, "Unrecognized unit type for pHYs chunk"); - - png_save_uint_32(buf, x_pixels_per_unit); - png_save_uint_32(buf + 4, y_pixels_per_unit); - buf[8] = (png_byte)unit_type; - - png_write_complete_chunk(png_ptr, png_pHYs, buf, 9); -} -#endif - -#ifdef PNG_WRITE_tIME_SUPPORTED -/* Write the tIME chunk. Use either png_convert_from_struct_tm() - * or png_convert_from_time_t(), or fill in the structure yourself. - */ -void /* PRIVATE */ -png_write_tIME(png_structrp png_ptr, png_const_timep mod_time) -{ - png_byte buf[7]; - - png_debug(1, "in png_write_tIME"); - - if (mod_time->month > 12 || mod_time->month < 1 || - mod_time->day > 31 || mod_time->day < 1 || - mod_time->hour > 23 || mod_time->second > 60) - { - png_warning(png_ptr, "Invalid time specified for tIME chunk"); - return; - } - - png_save_uint_16(buf, mod_time->year); - buf[2] = mod_time->month; - buf[3] = mod_time->day; - buf[4] = mod_time->hour; - buf[5] = mod_time->minute; - buf[6] = mod_time->second; - - png_write_complete_chunk(png_ptr, png_tIME, buf, 7); -} -#endif - -/* Initializes the row writing capability of libpng */ -void /* PRIVATE */ -png_write_start_row(png_structrp png_ptr) -{ -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; -#endif - - png_alloc_size_t buf_size; - int usr_pixel_depth; - -#ifdef PNG_WRITE_FILTER_SUPPORTED - png_byte filters; -#endif - - png_debug(1, "in png_write_start_row"); - - usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth; - buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1; - - /* 1.5.6: added to allow checking in the row write code. */ - png_ptr->transformed_pixel_depth = png_ptr->pixel_depth; - png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth; - - /* Set up row buffer */ - png_ptr->row_buf = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); - - png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; - -#ifdef PNG_WRITE_FILTER_SUPPORTED - filters = png_ptr->do_filter; - - if (png_ptr->height == 1) - filters &= 0xff & ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH); - - if (png_ptr->width == 1) - filters &= 0xff & ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH); - - if (filters == 0) - filters = PNG_FILTER_NONE; - - png_ptr->do_filter = filters; - - if (((filters & (PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG | - PNG_FILTER_PAETH)) != 0) && png_ptr->try_row == NULL) - { - int num_filters = 0; - - png_ptr->try_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size)); - - if (filters & PNG_FILTER_SUB) - num_filters++; - - if (filters & PNG_FILTER_UP) - num_filters++; - - if (filters & PNG_FILTER_AVG) - num_filters++; - - if (filters & PNG_FILTER_PAETH) - num_filters++; - - if (num_filters > 1) - png_ptr->tst_row = png_voidcast(png_bytep, png_malloc(png_ptr, - buf_size)); - } - - /* We only need to keep the previous row if we are using one of the following - * filters. - */ - if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0) - png_ptr->prev_row = png_voidcast(png_bytep, - png_calloc(png_ptr, buf_size)); -#endif /* WRITE_FILTER */ - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* If interlaced, we need to set up width and height of pass */ - if (png_ptr->interlaced != 0) - { - if ((png_ptr->transformations & PNG_INTERLACE) == 0) - { - png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - - png_pass_ystart[0]) / png_pass_yinc[0]; - - png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 - - png_pass_start[0]) / png_pass_inc[0]; - } - - else - { - png_ptr->num_rows = png_ptr->height; - png_ptr->usr_width = png_ptr->width; - } - } - - else -#endif - { - png_ptr->num_rows = png_ptr->height; - png_ptr->usr_width = png_ptr->width; - } -} - -/* Internal use only. Called when finished processing a row of data. */ -void /* PRIVATE */ -png_write_finish_row(png_structrp png_ptr) -{ -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; -#endif - - png_debug(1, "in png_write_finish_row"); - - /* Next row */ - png_ptr->row_number++; - - /* See if we are done */ - if (png_ptr->row_number < png_ptr->num_rows) - return; - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* If interlaced, go to next pass */ - if (png_ptr->interlaced != 0) - { - png_ptr->row_number = 0; - if ((png_ptr->transformations & PNG_INTERLACE) != 0) - { - png_ptr->pass++; - } - - else - { - /* Loop until we find a non-zero width or height pass */ - do - { - png_ptr->pass++; - - if (png_ptr->pass >= 7) - break; - - png_ptr->usr_width = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - - png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; - - if ((png_ptr->transformations & PNG_INTERLACE) != 0) - break; - - } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); - - } - - /* Reset the row above the image for the next pass */ - if (png_ptr->pass < 7) - { - if (png_ptr->prev_row != NULL) - memset(png_ptr->prev_row, 0, - PNG_ROWBYTES(png_ptr->usr_channels * - png_ptr->usr_bit_depth, png_ptr->width) + 1); - - return; - } - } -#endif - - /* If we get here, we've just written the last row, so we need - to flush the compressor */ - png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH); -} - -#ifdef PNG_WRITE_INTERLACING_SUPPORTED -/* Pick out the correct pixels for the interlace pass. - * The basic idea here is to go through the row with a source - * pointer and a destination pointer (sp and dp), and copy the - * correct pixels for the pass. As the row gets compacted, - * sp will always be >= dp, so we should never overwrite anything. - * See the default: case for the easiest code to understand. - */ -void /* PRIVATE */ -png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) -{ - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - - png_debug(1, "in png_do_write_interlace"); - - /* We don't have to do anything on the last pass (6) */ - if (pass < 6) - { - /* Each pixel depth is handled separately */ - switch (row_info->pixel_depth) - { - case 1: - { - png_bytep sp; - png_bytep dp; - unsigned int shift; - int d; - int value; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - dp = row; - d = 0; - shift = 7; - - for (i = png_pass_start[pass]; i < row_width; - i += png_pass_inc[pass]) - { - sp = row + (size_t)(i >> 3); - value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01; - d |= (value << shift); - - if (shift == 0) - { - shift = 7; - *dp++ = (png_byte)d; - d = 0; - } - - else - shift--; - - } - if (shift != 7) - *dp = (png_byte)d; - - break; - } - - case 2: - { - png_bytep sp; - png_bytep dp; - unsigned int shift; - int d; - int value; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - dp = row; - shift = 6; - d = 0; - - for (i = png_pass_start[pass]; i < row_width; - i += png_pass_inc[pass]) - { - sp = row + (size_t)(i >> 2); - value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03; - d |= (value << shift); - - if (shift == 0) - { - shift = 6; - *dp++ = (png_byte)d; - d = 0; - } - - else - shift -= 2; - } - if (shift != 6) - *dp = (png_byte)d; - - break; - } - - case 4: - { - png_bytep sp; - png_bytep dp; - unsigned int shift; - int d; - int value; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - - dp = row; - shift = 4; - d = 0; - for (i = png_pass_start[pass]; i < row_width; - i += png_pass_inc[pass]) - { - sp = row + (size_t)(i >> 1); - value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f; - d |= (value << shift); - - if (shift == 0) - { - shift = 4; - *dp++ = (png_byte)d; - d = 0; - } - - else - shift -= 4; - } - if (shift != 4) - *dp = (png_byte)d; - - break; - } - - default: - { - png_bytep sp; - png_bytep dp; - png_uint_32 i; - png_uint_32 row_width = row_info->width; - size_t pixel_bytes; - - /* Start at the beginning */ - dp = row; - - /* Find out how many bytes each pixel takes up */ - pixel_bytes = (row_info->pixel_depth >> 3); - - /* Loop through the row, only looking at the pixels that matter */ - for (i = png_pass_start[pass]; i < row_width; - i += png_pass_inc[pass]) - { - /* Find out where the original pixel is */ - sp = row + (size_t)i * pixel_bytes; - - /* Move the pixel */ - if (dp != sp) - memcpy(dp, sp, pixel_bytes); - - /* Next pixel */ - dp += pixel_bytes; - } - break; - } - } - /* Set new row width */ - row_info->width = (row_info->width + - png_pass_inc[pass] - 1 - - png_pass_start[pass]) / - png_pass_inc[pass]; - - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, - row_info->width); - } -} -#endif - - -/* This filters the row, chooses which filter to use, if it has not already - * been specified by the application, and then writes the row out with the - * chosen filter. - */ -static void /* PRIVATE */ -png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, - size_t row_bytes); - -#ifdef PNG_WRITE_FILTER_SUPPORTED -static size_t /* PRIVATE */ -png_setup_sub_row(png_structrp png_ptr, png_uint_32 bpp, - size_t row_bytes, size_t lmins) -{ - png_bytep rp, dp, lp; - size_t i; - size_t sum = 0; - unsigned int v; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp; - i++, rp++, dp++) - { - v = *dp = *rp; -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - } - - for (lp = png_ptr->row_buf + 1; i < row_bytes; - i++, rp++, lp++, dp++) - { - v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - - return (sum); -} - -static void /* PRIVATE */ -png_setup_sub_row_only(png_structrp png_ptr, png_uint_32 bpp, - size_t row_bytes) -{ - png_bytep rp, dp, lp; - size_t i; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp; - i++, rp++, dp++) - { - *dp = *rp; - } - - for (lp = png_ptr->row_buf + 1; i < row_bytes; - i++, rp++, lp++, dp++) - { - *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); - } -} - -static size_t /* PRIVATE */ -png_setup_up_row(png_structrp png_ptr, size_t row_bytes, size_t lmins) -{ - png_bytep rp, dp, pp; - size_t i; - size_t sum = 0; - unsigned int v; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, - pp = png_ptr->prev_row + 1; i < row_bytes; - i++, rp++, pp++, dp++) - { - v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - - return (sum); -} -static void /* PRIVATE */ -png_setup_up_row_only(png_structrp png_ptr, size_t row_bytes) -{ - png_bytep rp, dp, pp; - size_t i; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, - pp = png_ptr->prev_row + 1; i < row_bytes; - i++, rp++, pp++, dp++) - { - *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); - } -} - -static size_t /* PRIVATE */ -png_setup_avg_row(png_structrp png_ptr, png_uint_32 bpp, - size_t row_bytes, size_t lmins) -{ - png_bytep rp, dp, pp, lp; - png_uint_32 i; - size_t sum = 0; - unsigned int v; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, - pp = png_ptr->prev_row + 1; i < bpp; i++) - { - v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); - -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - } - - for (lp = png_ptr->row_buf + 1; i < row_bytes; i++) - { - v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) - & 0xff); - -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - - return (sum); -} -static void /* PRIVATE */ -png_setup_avg_row_only(png_structrp png_ptr, png_uint_32 bpp, - size_t row_bytes) -{ - png_bytep rp, dp, pp, lp; - png_uint_32 i; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, - pp = png_ptr->prev_row + 1; i < bpp; i++) - { - *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); - } - - for (lp = png_ptr->row_buf + 1; i < row_bytes; i++) - { - *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) - & 0xff); - } -} - -static size_t /* PRIVATE */ -png_setup_paeth_row(png_structrp png_ptr, png_uint_32 bpp, - size_t row_bytes, size_t lmins) -{ - png_bytep rp, dp, pp, cp, lp; - size_t i; - size_t sum = 0; - unsigned int v; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, - pp = png_ptr->prev_row + 1; i < bpp; i++) - { - v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); - -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - } - - for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes; - i++) - { - int a, b, c, pa, pb, pc, p; - - b = *pp++; - c = *cp++; - a = *lp++; - - p = b - c; - pc = a - c; - -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - - p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; - - v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); - -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - - if (sum > lmins) /* We are already worse, don't continue. */ - break; - } - - return (sum); -} -static void /* PRIVATE */ -png_setup_paeth_row_only(png_structrp png_ptr, png_uint_32 bpp, - size_t row_bytes) -{ - png_bytep rp, dp, pp, cp, lp; - size_t i; - - png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH; - - for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1, - pp = png_ptr->prev_row + 1; i < bpp; i++) - { - *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); - } - - for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes; - i++) - { - int a, b, c, pa, pb, pc, p; - - b = *pp++; - c = *cp++; - a = *lp++; - - p = b - c; - pc = a - c; - -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - - p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; - - *dp++ = (png_byte)(((int)*rp++ - p) & 0xff); - } -} -#endif /* WRITE_FILTER */ - -void /* PRIVATE */ -png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) -{ -#ifndef PNG_WRITE_FILTER_SUPPORTED - png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1); -#else - unsigned int filter_to_do = png_ptr->do_filter; - png_bytep row_buf; - png_bytep best_row; - png_uint_32 bpp; - size_t mins; - size_t row_bytes = row_info->rowbytes; - - png_debug(1, "in png_write_find_filter"); - - /* Find out how many bytes offset each pixel is */ - bpp = (row_info->pixel_depth + 7) >> 3; - - row_buf = png_ptr->row_buf; - mins = PNG_SIZE_MAX - 256/* so we can detect potential overflow of the - running sum */; - - /* The prediction method we use is to find which method provides the - * smallest value when summing the absolute values of the distances - * from zero, using anything >= 128 as negative numbers. This is known - * as the "minimum sum of absolute differences" heuristic. Other - * heuristics are the "weighted minimum sum of absolute differences" - * (experimental and can in theory improve compression), and the "zlib - * predictive" method (not implemented yet), which does test compressions - * of lines using different filter methods, and then chooses the - * (series of) filter(s) that give minimum compressed data size (VERY - * computationally expensive). - * - * GRR 980525: consider also - * - * (1) minimum sum of absolute differences from running average (i.e., - * keep running sum of non-absolute differences & count of bytes) - * [track dispersion, too? restart average if dispersion too large?] - * - * (1b) minimum sum of absolute differences from sliding average, probably - * with window size <= deflate window (usually 32K) - * - * (2) minimum sum of squared differences from zero or running average - * (i.e., ~ root-mean-square approach) - */ - - - /* We don't need to test the 'no filter' case if this is the only filter - * that has been chosen, as it doesn't actually do anything to the data. - */ - best_row = png_ptr->row_buf; - - if (PNG_SIZE_MAX/128 <= row_bytes) - { - /* Overflow can occur in the calculation, just select the lowest set - * filter. - */ - filter_to_do &= 0U-filter_to_do; - } - else if ((filter_to_do & PNG_FILTER_NONE) != 0 && - filter_to_do != PNG_FILTER_NONE) - { - /* Overflow not possible and multiple filters in the list, including the - * 'none' filter. - */ - png_bytep rp; - size_t sum = 0; - size_t i; - unsigned int v; - - { - for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) - { - v = *rp; -#ifdef PNG_USE_ABS - sum += 128 - abs((int)v - 128); -#else - sum += (v < 128) ? v : 256 - v; -#endif - } - } - - mins = sum; - } - - /* Sub filter */ - if (filter_to_do == PNG_FILTER_SUB) - /* It's the only filter so no testing is needed */ - { - png_setup_sub_row_only(png_ptr, bpp, row_bytes); - best_row = png_ptr->try_row; - } - - else if ((filter_to_do & PNG_FILTER_SUB) != 0) - { - size_t sum; - size_t lmins = mins; - - sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins); - - if (sum < mins) - { - mins = sum; - best_row = png_ptr->try_row; - if (png_ptr->tst_row != NULL) - { - png_ptr->try_row = png_ptr->tst_row; - png_ptr->tst_row = best_row; - } - } - } - - /* Up filter */ - if (filter_to_do == PNG_FILTER_UP) - { - png_setup_up_row_only(png_ptr, row_bytes); - best_row = png_ptr->try_row; - } - - else if ((filter_to_do & PNG_FILTER_UP) != 0) - { - size_t sum; - size_t lmins = mins; - - sum = png_setup_up_row(png_ptr, row_bytes, lmins); - - if (sum < mins) - { - mins = sum; - best_row = png_ptr->try_row; - if (png_ptr->tst_row != NULL) - { - png_ptr->try_row = png_ptr->tst_row; - png_ptr->tst_row = best_row; - } - } - } - - /* Avg filter */ - if (filter_to_do == PNG_FILTER_AVG) - { - png_setup_avg_row_only(png_ptr, bpp, row_bytes); - best_row = png_ptr->try_row; - } - - else if ((filter_to_do & PNG_FILTER_AVG) != 0) - { - size_t sum; - size_t lmins = mins; - - sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins); - - if (sum < mins) - { - mins = sum; - best_row = png_ptr->try_row; - if (png_ptr->tst_row != NULL) - { - png_ptr->try_row = png_ptr->tst_row; - png_ptr->tst_row = best_row; - } - } - } - - /* Paeth filter */ - if (filter_to_do == PNG_FILTER_PAETH) - { - png_setup_paeth_row_only(png_ptr, bpp, row_bytes); - best_row = png_ptr->try_row; - } - - else if ((filter_to_do & PNG_FILTER_PAETH) != 0) - { - size_t sum; - size_t lmins = mins; - - sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins); - - if (sum < mins) - { - best_row = png_ptr->try_row; - if (png_ptr->tst_row != NULL) - { - png_ptr->try_row = png_ptr->tst_row; - png_ptr->tst_row = best_row; - } - } - } - - /* Do the actual writing of the filtered row data from the chosen filter. */ - png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1); - -#endif /* WRITE_FILTER */ -} - - -/* Do the actual writing of a previously filtered row. */ -static void -png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, - size_t full_row_length/*includes filter byte*/) -{ - png_debug(1, "in png_write_filtered_row"); - - png_debug1(2, "filter = %d", filtered_row[0]); - - png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH); - -#ifdef PNG_WRITE_FILTER_SUPPORTED - /* Swap the current and previous rows */ - if (png_ptr->prev_row != NULL) - { - png_bytep tptr; - - tptr = png_ptr->prev_row; - png_ptr->prev_row = png_ptr->row_buf; - png_ptr->row_buf = tptr; - } -#endif /* WRITE_FILTER */ - - /* Finish row - updates counters and flushes zlib if last row */ - png_write_finish_row(png_ptr); - -#ifdef PNG_WRITE_FLUSH_SUPPORTED - png_ptr->flush_rows++; - - if (png_ptr->flush_dist > 0 && - png_ptr->flush_rows >= png_ptr->flush_dist) - { - png_write_flush(png_ptr); - } -#endif /* WRITE_FLUSH */ -} -#endif /* WRITE */ diff --git a/extern/optick b/extern/optick new file mode 160000 index 000000000..1db8585d2 --- /dev/null +++ b/extern/optick @@ -0,0 +1 @@ +Subproject commit 1db8585d2bf80c4e1497280d31fedc6fab4e1bba diff --git a/extern/sanitizers-cmake b/extern/sanitizers-cmake deleted file mode 160000 index 99e159ec9..000000000 --- a/extern/sanitizers-cmake +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 99e159ec9bc8dd362b08d18436bd40ff0648417b diff --git a/extern/tinyxml2 b/extern/tinyxml2 deleted file mode 160000 index 2ab76dab6..000000000 --- a/extern/tinyxml2 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2ab76dab6d3d744b4992a7795d3648dc86a1a890 diff --git a/gmm/LICENSE b/gmm/LICENSE deleted file mode 100644 index 65bf0a958..000000000 --- a/gmm/LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -GetFEM++ is free software; you can redistribute it and/or modify it -under the terms of the GNU Lesser General Public License as published -by the Free Software Foundation; either version 3 of the License, or -(at your option) any later version along with the GCC Runtime Library -Exception either version 3.1 or (at your option) any later version. -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License and the GCC Runtime Library Exception for more details. -You should have received a copy of the GNU Lesser General Public License -along with this program (see GNU_GPL_V3, GNU_LGPL_V3 and -GNU_GCC_RUNTIME_EXCEPTION files); if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. \ No newline at end of file diff --git a/gmm/gmm.h b/gmm/gmm.h deleted file mode 100644 index feeb299fa..000000000 --- a/gmm/gmm.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm.h - @author Yves Renard - @date October 13, 2002. - @brief Include common gmm files. -*/ -#ifndef GMM_H__ -#define GMM_H__ - -#include "gmm_kernel.h" -#include "gmm_dense_lu.h" -#include "gmm_dense_qr.h" - -#include "gmm_iter_solvers.h" -#include "gmm_condition_number.h" -#include "gmm_inoutput.h" - -#include "gmm_lapack_interface.h" -#include "gmm_superlu_interface.h" -#include "gmm_range_basis.h" - -#include "gmm_domain_decomp.h" - -#endif // GMM_H__ diff --git a/gmm/gmm_MUMPS_interface.h b/gmm/gmm_MUMPS_interface.h deleted file mode 100644 index bc68777fc..000000000 --- a/gmm/gmm_MUMPS_interface.h +++ /dev/null @@ -1,355 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard, Julien Pommier - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_MUMPS_interface.h - @author Yves Renard , - @author Julien Pommier - @date December 8, 2005. - @brief Interface with MUMPS (LU direct solver for sparse matrices). -*/ -#if defined(GMM_USES_MUMPS) || defined(HAVE_DMUMPS_C_H) - -#ifndef GMM_MUMPS_INTERFACE_H -#define GMM_MUMPS_INTERFACE_H - -#include "gmm_kernel.h" - - -extern "C" { - -#include -#undef F_INT -#undef F_DOUBLE -#undef F_DOUBLE2 -#include -#undef F_INT -#undef F_DOUBLE -#undef F_DOUBLE2 -#include -#undef F_INT -#undef F_DOUBLE -#undef F_DOUBLE2 -#include -#undef F_INT -#undef F_DOUBLE -#undef F_DOUBLE2 - -} - -namespace gmm { - -#define ICNTL(I) icntl[(I)-1] -#define INFO(I) info[(I)-1] -#define INFOG(I) infog[(I)-1] -#define RINFOG(I) rinfog[(I)-1] - - template struct ij_sparse_matrix { - std::vector irn; - std::vector jcn; - std::vector a; - bool sym; - - template void store(const L& l, size_type i) { - typename linalg_traits::const_iterator it = vect_const_begin(l), - ite = vect_const_end(l); - for (; it != ite; ++it) { - int ir = (int)i + 1, jc = (int)it.index() + 1; - if (*it != T(0) && (!sym || ir >= jc)) - { irn.push_back(ir); jcn.push_back(jc); a.push_back(*it); } - } - } - - template void build_from(const L& l, row_major) { - for (size_type i = 0; i < mat_nrows(l); ++i) - store(mat_const_row(l, i), i); - } - - template void build_from(const L& l, col_major) { - for (size_type i = 0; i < mat_ncols(l); ++i) - store(mat_const_col(l, i), i); - irn.swap(jcn); - } - - template ij_sparse_matrix(const L& A, bool sym_) { - size_type nz = nnz(A); - sym = sym_; - irn.reserve(nz); jcn.reserve(nz); a.reserve(nz); - build_from(A, typename principal_orientation_type::sub_orientation>::potype()); - } - }; - - /* ********************************************************************* */ - /* MUMPS solve interface */ - /* ********************************************************************* */ - - template struct mumps_interf {}; - - template <> struct mumps_interf { - typedef SMUMPS_STRUC_C MUMPS_STRUC_C; - typedef float value_type; - - static void mumps_c(MUMPS_STRUC_C &id) { smumps_c(&id); } - }; - - template <> struct mumps_interf { - typedef DMUMPS_STRUC_C MUMPS_STRUC_C; - typedef double value_type; - static void mumps_c(MUMPS_STRUC_C &id) { dmumps_c(&id); } - }; - - template <> struct mumps_interf > { - typedef CMUMPS_STRUC_C MUMPS_STRUC_C; - typedef mumps_complex value_type; - static void mumps_c(MUMPS_STRUC_C &id) { cmumps_c(&id); } - }; - - template <> struct mumps_interf > { - typedef ZMUMPS_STRUC_C MUMPS_STRUC_C; - typedef mumps_double_complex value_type; - static void mumps_c(MUMPS_STRUC_C &id) { zmumps_c(&id); } - }; - - - template - static inline bool mumps_error_check(MUMPS_STRUCT &id) { - if (id.INFO(1) < 0) { - switch (id.INFO(1)) { - case -2: - GMM_ASSERT1(false, "Solve with MUMPS failed: NZ = " << id.INFO(2) - << " is out of range"); - case -6 : case -10 : - GMM_WARNING1("Solve with MUMPS failed: matrix is singular"); - return false; - case -9: - GMM_ASSERT1(false, "Solve with MUMPS failed: error " - << id.INFO(1) << ", increase ICNTL(14)"); - case -13 : - GMM_ASSERT1(false, "Solve with MUMPS failed: not enough memory"); - default : - GMM_ASSERT1(false, "Solve with MUMPS failed with error " - << id.INFO(1)); - } - } - return true; - } - - - /** MUMPS solve interface - * Works only with sparse or skyline matrices - */ - template - bool MUMPS_solve(const MAT &A, const VECTX &X_, const VECTB &B, - bool sym = false, bool distributed = false) { - VECTX &X = const_cast(X_); - - typedef typename linalg_traits::value_type T; - typedef typename mumps_interf::value_type MUMPS_T; - GMM_ASSERT2(gmm::mat_nrows(A) == gmm::mat_ncols(A), "Non-square matrix"); - - std::vector rhs(gmm::vect_size(B)); gmm::copy(B, rhs); - - ij_sparse_matrix AA(A, sym); - - const int JOB_INIT = -1; - const int JOB_END = -2; - const int USE_COMM_WORLD = -987654; - - typename mumps_interf::MUMPS_STRUC_C id; - - int rank(0); -#ifdef GMM_USES_MPI - MPI_Comm_rank(MPI_COMM_WORLD, &rank); -#endif - - id.job = JOB_INIT; - id.par = 1; - id.sym = sym ? 2 : 0; - id.comm_fortran = USE_COMM_WORLD; - mumps_interf::mumps_c(id); - - if (rank == 0 || distributed) { - id.n = int(gmm::mat_nrows(A)); - if (distributed) { - id.nz_loc = int(AA.irn.size()); - id.irn_loc = &(AA.irn[0]); - id.jcn_loc = &(AA.jcn[0]); - id.a_loc = (MUMPS_T*)(&(AA.a[0])); - } else { - id.nz = int(AA.irn.size()); - id.irn = &(AA.irn[0]); - id.jcn = &(AA.jcn[0]); - id.a = (MUMPS_T*)(&(AA.a[0])); - } - if (rank == 0) - id.rhs = (MUMPS_T*)(&(rhs[0])); - } - - id.ICNTL(1) = -1; // output stream for error messages - id.ICNTL(2) = -1; // output stream for other messages - id.ICNTL(3) = -1; // output stream for global information - id.ICNTL(4) = 0; // verbosity level - - if (distributed) - id.ICNTL(5) = 0; // assembled input matrix (default) - - id.ICNTL(14) += 80; /* small boost to the workspace size as we have encountered some problem - who did not fit in the default settings of mumps.. - by default, ICNTL(14) = 15 or 20 - */ - //cout << "ICNTL(14): " << id.ICNTL(14) << "\n"; - - if (distributed) - id.ICNTL(18) = 3; // strategy for distributed input matrix - - // id.ICNTL(22) = 1; /* enables out-of-core support */ - - id.job = 6; - mumps_interf::mumps_c(id); - bool ok = mumps_error_check(id); - - id.job = JOB_END; - mumps_interf::mumps_c(id); - -#ifdef GMM_USES_MPI - MPI_Bcast(&(rhs[0]),id.n,gmm::mpi_type(T()),0,MPI_COMM_WORLD); -#endif - - gmm::copy(rhs, X); - - return ok; - - } - - - - /** MUMPS solve interface for distributed matrices - * Works only with sparse or skyline matrices - */ - template - bool MUMPS_distributed_matrix_solve(const MAT &A, const VECTX &X_, - const VECTB &B, bool sym = false) { - return MUMPS_solve(A, X_, B, sym, true); - } - - - - template - inline T real_or_complex(std::complex a) { return a.real(); } - template - inline T real_or_complex(T &a) { return a; } - - - /** Evaluate matrix determinant with MUMPS - * Works only with sparse or skyline matrices - */ - template ::value_type> - T MUMPS_determinant(const MAT &A, int &exponent, - bool sym = false, bool distributed = false) { - exponent = 0; - typedef typename mumps_interf::value_type MUMPS_T; - typedef typename number_traits::magnitude_type R; - GMM_ASSERT2(gmm::mat_nrows(A) == gmm::mat_ncols(A), "Non-square matrix"); - - ij_sparse_matrix AA(A, sym); - - const int JOB_INIT = -1; - const int JOB_END = -2; - const int USE_COMM_WORLD = -987654; - - typename mumps_interf::MUMPS_STRUC_C id; - - int rank(0); -#ifdef GMM_USES_MPI - MPI_Comm_rank(MPI_COMM_WORLD, &rank); -#endif - - id.job = JOB_INIT; - id.par = 1; - id.sym = sym ? 2 : 0; - id.comm_fortran = USE_COMM_WORLD; - mumps_interf::mumps_c(id); - - if (rank == 0 || distributed) { - id.n = int(gmm::mat_nrows(A)); - if (distributed) { - id.nz_loc = int(AA.irn.size()); - id.irn_loc = &(AA.irn[0]); - id.jcn_loc = &(AA.jcn[0]); - id.a_loc = (MUMPS_T*)(&(AA.a[0])); - } else { - id.nz = int(AA.irn.size()); - id.irn = &(AA.irn[0]); - id.jcn = &(AA.jcn[0]); - id.a = (MUMPS_T*)(&(AA.a[0])); - } - } - - id.ICNTL(1) = -1; // output stream for error messages - id.ICNTL(2) = -1; // output stream for other messages - id.ICNTL(3) = -1; // output stream for global information - id.ICNTL(4) = 0; // verbosity level - - if (distributed) - id.ICNTL(5) = 0; // assembled input matrix (default) - -// id.ICNTL(14) += 80; // small boost to the workspace size - - if (distributed) - id.ICNTL(18) = 3; // strategy for distributed input matrix - - id.ICNTL(31) = 1; // only factorization, no solution to follow - id.ICNTL(33) = 1; // request determinant calculation - - id.job = 4; // abalysis (job=1) + factorization (job=2) - mumps_interf::mumps_c(id); - mumps_error_check(id); - - T det = real_or_complex(std::complex(id.RINFOG(12),id.RINFOG(13))); - exponent = id.INFOG(34); - - id.job = JOB_END; - mumps_interf::mumps_c(id); - - return det; - } - -#undef ICNTL -#undef INFO -#undef INFOG -#undef RINFOG - -} - - -#endif // GMM_MUMPS_INTERFACE_H - -#endif // GMM_USES_MUMPS diff --git a/gmm/gmm_algobase.h b/gmm/gmm_algobase.h deleted file mode 100644 index 64a859da1..000000000 --- a/gmm/gmm_algobase.h +++ /dev/null @@ -1,228 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2000-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/** @file gmm_algobase.h - @author Yves Renard - @date September 28, 2000. - @brief Miscelleanous algorithms on containers. -*/ - -#ifndef GMM_ALGOBASE_H__ -#define GMM_ALGOBASE_H__ -#include "gmm_std.h" -#include "gmm_except.h" -#include - -namespace gmm { - - /* ********************************************************************* */ - /* Definitition de classes de comparaison. */ - /* retournant un int. */ - /* ********************************************************************* */ - - template - struct less : public std::binary_function { - inline int operator()(const T& x, const T& y) const - { return (x < y) ? -1 : ((y < x) ? 1 : 0); } - }; - - template<> struct less : public std::binary_function - { int operator()(int x, int y) const { return x-y; } }; - template<> struct less : public std::binary_function - { int operator()(char x, char y) const { return int(x-y); } }; - template<> struct less : public std::binary_function - { int operator()(short x, short y) const { return int(x-y); } }; - template<> struct less - : public std::binary_function { - int operator()(unsigned char x, unsigned char y) const - { return int(x)-int(y); } - }; - - - template - struct greater : public std::binary_function { - inline int operator()(const T& x, const T& y) const - { return (y < x) ? -1 : ((x < y) ? 1 : 0); } - }; - - template<> struct greater : public std::binary_function - { int operator()(int x, int y) const { return y-x; } }; - template<> struct greater : public std::binary_function - { int operator()(char x, char y) const { return int(y-x); } }; - template<> struct greater - : public std::binary_function - { int operator()(short x, short y) const { return int(y-x); } }; - template<> struct greater - : public std::binary_function { - int operator()(unsigned char x, unsigned char y) const - { return int(y)-int(x); } - }; - - template inline T my_abs(T a) { return (a < T(0)) ? T(-a) : a; } - - template - struct approx_less : public std::binary_function { - double eps; - inline int operator()(const T &x, const T &y) const - { if (my_abs(x - y) <= eps) return 0; if (x < y) return -1; return 1; } - approx_less(double e = 1E-13) { eps = e; } - }; - - template - struct approx_greater : public std::binary_function { - double eps; - inline int operator()(const T &x, const T &y) const - { if (my_abs(x - y) <= eps) return 0; if (x > y) return -1; return 1; } - approx_greater(double e = 1E-13) { eps = e; } - }; - - template - int lexicographical_compare(ITER1 b1, const ITER1 &e1, - ITER2 b2, const ITER2 &e2, const COMP &c) { - int i; - for ( ; b1 != e1 && b2 != e2; ++b1, ++b2) - if ((i = c(*b1, *b2)) != 0) return i; - if (b1 != e1) return 1; - if (b2 != e2) return -1; - return 0; - } - - template > - struct lexicographical_less : public std::binary_function - { - COMP c; - int operator()(const CONT &x, const CONT &y) const { - return gmm::lexicographical_compare(x.begin(), x.end(), - y.begin(), y.end(), c); - } - lexicographical_less(const COMP &d = COMP()) { c = d; } - }; - - template > - struct lexicographical_greater - : public std::binary_function { - COMP c; - int operator()(const CONT &x, const CONT &y) const { - return -gmm::lexicographical_compare(x.begin(), x.end(), - y.begin(), y.end(), c); - } - lexicographical_greater(const COMP &d = COMP()) { c = d; } - }; - - - /* ********************************************************************* */ - /* "Virtual" iterators on sequences. */ - /* The class T represent a class of sequence. */ - /* ********************************************************************* */ - - template struct sequence_iterator { - - typedef T value_type; - typedef value_type* pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef std::forward_iterator_tag iterator_category; - - T Un; - - sequence_iterator(T U0 = T(0)) { Un = U0; } - - sequence_iterator &operator ++() - { ++Un; return *this; } - sequence_iterator operator ++(int) - { sequence_iterator tmp = *this; (*this)++; return tmp; } - - const_reference operator *() const { return Un; } - reference operator *() { return Un; } - - bool operator ==(const sequence_iterator &i) const { return (i.Un==Un);} - bool operator !=(const sequence_iterator &i) const { return (i.Un!=Un);} - }; - - /* ********************************************************************* */ - /* generic algorithms. */ - /* ********************************************************************* */ - - template - ITER2 copy_n(ITER1 first, SIZE count, ITER2 result) { - for ( ; count > 0; --count, ++first, ++result) *result = *first; - return result; - } - - template - typename std::iterator_traits::value_type - mean_value(ITER first, const ITER &last) { - GMM_ASSERT2(first != last, "mean value of empty container"); - size_t n = 1; - typename std::iterator_traits::value_type res = *first++; - while (first != last) { res += *first; ++first; ++n; } - res /= float(n); - return res; - } - - template - typename CONT::value_type - mean_value(const CONT &c) { return mean_value(c.begin(), c.end()); } - - template /* hum ... */ - void minmax_box(typename std::iterator_traits::value_type &pmin, - typename std::iterator_traits::value_type &pmax, - ITER first, const ITER &last) { - typedef typename std::iterator_traits::value_type PT; - if (first != last) { pmin = pmax = *first; ++first; } - while (first != last) { - typename PT::const_iterator b = (*first).begin(), e = (*first).end(); - typename PT::iterator b1 = pmin.begin(), b2 = pmax.begin(); - while (b != e) - { *b1 = std::min(*b1, *b); *b2 = std::max(*b2, *b); ++b; ++b1; ++b2; } - } - } - - template struct sorted_indexes_aux { - const VEC &v; - public: - sorted_indexes_aux(const VEC& v_) : v(v_) {} - template - bool operator()(const IDX &ia, const IDX &ib) const - { return v[ia] < v[ib]; } - }; - - template - void sorted_indexes(const VEC &v, IVEC &iv) { - iv.clear(); iv.resize(v.size()); - for (size_t i=0; i < v.size(); ++i) iv[i] = i; - std::sort(iv.begin(), iv.end(), sorted_indexes_aux(v)); - } - -} - - -#endif /* GMM_ALGOBASE_H__ */ diff --git a/gmm/gmm_arch_config.h b/gmm/gmm_arch_config.h deleted file mode 100644 index 8d3ce66fb..000000000 --- a/gmm/gmm_arch_config.h +++ /dev/null @@ -1,7 +0,0 @@ -# ifndef _SRC_GMM_GMM_ARCH_CONFIG_H -#define _SRC_GMM_GMM_ARCH_CONFIG_H 1 -// enable the following line for OpenMP support -// #define GMM_HAVE_OPENMP -// -/* once: _SRC_GMM_GMM_ARCH_CONFIG_H */ -#endif diff --git a/gmm/gmm_blas.h b/gmm/gmm_blas.h deleted file mode 100644 index e227ac866..000000000 --- a/gmm/gmm_blas.h +++ /dev/null @@ -1,2285 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_blas.h - @author Yves Renard - @date October 13, 2002. - @brief Basic linear algebra functions. -*/ - -#ifndef GMM_BLAS_H__ -#define GMM_BLAS_H__ - -#include "gmm_scaled.h" -#include "gmm_transposed.h" -#include "gmm_conjugated.h" - -namespace gmm { - - /* ******************************************************************** */ - /* */ - /* Generic algorithms */ - /* */ - /* ******************************************************************** */ - - - /* ******************************************************************** */ - /* Miscellaneous */ - /* ******************************************************************** */ - - /** clear (fill with zeros) a vector or matrix. */ - template inline void clear(L &l) - { linalg_traits::do_clear(l); } - /** @cond DOXY_SHOW_ALL_FUNCTIONS - skip all these redundant definitions in doxygen documentation.. - */ - template inline void clear(const L &l) - { linalg_traits::do_clear(linalg_const_cast(l)); } - - ///@endcond - /** count the number of non-zero entries of a vector or matrix. */ template inline size_type nnz(const L& l) - { return nnz(l, typename linalg_traits::linalg_type()); } - - ///@cond DOXY_SHOW_ALL_FUNCTIONS - template inline size_type nnz(const L& l, abstract_vector) { - auto it = vect_const_begin(l), ite = vect_const_end(l); - size_type res(0); - for (; it != ite; ++it) ++res; - return res; - } - - template inline size_type nnz(const L& l, abstract_matrix) { - return nnz(l, typename principal_orientation_type::sub_orientation>::potype()); - } - - template inline size_type nnz(const L& l, row_major) { - size_type res(0); - for (size_type i = 0; i < mat_nrows(l); ++i) - res += nnz(mat_const_row(l, i)); - return res; - } - - template inline size_type nnz(const L& l, col_major) { - size_type res(0); - for (size_type i = 0; i < mat_ncols(l); ++i) - res += nnz(mat_const_col(l, i)); - return res; - } - - ///@endcond - - - /** fill a vector or matrix with x. */ - template inline - void fill(L& l, typename gmm::linalg_traits::value_type x) { - typedef typename gmm::linalg_traits::value_type T; - if (x == T(0)) gmm::clear(l); - fill(l, x, typename linalg_traits::linalg_type()); - } - - template inline - void fill(const L& l, typename gmm::linalg_traits::value_type x) { - fill(linalg_const_cast(l), x); - } - - template inline // to be optimized for dense vectors ... - void fill(L& l, typename gmm::linalg_traits::value_type x, - abstract_vector) { - for (size_type i = 0; i < vect_size(l); ++i) l[i] = x; - } - - template inline // to be optimized for dense matrices ... - void fill(L& l, typename gmm::linalg_traits::value_type x, - abstract_matrix) { - for (size_type i = 0; i < mat_nrows(l); ++i) - for (size_type j = 0; j < mat_ncols(l); ++j) - l(i,j) = x; - } - - /** fill a vector or matrix with random value (uniform [-1,1]). */ - template inline void fill_random(L& l) - { fill_random(l, typename linalg_traits::linalg_type()); } - - ///@cond DOXY_SHOW_ALL_FUNCTIONS - template inline void fill_random(const L& l) { - fill_random(linalg_const_cast(l), - typename linalg_traits::linalg_type()); - } - - template inline void fill_random(L& l, abstract_vector) { - for (size_type i = 0; i < vect_size(l); ++i) - l[i] = gmm::random(typename linalg_traits::value_type()); - } - - template inline void fill_random(L& l, abstract_matrix) { - for (size_type i = 0; i < mat_nrows(l); ++i) - for (size_type j = 0; j < mat_ncols(l); ++j) - l(i,j) = gmm::random(typename linalg_traits::value_type()); - } - - ///@endcond - /** fill a vector or matrix with random value. - @param l a vector or matrix. - @param cfill probability of a non-zero value. - */ - template inline void fill_random(L& l, double cfill) - { fill_random(l, cfill, typename linalg_traits::linalg_type()); } - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - template inline void fill_random(const L& l, double cfill) { - fill_random(linalg_const_cast(l), cfill, - typename linalg_traits::linalg_type()); - } - - template inline - void fill_random(L& l, double cfill, abstract_vector) { - typedef typename linalg_traits::value_type T; - size_type ntot = std::min(vect_size(l), - size_type(double(vect_size(l))*cfill) + 1); - for (size_type nb = 0; nb < ntot;) { - size_type i = gmm::irandom(vect_size(l)); - if (l[i] == T(0)) { - l[i] = gmm::random(typename linalg_traits::value_type()); - ++nb; - } - } - } - - template inline - void fill_random(L& l, double cfill, abstract_matrix) { - fill_random(l, cfill, typename principal_orientation_type::sub_orientation>::potype()); - } - - template inline - void fill_random(L& l, double cfill, row_major) { - for (size_type i=0; i < mat_nrows(l); ++i) fill_random(mat_row(l,i),cfill); - } - - template inline - void fill_random(L& l, double cfill, col_major) { - for (size_type j=0; j < mat_ncols(l); ++j) fill_random(mat_col(l,j),cfill); - } - - /* resize a vector */ - template inline - void resize(V &v, size_type n, linalg_false) - { linalg_traits::resize(v, n); } - - template inline - void resize(V &, size_type , linalg_modifiable) - { GMM_ASSERT1(false, "You cannot resize a reference"); } - - template inline - void resize(V &, size_type , linalg_const) - { GMM_ASSERT1(false, "You cannot resize a reference"); } - - ///@endcond - /** resize a vector. */ - template inline - void resize(V &v, size_type n) { - resize(v, n, typename linalg_traits::is_reference()); - } - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - /** resize a matrix **/ - template inline - void resize(M &v, size_type m, size_type n, linalg_false) { - linalg_traits::resize(v, m, n); - } - - template inline - void resize(M &, size_type, size_type, linalg_modifiable) - { GMM_ASSERT1(false, "You cannot resize a reference"); } - - template inline - void resize(M &, size_type, size_type, linalg_const) - { GMM_ASSERT1(false, "You cannot resize a reference"); } - - ///@endcond - /** resize a matrix */ - template inline - void resize(M &v, size_type m, size_type n) - { resize(v, m, n, typename linalg_traits::is_reference()); } - ///@cond - - template inline - void reshape(M &v, size_type m, size_type n, linalg_false) - { linalg_traits::reshape(v, m, n); } - - template inline - void reshape(M &, size_type, size_type, linalg_modifiable) - { GMM_ASSERT1(false, "You cannot reshape a reference"); } - - template inline - void reshape(M &, size_type, size_type, linalg_const) - { GMM_ASSERT1(false, "You cannot reshape a reference"); } - - ///@endcond - /** reshape a matrix */ - template inline - void reshape(M &v, size_type m, size_type n) - { reshape(v, m, n, typename linalg_traits::is_reference()); } - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - - /* ******************************************************************** */ - /* Scalar product */ - /* ******************************************************************** */ - - ///@endcond - /** scalar product between two vectors */ - template inline - typename strongest_value_type::value_type - vect_sp(const V1 &v1, const V2 &v2) { - GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch, " - << vect_size(v1) << " !=" << vect_size(v2)); - return vect_sp(v1, v2, - typename linalg_traits::storage_type(), - typename linalg_traits::storage_type()); - } - - /** scalar product between two vectors, using a matrix. - @param ps the matrix of the scalar product. - @param v1 the first vector - @param v2 the second vector - */ - template inline - typename strongest_value_type3::value_type - vect_sp(const MATSP &ps, const V1 &v1, const V2 &v2) { - return vect_sp_with_mat(ps, v1, v2, - typename linalg_traits::sub_orientation()); - } - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - template inline - typename strongest_value_type3::value_type - vect_sp_with_mat(const MATSP &ps, const V1 &v1, const V2 &v2, row_major) { - return vect_sp_with_matr(ps, v1, v2, - typename linalg_traits::storage_type()); - } - - template inline - typename strongest_value_type3::value_type - vect_sp_with_matr(const MATSP &ps, const V1 &v1, const V2 &v2, - abstract_sparse) { - GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) && - vect_size(v2) == mat_nrows(ps), "dimensions mismatch"); - size_type nr = mat_nrows(ps); - typename linalg_traits::const_iterator - it = vect_const_begin(v2), ite = vect_const_end(v2); - typename strongest_value_type3::value_type res(0); - for (; it != ite; ++it) - res += vect_sp(mat_const_row(ps, it.index()), v1)* (*it); - return res; - } - - template inline - typename strongest_value_type3::value_type - vect_sp_with_matr(const MATSP &ps, const V1 &v1, const V2 &v2, - abstract_skyline) - { return vect_sp_with_matr(ps, v1, v2, abstract_sparse()); } - - template inline - typename strongest_value_type3::value_type - vect_sp_with_matr(const MATSP &ps, const V1 &v1, const V2 &v2, - abstract_dense) { - GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) && - vect_size(v2) == mat_nrows(ps), "dimensions mismatch"); - typename linalg_traits::const_iterator - it = vect_const_begin(v2), ite = vect_const_end(v2); - typename strongest_value_type3::value_type res(0); - for (size_type i = 0; it != ite; ++i, ++it) - res += vect_sp(mat_const_row(ps, i), v1) * (*it); - return res; - } - - template inline - typename strongest_value_type3::value_type - vect_sp_with_mat(const MATSP &ps, const V1 &v1,const V2 &v2,row_and_col) - { return vect_sp_with_mat(ps, v1, v2, row_major()); } - - template inline - typename strongest_value_type3::value_type - vect_sp_with_mat(const MATSP &ps, const V1 &v1, const V2 &v2,col_major){ - return vect_sp_with_matc(ps, v1, v2, - typename linalg_traits::storage_type()); - } - - template inline - typename strongest_value_type3::value_type - vect_sp_with_matc(const MATSP &ps, const V1 &v1, const V2 &v2, - abstract_sparse) { - GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) && - vect_size(v2) == mat_nrows(ps), "dimensions mismatch"); - typename linalg_traits::const_iterator - it = vect_const_begin(v1), ite = vect_const_end(v1); - typename strongest_value_type3::value_type res(0); - for (; it != ite; ++it) - res += vect_sp(mat_const_col(ps, it.index()), v2) * (*it); - return res; - } - - template inline - typename strongest_value_type3::value_type - vect_sp_with_matc(const MATSP &ps, const V1 &v1, const V2 &v2, - abstract_skyline) - { return vect_sp_with_matc(ps, v1, v2, abstract_sparse()); } - - template inline - typename strongest_value_type3::value_type - vect_sp_with_matc(const MATSP &ps, const V1 &v1, const V2 &v2, - abstract_dense) { - GMM_ASSERT2(vect_size(v1) == mat_ncols(ps) && - vect_size(v2) == mat_nrows(ps), "dimensions mismatch"); - typename linalg_traits::const_iterator - it = vect_const_begin(v1), ite = vect_const_end(v1); - typename strongest_value_type3::value_type res(0); - for (size_type i = 0; it != ite; ++i, ++it) - res += vect_sp(mat_const_col(ps, i), v2) * (*it); - return res; - } - - template inline - typename strongest_value_type3::value_type - vect_sp_with_mat(const MATSP &ps, const V1 &v1,const V2 &v2,col_and_row) - { return vect_sp_with_mat(ps, v1, v2, col_major()); } - - template inline - typename strongest_value_type3::value_type - vect_sp_with_mat(const MATSP &ps, const V1 &v1, const V2 &v2, - abstract_null_type) { - typename temporary_vector::vector_type w(mat_nrows(ps)); - GMM_WARNING2("Warning, a temporary is used in scalar product\n"); - mult(ps, v1, w); - return vect_sp(w, v2); - } - - template inline - typename strongest_numeric_type::value_type, - typename std::iterator_traits::value_type>::T - vect_sp_dense_(IT1 it, IT1 ite, IT2 it2) { - typename strongest_numeric_type::value_type, - typename std::iterator_traits::value_type>::T res(0); - for (; it != ite; ++it, ++it2) res += (*it) * (*it2); - return res; - } - - template inline - typename strongest_numeric_type::value_type, - typename linalg_traits::value_type>::T - vect_sp_sparse_(IT1 it, IT1 ite, const V &v) { - typename strongest_numeric_type::value_type, - typename linalg_traits::value_type>::T res(0); - for (; it != ite; ++it) res += (*it) * v[it.index()]; - return res; - } - - template inline - typename strongest_value_type::value_type - vect_sp(const V1 &v1, const V2 &v2, abstract_dense, abstract_dense) { - return vect_sp_dense_(vect_const_begin(v1), vect_const_end(v1), - vect_const_begin(v2)); - } - - template inline - typename strongest_value_type::value_type - vect_sp(const V1 &v1, const V2 &v2, abstract_skyline, abstract_dense) { - typename linalg_traits::const_iterator it1 = vect_const_begin(v1), - ite = vect_const_end(v1); - typename linalg_traits::const_iterator it2 = vect_const_begin(v2); - return vect_sp_dense_(it1, ite, it2 + it1.index()); - } - - template inline - typename strongest_value_type::value_type - vect_sp(const V1 &v1, const V2 &v2, abstract_dense, abstract_skyline) { - typename linalg_traits::const_iterator it1 = vect_const_begin(v2), - ite = vect_const_end(v2); - typename linalg_traits::const_iterator it2 = vect_const_begin(v1); - return vect_sp_dense_(it1, ite, it2 + it1.index()); - } - - template inline - typename strongest_value_type::value_type - vect_sp(const V1 &v1, const V2 &v2, abstract_skyline, abstract_skyline) { - typedef typename strongest_value_type::value_type T; - auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1); - auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2); - size_type n = std::min(ite1.index(), ite2.index()); - size_type l = std::max(it1.index(), it2.index()); - - if (l < n) { - size_type m = l - it1.index(), p = l - it2.index(), q = m + n - l; - return vect_sp_dense_(it1+m, it1+q, it2 + p); - } - return T(0); - } - - template inline - typename strongest_value_type::value_type - vect_sp(const V1 &v1, const V2 &v2,abstract_sparse,abstract_dense) { - return vect_sp_sparse_(vect_const_begin(v1), vect_const_end(v1), v2); - } - - template inline - typename strongest_value_type::value_type - vect_sp(const V1 &v1, const V2 &v2, abstract_sparse, abstract_skyline) { - return vect_sp_sparse_(vect_const_begin(v1), vect_const_end(v1), v2); - } - - template inline - typename strongest_value_type::value_type - vect_sp(const V1 &v1, const V2 &v2, abstract_skyline, abstract_sparse) { - return vect_sp_sparse_(vect_const_begin(v2), vect_const_end(v2), v1); - } - - template inline - typename strongest_value_type::value_type - vect_sp(const V1 &v1, const V2 &v2, abstract_dense,abstract_sparse) { - return vect_sp_sparse_(vect_const_begin(v2), vect_const_end(v2), v1); - } - - - template inline - typename strongest_value_type::value_type - vect_sp_sparse_sparse(const V1 &v1, const V2 &v2, linalg_true) { - typename linalg_traits::const_iterator it1 = vect_const_begin(v1), - ite1 = vect_const_end(v1); - typename linalg_traits::const_iterator it2 = vect_const_begin(v2), - ite2 = vect_const_end(v2); - typename strongest_value_type::value_type res(0); - - while (it1 != ite1 && it2 != ite2) { - if (it1.index() == it2.index()) - { res += (*it1) * *it2; ++it1; ++it2; } - else if (it1.index() < it2.index()) ++it1; else ++it2; - } - return res; - } - - template inline - typename strongest_value_type::value_type - vect_sp_sparse_sparse(const V1 &v1, const V2 &v2, linalg_false) { - return vect_sp_sparse_(vect_const_begin(v1), vect_const_end(v1), v2); - } - - template inline - typename strongest_value_type::value_type - vect_sp(const V1 &v1, const V2 &v2,abstract_sparse,abstract_sparse) { - return vect_sp_sparse_sparse(v1, v2, - typename linalg_and::index_sorted, - typename linalg_traits::index_sorted>::bool_type()); - } - - /* ******************************************************************** */ - /* Hermitian product */ - /* ******************************************************************** */ - ///@endcond - /** Hermitian product. */ - template - inline typename strongest_value_type::value_type - vect_hp(const V1 &v1, const V2 &v2) - { return vect_sp(v1, conjugated(v2)); } - - /** Hermitian product with a matrix. */ - template inline - typename strongest_value_type3::value_type - vect_hp(const MATSP &ps, const V1 &v1, const V2 &v2) { - return vect_sp(ps, v1, gmm::conjugated(v2)); - } - - /* ******************************************************************** */ - /* Trace of a matrix */ - /* ******************************************************************** */ - - /** Trace of a matrix */ - template - typename linalg_traits::value_type - mat_trace(const M &m) { - typedef typename linalg_traits::value_type T; - T res(0); - for (size_type i = 0; i < std::min(mat_nrows(m), mat_ncols(m)); ++i) - res += m(i,i); - return res; - } - - /* ******************************************************************** */ - /* Euclidean norm */ - /* ******************************************************************** */ - - /** squared Euclidean norm of a vector. */ - template - typename number_traits::value_type> - ::magnitude_type - vect_norm2_sqr(const V &v) { - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - auto it = vect_const_begin(v), ite = vect_const_end(v); - R res(0); - for (; it != ite; ++it) res += gmm::abs_sqr(*it); - return res; - } - - /** Euclidean norm of a vector. */ - template inline - typename number_traits::value_type> - ::magnitude_type - vect_norm2(const V &v) - { return sqrt(vect_norm2_sqr(v)); } - - - /** squared Euclidean distance between two vectors */ - template inline - typename number_traits::value_type> - ::magnitude_type - vect_dist2_sqr(const V1 &v1, const V2 &v2) { // not fully optimized - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1); - auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2); - size_type k1(0), k2(0); - R res(0); - while (it1 != ite1 && it2 != ite2) { - size_type i1 = index_of_it(it1, k1, - typename linalg_traits::storage_type()); - size_type i2 = index_of_it(it2, k2, - typename linalg_traits::storage_type()); - - if (i1 == i2) { - res += gmm::abs_sqr(*it2 - *it1); ++it1; ++k1; ++it2; ++k2; - } - else if (i1 < i2) { - res += gmm::abs_sqr(*it1); ++it1; ++k1; - } - else { - res += gmm::abs_sqr(*it2); ++it2; ++k2; - } - } - while (it1 != ite1) { res += gmm::abs_sqr(*it1); ++it1; } - while (it2 != ite2) { res += gmm::abs_sqr(*it2); ++it2; } - return res; - } - - /** Euclidean distance between two vectors */ - template inline - typename number_traits::value_type> - ::magnitude_type - vect_dist2(const V1 &v1, const V2 &v2) - { return sqrt(vect_dist2_sqr(v1, v2)); } - ///@cond DOXY_SHOW_ALL_FUNCTIONS - template - typename number_traits::value_type> - ::magnitude_type - mat_euclidean_norm_sqr(const M &m, row_major) { - typename number_traits::value_type> - ::magnitude_type res(0); - for (size_type i = 0; i < mat_nrows(m); ++i) - res += vect_norm2_sqr(mat_const_row(m, i)); - return res; - } - - template - typename number_traits::value_type> - ::magnitude_type - mat_euclidean_norm_sqr(const M &m, col_major) { - typename number_traits::value_type> - ::magnitude_type res(0); - for (size_type i = 0; i < mat_ncols(m); ++i) - res += vect_norm2_sqr(mat_const_col(m, i)); - return res; - } - ///@endcond - /** squared Euclidean norm of a matrix. */ - template inline - typename number_traits::value_type> - ::magnitude_type - mat_euclidean_norm_sqr(const M &m) { - return mat_euclidean_norm_sqr(m, - typename principal_orientation_type::sub_orientation>::potype()); - } - - /** Euclidean norm of a matrix. */ - template inline - typename number_traits::value_type> - ::magnitude_type - mat_euclidean_norm(const M &m) - { return gmm::sqrt(mat_euclidean_norm_sqr(m)); } - - /* ******************************************************************** */ - /* vector norm1 */ - /* ******************************************************************** */ - /** 1-norm of a vector */ - template - typename number_traits::value_type> - ::magnitude_type - vect_norm1(const V &v) { - auto it = vect_const_begin(v), ite = vect_const_end(v); - typename number_traits::value_type> - ::magnitude_type res(0); - for (; it != ite; ++it) res += gmm::abs(*it); - return res; - } - - /** 1-distance between two vectors */ - template inline - typename number_traits::value_type> - ::magnitude_type - vect_dist1(const V1 &v1, const V2 &v2) { // not fully optimized - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1); - auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2); - size_type k1(0), k2(0); - R res(0); - while (it1 != ite1 && it2 != ite2) { - size_type i1 = index_of_it(it1, k1, - typename linalg_traits::storage_type()); - size_type i2 = index_of_it(it2, k2, - typename linalg_traits::storage_type()); - - if (i1 == i2) { - res += gmm::abs(*it2 - *it1); ++it1; ++k1; ++it2; ++k2; - } - else if (i1 < i2) { - res += gmm::abs(*it1); ++it1; ++k1; - } - else { - res += gmm::abs(*it2); ++it2; ++k2; - } - } - while (it1 != ite1) { res += gmm::abs(*it1); ++it1; } - while (it2 != ite2) { res += gmm::abs(*it2); ++it2; } - return res; - } - - /* ******************************************************************** */ - /* vector Infinity norm */ - /* ******************************************************************** */ - /** Infinity norm of a vector. */ - template - typename number_traits::value_type> - ::magnitude_type - vect_norminf(const V &v) { - auto it = vect_const_begin(v), ite = vect_const_end(v); - typename number_traits::value_type> - ::magnitude_type res(0); - for (; it != ite; ++it) res = std::max(res, gmm::abs(*it)); - return res; - } - - /** Infinity distance between two vectors */ - template inline - typename number_traits::value_type> - ::magnitude_type - vect_distinf(const V1 &v1, const V2 &v2) { // not fully optimized - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - auto it1 = vect_const_begin(v1), ite1 = vect_const_end(v1); - auto it2 = vect_const_begin(v2), ite2 = vect_const_end(v2); - size_type k1(0), k2(0); - R res(0); - while (it1 != ite1 && it2 != ite2) { - size_type i1 = index_of_it(it1, k1, - typename linalg_traits::storage_type()); - size_type i2 = index_of_it(it2, k2, - typename linalg_traits::storage_type()); - - if (i1 == i2) { - res = std::max(res, gmm::abs(*it2 - *it1)); ++it1; ++k1; ++it2; ++k2; - } - else if (i1 < i2) { - res = std::max(res, gmm::abs(*it1)); ++it1; ++k1; - } - else { - res = std::max(res, gmm::abs(*it2)); ++it2; ++k2; - } - } - while (it1 != ite1) { res = std::max(res, gmm::abs(*it1)); ++it1; } - while (it2 != ite2) { res = std::max(res, gmm::abs(*it2)); ++it2; } - return res; - } - - /* ******************************************************************** */ - /* matrix norm1 */ - /* ******************************************************************** */ - ///@cond DOXY_SHOW_ALL_FUNCTIONS - template - typename number_traits::value_type> - ::magnitude_type - mat_norm1(const M &m, col_major) { - typename number_traits::value_type> - ::magnitude_type res(0); - for (size_type i = 0; i < mat_ncols(m); ++i) - res = std::max(res, vect_norm1(mat_const_col(m,i))); - return res; - } - - template - typename number_traits::value_type> - ::magnitude_type - mat_norm1(const M &m, row_major) { - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - typedef typename linalg_traits::storage_type store_type; - - std::vector aux(mat_ncols(m)); - for (size_type i = 0; i < mat_nrows(m); ++i) { - typename linalg_traits::const_sub_row_type row = mat_const_row(m, i); - auto it = vect_const_begin(row), ite = vect_const_end(row); - for (size_type k = 0; it != ite; ++it, ++k) - aux[index_of_it(it, k, store_type())] += gmm::abs(*it); - } - return vect_norminf(aux); - } - - template - typename number_traits::value_type> - ::magnitude_type - mat_norm1(const M &m, col_and_row) - { return mat_norm1(m, col_major()); } - - template - typename number_traits::value_type> - ::magnitude_type - mat_norm1(const M &m, row_and_col) - { return mat_norm1(m, col_major()); } - ///@endcond - /** 1-norm of a matrix */ - template - typename number_traits::value_type> - ::magnitude_type - mat_norm1(const M &m) { - return mat_norm1(m, typename linalg_traits::sub_orientation()); - } - - - /* ******************************************************************** */ - /* matrix Infinity norm */ - /* ******************************************************************** */ - ///@cond DOXY_SHOW_ALL_FUNCTIONS - template - typename number_traits::value_type> - ::magnitude_type - mat_norminf(const M &m, row_major) { - typename number_traits::value_type> - ::magnitude_type res(0); - for (size_type i = 0; i < mat_nrows(m); ++i) - res = std::max(res, vect_norm1(mat_const_row(m,i))); - return res; - } - - template - typename number_traits::value_type> - ::magnitude_type - mat_norminf(const M &m, col_major) { - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - typedef typename linalg_traits::storage_type store_type; - - std::vector aux(mat_nrows(m)); - for (size_type i = 0; i < mat_ncols(m); ++i) { - typename linalg_traits::const_sub_col_type col = mat_const_col(m, i); - auto it = vect_const_begin(col), ite = vect_const_end(col); - for (size_type k = 0; it != ite; ++it, ++k) - aux[index_of_it(it, k, store_type())] += gmm::abs(*it); - } - return vect_norminf(aux); - } - - template - typename number_traits::value_type> - ::magnitude_type - mat_norminf(const M &m, col_and_row) - { return mat_norminf(m, row_major()); } - - template - typename number_traits::value_type> - ::magnitude_type - mat_norminf(const M &m, row_and_col) - { return mat_norminf(m, row_major()); } - ///@endcond - /** infinity-norm of a matrix.*/ - template - typename number_traits::value_type> - ::magnitude_type - mat_norminf(const M &m) { - return mat_norminf(m, typename linalg_traits::sub_orientation()); - } - - /* ******************************************************************** */ - /* Max norm for matrices */ - /* ******************************************************************** */ - ///@cond DOXY_SHOW_ALL_FUNCTIONS - template - typename number_traits::value_type> - ::magnitude_type - mat_maxnorm(const M &m, row_major) { - typename number_traits::value_type> - ::magnitude_type res(0); - for (size_type i = 0; i < mat_nrows(m); ++i) - res = std::max(res, vect_norminf(mat_const_row(m,i))); - return res; - } - - template - typename number_traits::value_type> - ::magnitude_type - mat_maxnorm(const M &m, col_major) { - typename number_traits::value_type> - ::magnitude_type res(0); - for (size_type i = 0; i < mat_ncols(m); ++i) - res = std::max(res, vect_norminf(mat_const_col(m,i))); - return res; - } - ///@endcond - /** max-norm of a matrix. */ - template - typename number_traits::value_type> - ::magnitude_type - mat_maxnorm(const M &m) { - return mat_maxnorm(m, - typename principal_orientation_type::sub_orientation>::potype()); - } - - /* ******************************************************************** */ - /* Clean */ - /* ******************************************************************** */ - /** Clean a vector or matrix (replace near-zero entries with zeroes). */ - - template inline void clean(L &l, double threshold); - - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - template - void clean(L &l, double threshold, abstract_dense, T) { - typedef typename number_traits::magnitude_type R; - auto it = vect_begin(l), ite = vect_end(l); - for (; it != ite; ++it) - if (gmm::abs(*it) < R(threshold)) *it = T(0); - } - - template - void clean(L &l, double threshold, abstract_skyline, T) - { gmm::clean(l, threshold, abstract_dense(), T()); } - - template - void clean(L &l, double threshold, abstract_sparse, T) { - typedef typename number_traits::magnitude_type R; - auto it = vect_begin(l), ite = vect_end(l); - std::vector ind; - for (; it != ite; ++it) - if (gmm::abs(*it) < R(threshold)) ind.push_back(it.index()); - for (size_type i = 0; i < ind.size(); ++i) l[ind[i]] = T(0); - } - - template - void clean(L &l, double threshold, abstract_dense, std::complex) { - auto it = vect_begin(l), ite = vect_end(l); - for (; it != ite; ++it){ - if (gmm::abs((*it).real()) < T(threshold)) - *it = std::complex(T(0), (*it).imag()); - if (gmm::abs((*it).imag()) < T(threshold)) - *it = std::complex((*it).real(), T(0)); - } - } - - template - void clean(L &l, double threshold, abstract_skyline, std::complex) - { gmm::clean(l, threshold, abstract_dense(), std::complex()); } - - template - void clean(L &l, double threshold, abstract_sparse, std::complex) { - auto it = vect_begin(l), ite = vect_end(l); - std::vector ind; - for (; it != ite; ++it) { - bool r = (gmm::abs((*it).real()) < T(threshold)); - bool i = (gmm::abs((*it).imag()) < T(threshold)); - if (r && i) ind.push_back(it.index()); - else if (r) *it = std::complex(T(0), (*it).imag()); - else if (i) *it = std::complex((*it).real(), T(0)); - } - for (size_type i = 0; i < ind.size(); ++i) - l[ind[i]] = std::complex(T(0),T(0)); - } - - template inline void clean(L &l, double threshold, - abstract_vector) { - gmm::clean(l, threshold, typename linalg_traits::storage_type(), - typename linalg_traits::value_type()); - } - - template inline void clean(const L &l, double threshold); - - template void clean(L &l, double threshold, row_major) { - for (size_type i = 0; i < mat_nrows(l); ++i) - gmm::clean(mat_row(l, i), threshold); - } - - template void clean(L &l, double threshold, col_major) { - for (size_type i = 0; i < mat_ncols(l); ++i) - gmm::clean(mat_col(l, i), threshold); - } - - template inline void clean(L &l, double threshold, - abstract_matrix) { - gmm::clean(l, threshold, - typename principal_orientation_type::sub_orientation>::potype()); - } - - template inline void clean(L &l, double threshold) - { clean(l, threshold, typename linalg_traits::linalg_type()); } - - template inline void clean(const L &l, double threshold) - { gmm::clean(linalg_const_cast(l), threshold); } - - /* ******************************************************************** */ - /* Copy */ - /* ******************************************************************** */ - ///@endcond - /** Copy vectors or matrices. - @param l1 source vector or matrix. - @param l2 destination. - */ - template inline - void copy(const L1& l1, L2& l2) { - if ((const void *)(&l1) != (const void *)(&l2)) { - if (same_origin(l1,l2)) - GMM_WARNING2("Warning : a conflict is possible in copy\n"); - - copy(l1, l2, typename linalg_traits::linalg_type(), - typename linalg_traits::linalg_type()); - } - } - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - template inline - void copy(const L1& l1, const L2& l2) { copy(l1, linalg_const_cast(l2)); } - - template inline - void copy(const L1& l1, L2& l2, abstract_vector, abstract_vector) { - GMM_ASSERT2(vect_size(l1) == vect_size(l2), "dimensions mismatch, " - << vect_size(l1) << " !=" << vect_size(l2)); - copy_vect(l1, l2, typename linalg_traits::storage_type(), - typename linalg_traits::storage_type()); - } - - template inline - void copy(const L1& l1, L2& l2, abstract_matrix, abstract_matrix) { - size_type m = mat_nrows(l1), n = mat_ncols(l1); - if (!m || !n) return; - GMM_ASSERT2(n==mat_ncols(l2) && m==mat_nrows(l2), "dimensions mismatch"); - copy_mat(l1, l2, typename linalg_traits::sub_orientation(), - typename linalg_traits::sub_orientation()); - } - - template inline - void copy_vect(const V1 &v1, const V2 &v2, C1, C2) - { copy_vect(v1, const_cast(v2), C1(), C2()); } - - - template - void copy_mat_by_row(const L1& l1, L2& l2) { - size_type nbr = mat_nrows(l1); - for (size_type i = 0; i < nbr; ++i) - copy(mat_const_row(l1, i), mat_row(l2, i)); - } - - template - void copy_mat_by_col(const L1 &l1, L2 &l2) { - size_type nbc = mat_ncols(l1); - for (size_type i = 0; i < nbc; ++i) { - copy(mat_const_col(l1, i), mat_col(l2, i)); - } - } - - template inline - void copy_mat(const L1& l1, L2& l2, row_major, row_major) - { copy_mat_by_row(l1, l2); } - - template inline - void copy_mat(const L1& l1, L2& l2, row_major, row_and_col) - { copy_mat_by_row(l1, l2); } - - template inline - void copy_mat(const L1& l1, L2& l2, row_and_col, row_and_col) - { copy_mat_by_row(l1, l2); } - - template inline - void copy_mat(const L1& l1, L2& l2, row_and_col, row_major) - { copy_mat_by_row(l1, l2); } - - template inline - void copy_mat(const L1& l1, L2& l2, col_and_row, row_major) - { copy_mat_by_row(l1, l2); } - - template inline - void copy_mat(const L1& l1, L2& l2, row_major, col_and_row) - { copy_mat_by_row(l1, l2); } - - template inline - void copy_mat(const L1& l1, L2& l2, col_and_row, row_and_col) - { copy_mat_by_row(l1, l2); } - - template inline - void copy_mat(const L1& l1, L2& l2, row_and_col, col_and_row) - { copy_mat_by_row(l1, l2); } - - template inline - void copy_mat(const L1& l1, L2& l2, col_major, col_major) - { copy_mat_by_col(l1, l2); } - - template inline - void copy_mat(const L1& l1, L2& l2, col_major, col_and_row) - { copy_mat_by_col(l1, l2); } - - template inline - void copy_mat(const L1& l1, L2& l2, col_major, row_and_col) - { copy_mat_by_col(l1, l2); } - - template inline - void copy_mat(const L1& l1, L2& l2, row_and_col, col_major) - { copy_mat_by_col(l1, l2); } - - template inline - void copy_mat(const L1& l1, L2& l2, col_and_row, col_major) - { copy_mat_by_col(l1, l2); } - - template inline - void copy_mat(const L1& l1, L2& l2, col_and_row, col_and_row) - { copy_mat_by_col(l1, l2); } - - template inline - void copy_mat_mixed_rc(const L1& l1, L2& l2, size_type i) { - copy_mat_mixed_rc(l1, l2, i, typename linalg_traits::storage_type()); - } - - template - void copy_mat_mixed_rc(const L1& l1, L2& l2, size_type i, abstract_sparse) { - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (; it != ite; ++it) - l2(i, it.index()) = *it; - } - - template - void copy_mat_mixed_rc(const L1& l1, L2& l2, size_type i, abstract_skyline) { - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (; it != ite; ++it) - l2(i, it.index()) = *it; - } - - template - void copy_mat_mixed_rc(const L1& l1, L2& l2, size_type i, abstract_dense) { - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (size_type j = 0; it != ite; ++it, ++j) l2(i, j) = *it; - } - - template inline - void copy_mat_mixed_cr(const L1& l1, L2& l2, size_type i) { - copy_mat_mixed_cr(l1, l2, i, typename linalg_traits::storage_type()); - } - - template - void copy_mat_mixed_cr(const L1& l1, L2& l2, size_type i, abstract_sparse) { - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (; it != ite; ++it) l2(it.index(), i) = *it; - } - - template - void copy_mat_mixed_cr(const L1& l1, L2& l2, size_type i, abstract_skyline) { - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (; it != ite; ++it) l2(it.index(), i) = *it; - } - - template - void copy_mat_mixed_cr(const L1& l1, L2& l2, size_type i, abstract_dense) { - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (size_type j = 0; it != ite; ++it, ++j) l2(j, i) = *it; - } - - template - void copy_mat(const L1& l1, L2& l2, row_major, col_major) { - clear(l2); - size_type nbr = mat_nrows(l1); - for (size_type i = 0; i < nbr; ++i) - copy_mat_mixed_rc(mat_const_row(l1, i), l2, i); - } - - template - void copy_mat(const L1& l1, L2& l2, col_major, row_major) { - clear(l2); - size_type nbc = mat_ncols(l1); - for (size_type i = 0; i < nbc; ++i) - copy_mat_mixed_cr(mat_const_col(l1, i), l2, i); - } - - template inline - void copy_vect(const L1 &l1, L2 &l2, abstract_dense, abstract_dense) { - std::copy(vect_const_begin(l1), vect_const_end(l1), vect_begin(l2)); - } - - template inline // to be optimised ? - void copy_vect(const L1 &l1, L2 &l2, abstract_skyline, abstract_skyline) { - auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1); - while (it1 != ite1 && *it1 == typename linalg_traits::value_type(0)) - ++it1; - - if (ite1 - it1 > 0) { - clear(l2); - auto it2 = vect_begin(l2), ite2 = vect_end(l2); - while (*(ite1-1) == typename linalg_traits::value_type(0)) ite1--; - - if (it2 == ite2) { - l2[it1.index()] = *it1; ++it1; - l2[ite1.index()-1] = *(ite1-1); --ite1; - if (it1 < ite1) - { it2 = vect_begin(l2); ++it2; std::copy(it1, ite1, it2); } - } - else { - ptrdiff_t m = it1.index() - it2.index(); - if (m >= 0 && ite1.index() <= ite2.index()) - std::copy(it1, ite1, it2 + m); - else { - if (m < 0) l2[it1.index()] = *it1; - if (ite1.index() > ite2.index()) l2[ite1.index()-1] = *(ite1-1); - it2 = vect_begin(l2); ite2 = vect_end(l2); - m = it1.index() - it2.index(); - std::copy(it1, ite1, it2 + m); - } - } - } - } - - template - void copy_vect(const L1& l1, L2& l2, abstract_sparse, abstract_dense) { - clear(l2); - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (; it != ite; ++it) { l2[it.index()] = *it; } - } - - template - void copy_vect(const L1& l1, L2& l2, abstract_sparse, abstract_skyline) { - clear(l2); - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (; it != ite; ++it) l2[it.index()] = *it; - } - - template - void copy_vect(const L1& l1, L2& l2, abstract_skyline, abstract_dense) { - typedef typename linalg_traits::value_type T; - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - if (it == ite) - gmm::clear(l2); - else { - auto it2 = vect_begin(l2), ite2 = vect_end(l2); - - size_type i = it.index(), j; - for (j = 0; j < i; ++j, ++it2) *it2 = T(0); - for (; it != ite; ++it, ++it2) *it2 = *it; - for (; it2 != ite2; ++it2) *it2 = T(0); - } - } - - template - void copy_vect(const L1& l1, L2& l2, abstract_sparse, abstract_sparse) { - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - clear(l2); - // cout << "copy " << l1 << " of size " << vect_size(l1) << " nnz = " << nnz(l1) << endl; - for (; it != ite; ++it) { - // cout << "*it = " << *it << endl; - // cout << "it.index() = " << it.index() << endl; - if (*it != (typename linalg_traits::value_type)(0)) - l2[it.index()] = *it; - } - } - - template - void copy_vect(const L1& l1, L2& l2, abstract_dense, abstract_sparse) { - clear(l2); - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (size_type i = 0; it != ite; ++it, ++i) - if (*it != (typename linalg_traits::value_type)(0)) - l2[i] = *it; - } - - template // to be optimised ... - void copy_vect(const L1& l1, L2& l2, abstract_dense, abstract_skyline) { - clear(l2); - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (size_type i = 0; it != ite; ++it, ++i) - if (*it != (typename linalg_traits::value_type)(0)) - l2[i] = *it; - } - - - template - void copy_vect(const L1& l1, L2& l2, abstract_skyline, abstract_sparse) { - clear(l2); - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (; it != ite; ++it) - if (*it != (typename linalg_traits::value_type)(0)) - l2[it.index()] = *it; - } - - /* ******************************************************************** */ - /* Matrix and vector addition */ - /* algorithms are built in order to avoid some conflicts with */ - /* repeated arguments or with overlapping part of a same object. */ - /* In the latter case, conflicts are still possible. */ - /* ******************************************************************** */ - ///@endcond - /** Add two vectors or matrices - @param l1 - @param l2 contains on output, l2+l1. - */ - template inline - void add(const L1& l1, L2& l2) { - add_spec(l1, l2, typename linalg_traits::linalg_type()); - } - ///@cond - - template inline - void add(const L1& l1, const L2& l2) { add(l1, linalg_const_cast(l2)); } - - template inline - void add_spec(const L1& l1, L2& l2, abstract_vector) { - GMM_ASSERT2(vect_size(l1) == vect_size(l2), "dimensions mismatch, " - << vect_size(l1) << " !=" << vect_size(l2)); - add(l1, l2, typename linalg_traits::storage_type(), - typename linalg_traits::storage_type()); - } - - template inline - void add_spec(const L1& l1, L2& l2, abstract_matrix) { - GMM_ASSERT2(mat_nrows(l1)==mat_nrows(l2) && mat_ncols(l1)==mat_ncols(l2), - "dimensions mismatch l1 is " << mat_nrows(l1) << "x" - << mat_ncols(l1) << " and l2 is " << mat_nrows(l2) - << "x" << mat_ncols(l2)); - add(l1, l2, typename linalg_traits::sub_orientation(), - typename linalg_traits::sub_orientation()); - } - - template - void add(const L1& l1, L2& l2, row_major, row_major) { - auto it1 = mat_row_begin(l1), ite = mat_row_end(l1); - auto it2 = mat_row_begin(l2); - for ( ; it1 != ite; ++it1, ++it2) - add(linalg_traits::row(it1), linalg_traits::row(it2)); - } - - template - void add(const L1& l1, L2& l2, col_major, col_major) { - auto it1 = mat_col_const_begin(l1), ite = mat_col_const_end(l1); - typename linalg_traits::col_iterator it2 = mat_col_begin(l2); - for ( ; it1 != ite; ++it1, ++it2) - add(linalg_traits::col(it1), linalg_traits::col(it2)); - } - - template inline - void add_mat_mixed_rc(const L1& l1, L2& l2, size_type i) { - add_mat_mixed_rc(l1, l2, i, typename linalg_traits::storage_type()); - } - - template - void add_mat_mixed_rc(const L1& l1, L2& l2, size_type i, abstract_sparse) { - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (; it != ite; ++it) l2(i, it.index()) += *it; - } - - template - void add_mat_mixed_rc(const L1& l1, L2& l2, size_type i, abstract_skyline) { - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (; it != ite; ++it) l2(i, it.index()) += *it; - } - - template - void add_mat_mixed_rc(const L1& l1, L2& l2, size_type i, abstract_dense) { - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (size_type j = 0; it != ite; ++it, ++j) l2(i, j) += *it; - } - - template inline - void add_mat_mixed_cr(const L1& l1, L2& l2, size_type i) { - add_mat_mixed_cr(l1, l2, i, typename linalg_traits::storage_type()); - } - - template - void add_mat_mixed_cr(const L1& l1, L2& l2, size_type i, abstract_sparse) { - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (; it != ite; ++it) l2(it.index(), i) += *it; - } - - template - void add_mat_mixed_cr(const L1& l1, L2& l2, size_type i, abstract_skyline) { - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (; it != ite; ++it) l2(it.index(), i) += *it; - } - - template - void add_mat_mixed_cr(const L1& l1, L2& l2, size_type i, abstract_dense) { - auto it = vect_const_begin(l1), ite = vect_const_end(l1); - for (size_type j = 0; it != ite; ++it, ++j) l2(j, i) += *it; - } - - template - void add(const L1& l1, L2& l2, row_major, col_major) { - size_type nbr = mat_nrows(l1); - for (size_type i = 0; i < nbr; ++i) - add_mat_mixed_rc(mat_const_row(l1, i), l2, i); - } - - template - void add(const L1& l1, L2& l2, col_major, row_major) { - size_type nbc = mat_ncols(l1); - for (size_type i = 0; i < nbc; ++i) - add_mat_mixed_cr(mat_const_col(l1, i), l2, i); - } - - template inline - void add(const L1& l1, L2& l2, row_and_col, row_major) - { add(l1, l2, row_major(), row_major()); } - - template inline - void add(const L1& l1, L2& l2, row_and_col, row_and_col) - { add(l1, l2, row_major(), row_major()); } - - template inline - void add(const L1& l1, L2& l2, row_and_col, col_and_row) - { add(l1, l2, row_major(), row_major()); } - - template inline - void add(const L1& l1, L2& l2, col_and_row, row_and_col) - { add(l1, l2, row_major(), row_major()); } - - template inline - void add(const L1& l1, L2& l2, row_major, row_and_col) - { add(l1, l2, row_major(), row_major()); } - - template inline - void add(const L1& l1, L2& l2, col_and_row, row_major) - { add(l1, l2, row_major(), row_major()); } - - template inline - void add(const L1& l1, L2& l2, row_major, col_and_row) - { add(l1, l2, row_major(), row_major()); } - - template inline - void add(const L1& l1, L2& l2, row_and_col, col_major) - { add(l1, l2, col_major(), col_major()); } - - template inline - void add(const L1& l1, L2& l2, col_major, row_and_col) - { add(l1, l2, col_major(), col_major()); } - - template inline - void add(const L1& l1, L2& l2, col_and_row, col_major) - { add(l1, l2, col_major(), col_major()); } - - template inline - void add(const L1& l1, L2& l2, col_and_row, col_and_row) - { add(l1, l2, col_major(), col_major()); } - - template inline - void add(const L1& l1, L2& l2, col_major, col_and_row) - { add(l1, l2, col_major(), col_major()); } - - ///@endcond - /** Addition of two vectors/matrices - @param l1 - @param l2 - @param l3 contains l1+l2 on output - */ - template inline - void add(const L1& l1, const L2& l2, L3& l3) { - add_spec(l1, l2, l3, typename linalg_traits::linalg_type()); - } - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - template inline - void add(const L1& l1, const L2& l2, const L3& l3) - { add(l1, l2, linalg_const_cast(l3)); } - - template inline - void add_spec(const L1& l1, const L2& l2, L3& l3, abstract_matrix) - { copy(l2, l3); add(l1, l3); } - - template inline - void add_spec(const L1& l1, const L2& l2, L3& l3, abstract_vector) { - GMM_ASSERT2(vect_size(l1) == vect_size(l2) && - vect_size(l1) == vect_size(l3), "dimensions mismatch"); - if ((const void *)(&l1) == (const void *)(&l3)) - add(l2, l3); - else if ((const void *)(&l2) == (const void *)(&l3)) - add(l1, l3); - else - add(l1, l2, l3, typename linalg_traits::storage_type(), - typename linalg_traits::storage_type(), - typename linalg_traits::storage_type()); - } - - template - void add_full_(IT1 it1, IT2 it2, IT3 it3, IT3 ite) { - for (; it3 != ite; ++it3, ++it2, ++it1) *it3 = *it1 + *it2; - } - - template - void add_almost_full_(IT1 it1, IT1 ite1, IT2 it2, IT3 it3, IT3 ite3) { - IT3 it = it3; - for (; it != ite3; ++it, ++it2) *it = *it2; - for (; it1 != ite1; ++it1) - *(it3 + it1.index()) += *it1; - } - - template - void add_to_full_(IT1 it1, IT1 ite1, IT2 it2, IT2 ite2, - IT3 it3, IT3 ite3) { - typedef typename std::iterator_traits::value_type T; - IT3 it = it3; - for (; it != ite3; ++it) *it = T(0); - for (; it1 != ite1; ++it1) *(it3 + it1.index()) = *it1; - for (; it2 != ite2; ++it2) *(it3 + it2.index()) += *it2; - } - - template inline - void add(const L1& l1, const L2& l2, L3& l3, - abstract_dense, abstract_dense, abstract_dense) { - add_full_(vect_const_begin(l1), vect_const_begin(l2), - vect_begin(l3), vect_end(l3)); - } - - // generic function for add(v1, v2, v3). - // Need to be specialized to optimize particular additions. - template - inline void add(const L1& l1, const L2& l2, L3& l3, ST1, ST2, ST3) - { copy(l2, l3); add(l1, l3, ST1(), ST3()); } - - template inline - void add(const L1& l1, const L2& l2, L3& l3, - abstract_sparse, abstract_dense, abstract_dense) { - add_almost_full_(vect_const_begin(l1), vect_const_end(l1), - vect_const_begin(l2), vect_begin(l3), vect_end(l3)); - } - - template inline - void add(const L1& l1, const L2& l2, L3& l3, - abstract_dense, abstract_sparse, abstract_dense) - { add(l2, l1, l3, abstract_sparse(), abstract_dense(), abstract_dense()); } - - template inline - void add(const L1& l1, const L2& l2, L3& l3, - abstract_sparse, abstract_sparse, abstract_dense) { - add_to_full_(vect_const_begin(l1), vect_const_end(l1), - vect_const_begin(l2), vect_const_end(l2), - vect_begin(l3), vect_end(l3)); - } - - - template - void add_spspsp(const L1& l1, const L2& l2, L3& l3, linalg_true) { - auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1); - auto it2 = vect_const_begin(l2), ite2 = vect_const_end(l2); - clear(l3); - while (it1 != ite1 && it2 != ite2) { - ptrdiff_t d = it1.index() - it2.index(); - if (d < 0) - { l3[it1.index()] += *it1; ++it1; } - else if (d > 0) - { l3[it2.index()] += *it2; ++it2; } - else - { l3[it1.index()] = *it1 + *it2; ++it1; ++it2; } - } - for (; it1 != ite1; ++it1) l3[it1.index()] += *it1; - for (; it2 != ite2; ++it2) l3[it2.index()] += *it2; - } - - template - void add_spspsp(const L1& l1, const L2& l2, L3& l3, linalg_false) - { copy(l2, l3); add(l2, l3); } - - template - void add(const L1& l1, const L2& l2, L3& l3, - abstract_sparse, abstract_sparse, abstract_sparse) { - add_spspsp(l1, l2, l3, typename linalg_and::index_sorted, - typename linalg_traits::index_sorted>::bool_type()); - } - - template - void add(const L1& l1, L2& l2, abstract_dense, abstract_dense) { - auto it1 = vect_const_begin(l1); - auto it2 = vect_begin(l2), ite = vect_end(l2); - for (; it2 != ite; ++it2, ++it1) *it2 += *it1; - } - - template - void add(const L1& l1, L2& l2, abstract_dense, abstract_skyline) { - typedef typename linalg_traits::value_type T; - - auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1); - size_type i1 = 0, ie1 = vect_size(l1); - while (it1 != ite1 && *it1 == T(0)) { ++it1; ++i1; } - if (it1 != ite1) { - auto it2 = vect_begin(l2), ite2 = vect_end(l2); - while (ie1 && *(ite1-1) == T(0)) { ite1--; --ie1; } - - if (it2 == ite2 || i1 < it2.index()) { - l2[i1] = *it1; ++i1; ++it1; - if (it1 == ite1) return; - it2 = vect_begin(l2); ite2 = vect_end(l2); - } - if (ie1 > ite2.index()) { - --ite1; l2[ie1 - 1] = *ite1; - it2 = vect_begin(l2); - } - it2 += i1 - it2.index(); - for (; it1 != ite1; ++it1, ++it2) { *it2 += *it1; } - } - } - - - template - void add(const L1& l1, L2& l2, abstract_skyline, abstract_dense) { - auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1); - if (it1 != ite1) { - auto it2 = vect_begin(l2); - it2 += it1.index(); - for (; it1 != ite1; ++it2, ++it1) *it2 += *it1; - } - } - - - template - void add(const L1& l1, L2& l2, abstract_sparse, abstract_dense) { - auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1); - for (; it1 != ite1; ++it1) l2[it1.index()] += *it1; - } - - template - void add(const L1& l1, L2& l2, abstract_sparse, abstract_sparse) { - auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1); - for (; it1 != ite1; ++it1) l2[it1.index()] += *it1; - } - - template - void add(const L1& l1, L2& l2, abstract_sparse, abstract_skyline) { - auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1); - for (; it1 != ite1; ++it1) l2[it1.index()] += *it1; - } - - - template - void add(const L1& l1, L2& l2, abstract_skyline, abstract_sparse) { - auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1); - for (; it1 != ite1; ++it1) - if (*it1 != typename linalg_traits::value_type(0)) - l2[it1.index()] += *it1; - } - - template - void add(const L1& l1, L2& l2, abstract_skyline, abstract_skyline) { - typedef typename linalg_traits::value_type T1; - typedef typename linalg_traits::value_type T2; - - auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1); - - while (it1 != ite1 && *it1 == T1(0)) ++it1; - if (ite1 != it1) { - auto it2 = vect_begin(l2), ite2 = vect_end(l2); - while (*(ite1-1) == T1(0)) ite1--; - if (it2 == ite2 || it1.index() < it2.index()) { - l2[it1.index()] = T2(0); - it2 = vect_begin(l2); ite2 = vect_end(l2); - } - if (ite1.index() > ite2.index()) { - l2[ite1.index() - 1] = T2(0); - it2 = vect_begin(l2); - } - it2 += it1.index() - it2.index(); - for (; it1 != ite1; ++it1, ++it2) *it2 += *it1; - } - } - - template - void add(const L1& l1, L2& l2, abstract_dense, abstract_sparse) { - auto it1 = vect_const_begin(l1), ite1 = vect_const_end(l1); - for (size_type i = 0; it1 != ite1; ++it1, ++i) - if (*it1 != typename linalg_traits::value_type(0)) l2[i] += *it1; - } - - /* ******************************************************************** */ - /* Matrix-vector mult */ - /* ******************************************************************** */ - ///@endcond - /** matrix-vector or matrix-matrix product. - @param l1 a matrix. - @param l2 a vector or matrix. - @param l3 the product l1*l2. - */ - template inline - void mult(const L1& l1, const L2& l2, L3& l3) { - mult_dispatch(l1, l2, l3, typename linalg_traits::linalg_type()); - } - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - template inline - void mult(const L1& l1, const L2& l2, const L3& l3) - { mult(l1, l2, linalg_const_cast(l3)); } - - template inline - void mult_dispatch(const L1& l1, const L2& l2, L3& l3, abstract_vector) { - size_type m = mat_nrows(l1), n = mat_ncols(l1); - if (!m || !n) { gmm::clear(l3); return; } - GMM_ASSERT2(n==vect_size(l2) && m==vect_size(l3), "dimensions mismatch"); - if (!same_origin(l2, l3)) - mult_spec(l1, l2, l3, typename principal_orientation_type::sub_orientation>::potype()); - else { - GMM_WARNING2("Warning, A temporary is used for mult\n"); - typename temporary_vector::vector_type temp(vect_size(l3)); - mult_spec(l1, l2, temp, typename principal_orientation_type::sub_orientation>::potype()); - copy(temp, l3); - } - } - - template - void mult_by_row(const L1& l1, const L2& l2, L3& l3, abstract_sparse) { - typedef typename linalg_traits::value_type T; - clear(l3); - size_type nr = mat_nrows(l1); - for (size_type i = 0; i < nr; ++i) { - T aux = vect_sp(mat_const_row(l1, i), l2); - if (aux != T(0)) l3[i] = aux; - } - } - - template - void mult_by_row(const L1& l1, const L2& l2, L3& l3, abstract_skyline) { - typedef typename linalg_traits::value_type T; - clear(l3); - size_type nr = mat_nrows(l1); - for (size_type i = 0; i < nr; ++i) { - T aux = vect_sp(mat_const_row(l1, i), l2); - if (aux != T(0)) l3[i] = aux; - } - } - - template - void mult_by_row(const L1& l1, const L2& l2, L3& l3, abstract_dense) { - typename linalg_traits::iterator it=vect_begin(l3), ite=vect_end(l3); - auto itr = mat_row_const_begin(l1); - for (; it != ite; ++it, ++itr) - *it = vect_sp(linalg_traits::row(itr), l2, - typename linalg_traits::storage_type(), - typename linalg_traits::storage_type()); - } - - template - void mult_by_col(const L1& l1, const L2& l2, L3& l3, abstract_dense) { - clear(l3); - size_type nc = mat_ncols(l1); - for (size_type i = 0; i < nc; ++i) - add(scaled(mat_const_col(l1, i), l2[i]), l3); - } - - template - void mult_by_col(const L1& l1, const L2& l2, L3& l3, abstract_sparse) { - typedef typename linalg_traits::value_type T; - clear(l3); - auto it = vect_const_begin(l2), ite = vect_const_end(l2); - for (; it != ite; ++it) - if (*it != T(0)) add(scaled(mat_const_col(l1, it.index()), *it), l3); - } - - template - void mult_by_col(const L1& l1, const L2& l2, L3& l3, abstract_skyline) { - typedef typename linalg_traits::value_type T; - clear(l3); - auto it = vect_const_begin(l2), ite = vect_const_end(l2); - for (; it != ite; ++it) - if (*it != T(0)) add(scaled(mat_const_col(l1, it.index()), *it), l3); - } - - template inline - void mult_spec(const L1& l1, const L2& l2, L3& l3, row_major) - { mult_by_row(l1, l2, l3, typename linalg_traits::storage_type()); } - - template inline - void mult_spec(const L1& l1, const L2& l2, L3& l3, col_major) - { mult_by_col(l1, l2, l3, typename linalg_traits::storage_type()); } - - template inline - void mult_spec(const L1& l1, const L2& l2, L3& l3, abstract_null_type) - { mult_ind(l1, l2, l3, typename linalg_traits::storage_type()); } - - template - void mult_ind(const L1& l1, const L2& l2, L3& l3, abstract_indirect) { - GMM_ASSERT1(false, "gmm::mult(m, ., .) undefined for this kind of matrix"); - } - - template inline - void mult(const L1& l1, const L2& l2, const L3& l3, L4& l4) { - size_type m = mat_nrows(l1), n = mat_ncols(l1); - copy(l3, l4); - if (!m || !n) { gmm::copy(l3, l4); return; } - GMM_ASSERT2(n==vect_size(l2) && m==vect_size(l4), "dimensions mismatch"); - if (!same_origin(l2, l4)) { - mult_add_spec(l1, l2, l4, typename principal_orientation_type::sub_orientation>::potype()); - } - else { - GMM_WARNING2("Warning, A temporary is used for mult\n"); - typename temporary_vector::vector_type temp(vect_size(l2)); - copy(l2, temp); - mult_add_spec(l1,temp, l4, typename principal_orientation_type::sub_orientation>::potype()); - } - } - - template inline - void mult(const L1& l1, const L2& l2, const L3& l3, const L4& l4) - { mult(l1, l2, l3, linalg_const_cast(l4)); } - - ///@endcond - /** Multiply-accumulate. l3 += l1*l2; */ - template inline - void mult_add(const L1& l1, const L2& l2, L3& l3) { - size_type m = mat_nrows(l1), n = mat_ncols(l1); - if (!m || !n) return; - GMM_ASSERT2(n==vect_size(l2) && m==vect_size(l3), "dimensions mismatch"); - if (!same_origin(l2, l3)) { - mult_add_spec(l1, l2, l3, typename principal_orientation_type::sub_orientation>::potype()); - } - else { - GMM_WARNING2("Warning, A temporary is used for mult\n"); - typename temporary_vector::vector_type temp(vect_size(l2)); - copy(l2, temp); - mult_add_spec(l1,temp, l3, typename principal_orientation_type::sub_orientation>::potype()); - } - } - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - template inline - void mult_add(const L1& l1, const L2& l2, const L3& l3) - { mult_add(l1, l2, linalg_const_cast(l3)); } - - template - void mult_add_by_row(const L1& l1, const L2& l2, L3& l3, abstract_sparse) { - typedef typename linalg_traits::value_type T; - size_type nr = mat_nrows(l1); - for (size_type i = 0; i < nr; ++i) { - T aux = vect_sp(mat_const_row(l1, i), l2); - if (aux != T(0)) l3[i] += aux; - } - } - - template - void mult_add_by_row(const L1& l1, const L2& l2, L3& l3, abstract_skyline) { - typedef typename linalg_traits::value_type T; - size_type nr = mat_nrows(l1); - for (size_type i = 0; i < nr; ++i) { - T aux = vect_sp(mat_const_row(l1, i), l2); - if (aux != T(0)) l3[i] += aux; - } - } - - template - void mult_add_by_row(const L1& l1, const L2& l2, L3& l3, abstract_dense) { - auto it=vect_begin(l3), ite=vect_end(l3); - auto itr = mat_row_const_begin(l1); - for (; it != ite; ++it, ++itr) - *it += vect_sp(linalg_traits::row(itr), l2); - } - - template - void mult_add_by_col(const L1& l1, const L2& l2, L3& l3, abstract_dense) { - size_type nc = mat_ncols(l1); - for (size_type i = 0; i < nc; ++i) - add(scaled(mat_const_col(l1, i), l2[i]), l3); - } - - template - void mult_add_by_col(const L1& l1, const L2& l2, L3& l3, abstract_sparse) { - auto it = vect_const_begin(l2), ite = vect_const_end(l2); - for (; it != ite; ++it) - if (*it != typename linalg_traits::value_type(0)) - add(scaled(mat_const_col(l1, it.index()), *it), l3); - } - - template - void mult_add_by_col(const L1& l1, const L2& l2, L3& l3, abstract_skyline) { - auto it = vect_const_begin(l2), ite = vect_const_end(l2); - for (; it != ite; ++it) - if (*it != typename linalg_traits::value_type(0)) - add(scaled(mat_const_col(l1, it.index()), *it), l3); - } - - template inline - void mult_add_spec(const L1& l1, const L2& l2, L3& l3, row_major) - { mult_add_by_row(l1, l2, l3, typename linalg_traits::storage_type()); } - - template inline - void mult_add_spec(const L1& l1, const L2& l2, L3& l3, col_major) - { mult_add_by_col(l1, l2, l3, typename linalg_traits::storage_type()); } - - template inline - void mult_add_spec(const L1& l1, const L2& l2, L3& l3, abstract_null_type) - { mult_ind(l1, l2, l3, typename linalg_traits::storage_type()); } - - template - void transposed_mult(const L1& l1, const L2& l2, const L3& l3) - { mult(gmm::transposed(l1), l2, l3); } - - - /* ******************************************************************** */ - /* Matrix-matrix mult */ - /* ******************************************************************** */ - - - struct g_mult {}; // generic mult, less optimized - struct c_mult {}; // col x col -> col mult - struct r_mult {}; // row x row -> row mult - struct rcmult {}; // row x col -> col mult - struct crmult {}; // col x row -> row mult - - - template struct mult_t; - #define DEFMU__ template<> struct mult_t - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef g_mult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef rcmult t; }; - DEFMU__ { typedef rcmult t; }; - DEFMU__ { typedef rcmult t; }; - DEFMU__ { typedef rcmult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef rcmult t; }; - DEFMU__ { typedef rcmult t; }; - DEFMU__ { typedef rcmult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef rcmult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef crmult t; }; - DEFMU__ { typedef g_mult t; }; - DEFMU__ { typedef crmult t; }; - DEFMU__ { typedef crmult t; }; - DEFMU__ { typedef g_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef crmult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef crmult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef rcmult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef rcmult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef rcmult t; }; - DEFMU__ { typedef rcmult t; }; - DEFMU__ { typedef rcmult t; }; - DEFMU__ { typedef rcmult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef c_mult t; }; - DEFMU__ { typedef r_mult t; }; - DEFMU__ { typedef r_mult t; }; - - template - void mult_dispatch(const L1& l1, const L2& l2, L3& l3, abstract_matrix) { - typedef typename temporary_matrix::matrix_type temp_mat_type; - size_type n = mat_ncols(l1); - if (n == 0) { gmm::clear(l3); return; } - GMM_ASSERT2(n == mat_nrows(l2) && mat_nrows(l1) == mat_nrows(l3) && - mat_ncols(l2) == mat_ncols(l3), "dimensions mismatch"); - - if (same_origin(l2, l3) || same_origin(l1, l3)) { - GMM_WARNING2("A temporary is used for mult"); - temp_mat_type temp(mat_nrows(l3), mat_ncols(l3)); - mult_spec(l1, l2, temp, typename mult_t< - typename linalg_traits::sub_orientation, - typename linalg_traits::sub_orientation, - typename linalg_traits::sub_orientation>::t()); - copy(temp, l3); - } - else - mult_spec(l1, l2, l3, typename mult_t< - typename linalg_traits::sub_orientation, - typename linalg_traits::sub_orientation, - typename linalg_traits::sub_orientation>::t()); - } - - // Completely generic but inefficient - - template - void mult_spec(const L1& l1, const L2& l2, L3& l3, g_mult) { - typedef typename linalg_traits::value_type T; - GMM_WARNING2("Inefficient generic matrix-matrix mult is used"); - for (size_type i = 0; i < mat_nrows(l3) ; ++i) - for (size_type j = 0; j < mat_ncols(l3) ; ++j) { - T a(0); - for (size_type k = 0; k < mat_nrows(l2) ; ++k) a += l1(i, k)*l2(k, j); - l3(i, j) = a; - } - } - - // row x col matrix-matrix mult - - template - void mult_row_col_with_temp(const L1& l1, const L2& l2, L3& l3, col_major) { - typedef typename temporary_col_matrix::matrix_type temp_col_mat; - temp_col_mat temp(mat_nrows(l1), mat_ncols(l1)); - copy(l1, temp); - mult(temp, l2, l3); - } - - template - void mult_row_col_with_temp(const L1& l1, const L2& l2, L3& l3, row_major) { - typedef typename temporary_row_matrix::matrix_type temp_row_mat; - temp_row_mat temp(mat_nrows(l2), mat_ncols(l2)); - copy(l2, temp); - mult(l1, temp, l3); - } - - template - void mult_spec(const L1& l1, const L2& l2, L3& l3, rcmult) { - if (is_sparse(l1) && is_sparse(l2)) { - GMM_WARNING3("Inefficient row matrix - col matrix mult for " - "sparse matrices, using temporary"); - mult_row_col_with_temp(l1, l2, l3, - typename principal_orientation_type::sub_orientation>::potype()); - } - else { - auto it2b = linalg_traits::col_begin(l2), it2 = it2b, - ite = linalg_traits::col_end(l2); - size_type i,j, k = mat_nrows(l1); - - for (i = 0; i < k; ++i) { - typename linalg_traits::const_sub_row_type r1=mat_const_row(l1, i); - for (it2 = it2b, j = 0; it2 != ite; ++it2, ++j) - l3(i,j) = vect_sp(r1, linalg_traits::col(it2)); - } - } - } - - // row - row matrix-matrix mult - - template inline - void mult_spec(const L1& l1, const L2& l2, L3& l3, r_mult) { - mult_spec(l1, l2, l3,r_mult(),typename linalg_traits::storage_type()); - } - - template - void mult_spec(const L1& l1, const L2& l2, L3& l3, r_mult, abstract_dense) { - // optimizable - clear(l3); - size_type nn = mat_nrows(l3), mm = mat_nrows(l2); - for (size_type i = 0; i < nn; ++i) { - for (size_type j = 0; j < mm; ++j) { - add(scaled(mat_const_row(l2, j), l1(i, j)), mat_row(l3, i)); - } - } - } - - template - void mult_spec(const L1& l1, const L2& l2, L3& l3, r_mult, abstract_sparse) { - // optimizable - clear(l3); - size_type nn = mat_nrows(l3); - for (size_type i = 0; i < nn; ++i) { - typename linalg_traits::const_sub_row_type rl1=mat_const_row(l1, i); - auto it = vect_const_begin(rl1), ite = vect_const_end(rl1); - for (; it != ite; ++it) - add(scaled(mat_const_row(l2, it.index()), *it), mat_row(l3, i)); - } - } - - template - void mult_spec(const L1& l1, const L2& l2, L3& l3, r_mult, abstract_skyline) - { mult_spec(l1, l2, l3, r_mult(), abstract_sparse()); } - - // col - col matrix-matrix mult - - template inline - void mult_spec(const L1& l1, const L2& l2, L3& l3, c_mult) { - mult_spec(l1, l2,l3,c_mult(),typename linalg_traits::storage_type(), - typename linalg_traits::sub_orientation()); - } - - - template - void mult_spec(const L1& l1, const L2& l2, L3& l3, c_mult, - abstract_dense, ORIEN) { - typedef typename linalg_traits::value_type T; - size_type nn = mat_ncols(l3), mm = mat_ncols(l1); - - for (size_type i = 0; i < nn; ++i) { - clear(mat_col(l3, i)); - for (size_type j = 0; j < mm; ++j) { - T b = l2(j, i); - if (b != T(0)) add(scaled(mat_const_col(l1, j), b), mat_col(l3, i)); - } - } - } - - template - void mult_spec(const L1& l1, const L2& l2, L3& l3, c_mult, - abstract_sparse, ORIEN) { - // optimizable - clear(l3); - size_type nn = mat_ncols(l3); - for (size_type i = 0; i < nn; ++i) { - typename linalg_traits::const_sub_col_type rc2 = mat_const_col(l2, i); - auto it = vect_const_begin(rc2), ite = vect_const_end(rc2); - for (; it != ite; ++it) - add(scaled(mat_const_col(l1, it.index()), *it), mat_col(l3, i)); - } - } - - template - void mult_spec(const L1& l1, const L2& l2, L3& l3, c_mult, - abstract_sparse, row_major) { - typedef typename linalg_traits::value_type T; - GMM_WARNING3("Inefficient matrix-matrix mult for sparse matrices"); - clear(l3); - size_type mm = mat_nrows(l2), nn = mat_ncols(l3); - for (size_type i = 0; i < nn; ++i) - for (size_type j = 0; j < mm; ++j) { - T a = l2(i,j); - if (a != T(0)) add(scaled(mat_const_col(l1, j), a), mat_col(l3, i)); - } - } - - template inline - void mult_spec(const L1& l1, const L2& l2, L3& l3, c_mult, - abstract_skyline, ORIEN) - { mult_spec(l1, l2, l3, c_mult(), abstract_sparse(), ORIEN()); } - - - // col - row matrix-matrix mult - - template inline - void mult_spec(const L1& l1, const L2& l2, L3& l3, crmult) - { mult_spec(l1,l2,l3,crmult(), typename linalg_traits::storage_type()); } - - - template - void mult_spec(const L1& l1, const L2& l2, L3& l3, crmult, abstract_dense) { - // optimizable - clear(l3); - size_type nn = mat_ncols(l1), mm = mat_nrows(l1); - for (size_type i = 0; i < nn; ++i) { - for (size_type j = 0; j < mm; ++j) - add(scaled(mat_const_row(l2, i), l1(j, i)), mat_row(l3, j)); - } - } - - template - void mult_spec(const L1& l1, const L2& l2, L3& l3, crmult, abstract_sparse) { - // optimizable - clear(l3); - size_type nn = mat_ncols(l1); - for (size_type i = 0; i < nn; ++i) { - typename linalg_traits::const_sub_col_type rc1 = mat_const_col(l1, i); - auto it = vect_const_begin(rc1), ite = vect_const_end(rc1); - for (; it != ite; ++it) - add(scaled(mat_const_row(l2, i), *it), mat_row(l3, it.index())); - } - } - - template inline - void mult_spec(const L1& l1, const L2& l2, L3& l3, crmult, abstract_skyline) - { mult_spec(l1, l2, l3, crmult(), abstract_sparse()); } - - - /* ******************************************************************** */ - /* Symmetry test. */ - /* ******************************************************************** */ - - ///@endcond - /** test if A is symmetric. - @param A a matrix. - @param tol a threshold. - */ - template inline - bool is_symmetric(const MAT &A, magnitude_of_linalg(MAT) tol - = magnitude_of_linalg(MAT)(-1)) { - typedef magnitude_of_linalg(MAT) R; - if (tol < R(0)) tol = default_tol(R()) * mat_maxnorm(A); - if (mat_nrows(A) != mat_ncols(A)) return false; - return is_symmetric(A, tol, typename linalg_traits::storage_type()); - } - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - template - bool is_symmetric(const MAT &A, magnitude_of_linalg(MAT) tol, - abstract_dense) { - size_type m = mat_nrows(A); - for (size_type i = 1; i < m; ++i) - for (size_type j = 0; j < i; ++j) - if (gmm::abs(A(i, j)-A(j, i)) > tol) return false; - return true; - } - - template - bool is_symmetric(const MAT &A, magnitude_of_linalg(MAT) tol, - abstract_sparse) { - return is_symmetric(A, tol, typename principal_orientation_type::sub_orientation>::potype()); - } - - template - bool is_symmetric(const MAT &A, magnitude_of_linalg(MAT) tol, - row_major) { - for (size_type i = 0; i < mat_nrows(A); ++i) { - typename linalg_traits::const_sub_row_type row = mat_const_row(A, i); - auto it = vect_const_begin(row), ite = vect_const_end(row); - for (; it != ite; ++it) - if (gmm::abs(*it - A(it.index(), i)) > tol) return false; - } - return true; - } - - template - bool is_symmetric(const MAT &A, magnitude_of_linalg(MAT) tol, - col_major) { - for (size_type i = 0; i < mat_ncols(A); ++i) { - typename linalg_traits::const_sub_col_type col = mat_const_col(A, i); - auto it = vect_const_begin(col), ite = vect_const_end(col); - for (; it != ite; ++it) - if (gmm::abs(*it - A(i, it.index())) > tol) return false; - } - return true; - } - - template - bool is_symmetric(const MAT &A, magnitude_of_linalg(MAT) tol, - abstract_skyline) - { return is_symmetric(A, tol, abstract_sparse()); } - - ///@endcond - /** test if A is Hermitian. - @param A a matrix. - @param tol a threshold. - */ - template inline - bool is_hermitian(const MAT &A, magnitude_of_linalg(MAT) tol - = magnitude_of_linalg(MAT)(-1)) { - typedef magnitude_of_linalg(MAT) R; - if (tol < R(0)) tol = default_tol(R()) * mat_maxnorm(A); - if (mat_nrows(A) != mat_ncols(A)) return false; - return is_hermitian(A, tol, typename linalg_traits::storage_type()); - } - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - template - bool is_hermitian(const MAT &A, magnitude_of_linalg(MAT) tol, - abstract_dense) { - size_type m = mat_nrows(A); - for (size_type i = 1; i < m; ++i) - for (size_type j = 0; j < i; ++j) - if (gmm::abs(A(i, j)-gmm::conj(A(j, i))) > tol) return false; - return true; - } - - template - bool is_hermitian(const MAT &A, magnitude_of_linalg(MAT) tol, - abstract_sparse) { - return is_hermitian(A, tol, typename principal_orientation_type::sub_orientation>::potype()); - } - - template - bool is_hermitian(const MAT &A, magnitude_of_linalg(MAT) tol, - row_major) { - for (size_type i = 0; i < mat_nrows(A); ++i) { - typename linalg_traits::const_sub_row_type row = mat_const_row(A, i); - auto it = vect_const_begin(row), ite = vect_const_end(row); - for (; it != ite; ++it) - if (gmm::abs(gmm::conj(*it) - A(it.index(), i)) > tol) return false; - } - return true; - } - - template - bool is_hermitian(const MAT &A, magnitude_of_linalg(MAT) tol, - col_major) { - for (size_type i = 0; i < mat_ncols(A); ++i) { - typename linalg_traits::const_sub_col_type col = mat_const_col(A, i); - auto it = vect_const_begin(col), ite = vect_const_end(col); - for (; it != ite; ++it) - if (gmm::abs(gmm::conj(*it) - A(i, it.index())) > tol) return false; - } - return true; - } - - template - bool is_hermitian(const MAT &A, magnitude_of_linalg(MAT) tol, - abstract_skyline) - { return is_hermitian(A, tol, abstract_sparse()); } - ///@endcond -} - - -#endif // GMM_BLAS_H__ diff --git a/gmm/gmm_blas_interface.h b/gmm/gmm_blas_interface.h deleted file mode 100644 index 8144293d5..000000000 --- a/gmm/gmm_blas_interface.h +++ /dev/null @@ -1,948 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_blas_interface.h - @author Yves Renard - @date October 7, 2003. - @brief gmm interface for fortran BLAS. -*/ - -#if defined(GETFEM_USES_BLAS) || defined(GMM_USES_BLAS) \ - || defined(GMM_USES_LAPACK) || defined(GMM_USES_ATLAS) - -#ifndef GMM_BLAS_INTERFACE_H -#define GMM_BLAS_INTERFACE_H - -#include "gmm_blas.h" -#include "gmm_interface.h" -#include "gmm_matrix.h" - -namespace gmm { - - // Use ./configure --enable-blas-interface to activate this interface. - -#define GMMLAPACK_TRACE(f) - // #define GMMLAPACK_TRACE(f) cout << "function " << f << " called" << endl; - - /* ********************************************************************* */ - /* Operations interfaced for T = float, double, std::complex */ - /* or std::complex : */ - /* */ - /* vect_norm2(std::vector) */ - /* */ - /* vect_sp(std::vector, std::vector) */ - /* vect_sp(scaled(std::vector), std::vector) */ - /* vect_sp(std::vector, scaled(std::vector)) */ - /* vect_sp(scaled(std::vector), scaled(std::vector)) */ - /* */ - /* vect_hp(std::vector, std::vector) */ - /* vect_hp(scaled(std::vector), std::vector) */ - /* vect_hp(std::vector, scaled(std::vector)) */ - /* vect_hp(scaled(std::vector), scaled(std::vector)) */ - /* */ - /* add(std::vector, std::vector) */ - /* add(scaled(std::vector, a), std::vector) */ - /* */ - /* mult(dense_matrix, dense_matrix, dense_matrix) */ - /* mult(transposed(dense_matrix), dense_matrix, dense_matrix) */ - /* mult(dense_matrix, transposed(dense_matrix), dense_matrix) */ - /* mult(transposed(dense_matrix), transposed(dense_matrix), */ - /* dense_matrix) */ - /* mult(conjugated(dense_matrix), dense_matrix, dense_matrix) */ - /* mult(dense_matrix, conjugated(dense_matrix), dense_matrix) */ - /* mult(conjugated(dense_matrix), conjugated(dense_matrix), */ - /* dense_matrix) */ - /* */ - /* mult(dense_matrix, std::vector, std::vector) */ - /* mult(transposed(dense_matrix), std::vector, std::vector) */ - /* mult(conjugated(dense_matrix), std::vector, std::vector) */ - /* mult(dense_matrix, scaled(std::vector), std::vector) */ - /* mult(transposed(dense_matrix), scaled(std::vector), */ - /* std::vector) */ - /* mult(conjugated(dense_matrix), scaled(std::vector), */ - /* std::vector) */ - /* */ - /* mult_add(dense_matrix, std::vector, std::vector) */ - /* mult_add(transposed(dense_matrix), std::vector, std::vector) */ - /* mult_add(conjugated(dense_matrix), std::vector, std::vector) */ - /* mult_add(dense_matrix, scaled(std::vector), std::vector) */ - /* mult_add(transposed(dense_matrix), scaled(std::vector), */ - /* std::vector) */ - /* mult_add(conjugated(dense_matrix), scaled(std::vector), */ - /* std::vector) */ - /* */ - /* mult(dense_matrix, std::vector, std::vector, std::vector) */ - /* mult(transposed(dense_matrix), std::vector, std::vector, */ - /* std::vector) */ - /* mult(conjugated(dense_matrix), std::vector, std::vector, */ - /* std::vector) */ - /* mult(dense_matrix, scaled(std::vector), std::vector, */ - /* std::vector) */ - /* mult(transposed(dense_matrix), scaled(std::vector), */ - /* std::vector, std::vector) */ - /* mult(conjugated(dense_matrix), scaled(std::vector), */ - /* std::vector, std::vector) */ - /* mult(dense_matrix, std::vector, scaled(std::vector), */ - /* std::vector) */ - /* mult(transposed(dense_matrix), std::vector, */ - /* scaled(std::vector), std::vector) */ - /* mult(conjugated(dense_matrix), std::vector, */ - /* scaled(std::vector), std::vector) */ - /* mult(dense_matrix, scaled(std::vector), scaled(std::vector), */ - /* std::vector) */ - /* mult(transposed(dense_matrix), scaled(std::vector), */ - /* scaled(std::vector), std::vector) */ - /* mult(conjugated(dense_matrix), scaled(std::vector), */ - /* scaled(std::vector), std::vector) */ - /* */ - /* lower_tri_solve(dense_matrix, std::vector, k, b) */ - /* upper_tri_solve(dense_matrix, std::vector, k, b) */ - /* lower_tri_solve(transposed(dense_matrix), std::vector, k, b) */ - /* upper_tri_solve(transposed(dense_matrix), std::vector, k, b) */ - /* lower_tri_solve(conjugated(dense_matrix), std::vector, k, b) */ - /* upper_tri_solve(conjugated(dense_matrix), std::vector, k, b) */ - /* */ - /* rank_one_update(dense_matrix, std::vector, std::vector) */ - /* rank_one_update(dense_matrix, scaled(std::vector), */ - /* std::vector) */ - /* rank_one_update(dense_matrix, std::vector, */ - /* scaled(std::vector)) */ - /* */ - /* ********************************************************************* */ - - /* ********************************************************************* */ - /* Basic defines. */ - /* ********************************************************************* */ - -# define BLAS_S float -# define BLAS_D double -# define BLAS_C std::complex -# define BLAS_Z std::complex - - /* ********************************************************************* */ - /* BLAS functions used. */ - /* ********************************************************************* */ - extern "C" { - void daxpy_(const long *n, const double *alpha, const double *x, - const long *incx, double *y, const long *incy); - void dgemm_(const char *tA, const char *tB, const long *m, - const long *n, const long *k, const double *alpha, - const double *A, const long *ldA, const double *B, - const long *ldB, const double *beta, double *C, - const long *ldC); - void sgemm_(...); void cgemm_(...); void zgemm_(...); - void sgemv_(...); void dgemv_(...); void cgemv_(...); void zgemv_(...); - void strsv_(...); void dtrsv_(...); void ctrsv_(...); void ztrsv_(...); - void saxpy_(...); /*void daxpy_(...); */void caxpy_(...); void zaxpy_(...); - BLAS_S sdot_ (...); BLAS_D ddot_ (...); - BLAS_C cdotu_(...); BLAS_Z zdotu_(...); - BLAS_C cdotc_(...); BLAS_Z zdotc_(...); - BLAS_S snrm2_(...); BLAS_D dnrm2_(...); - BLAS_S scnrm2_(...); BLAS_D dznrm2_(...); - void sger_(...); void dger_(...); void cgerc_(...); void zgerc_(...); - } - -#if 1 - - /* ********************************************************************* */ - /* vect_norm2(x). */ - /* ********************************************************************* */ - -# define nrm2_interface(param1, trans1, blas_name, base_type) \ - inline number_traits::magnitude_type \ - vect_norm2(param1(base_type)) { \ - GMMLAPACK_TRACE("nrm2_interface"); \ - long inc(1), n(long(vect_size(x))); trans1(base_type); \ - return blas_name(&n, &x[0], &inc); \ - } - -# define nrm2_p1(base_type) const std::vector &x -# define nrm2_trans1(base_type) - - nrm2_interface(nrm2_p1, nrm2_trans1, snrm2_ , BLAS_S) - nrm2_interface(nrm2_p1, nrm2_trans1, dnrm2_ , BLAS_D) - nrm2_interface(nrm2_p1, nrm2_trans1, scnrm2_, BLAS_C) - nrm2_interface(nrm2_p1, nrm2_trans1, dznrm2_, BLAS_Z) - - /* ********************************************************************* */ - /* vect_sp(x, y). */ - /* ********************************************************************* */ - -# define dot_interface(param1, trans1, mult1, param2, trans2, mult2, \ - blas_name, base_type) \ - inline base_type vect_sp(param1(base_type), param2(base_type)) { \ - GMMLAPACK_TRACE("dot_interface"); \ - trans1(base_type); trans2(base_type); long inc(1), n(long(vect_size(y)));\ - return mult1 mult2 blas_name(&n, &x[0], &inc, &y[0], &inc); \ - } - -# define dot_p1(base_type) const std::vector &x -# define dot_trans1(base_type) -# define dot_p1_s(base_type) \ - const scaled_vector_const_ref, base_type > &x_ -# define dot_trans1_s(base_type) \ - std::vector &x = \ - const_cast &>(*(linalg_origin(x_))); \ - base_type a(x_.r) - -# define dot_p2(base_type) const std::vector &y -# define dot_trans2(base_type) -# define dot_p2_s(base_type) \ - const scaled_vector_const_ref, base_type > &y_ -# define dot_trans2_s(base_type) \ - std::vector &y = \ - const_cast &>(*(linalg_origin(y_))); \ - base_type b(y_.r) - - dot_interface(dot_p1, dot_trans1, (BLAS_S), dot_p2, dot_trans2, (BLAS_S), - sdot_ , BLAS_S) - dot_interface(dot_p1, dot_trans1, (BLAS_D), dot_p2, dot_trans2, (BLAS_D), - ddot_ , BLAS_D) - dot_interface(dot_p1, dot_trans1, (BLAS_C), dot_p2, dot_trans2, (BLAS_C), - cdotu_, BLAS_C) - dot_interface(dot_p1, dot_trans1, (BLAS_Z), dot_p2, dot_trans2, (BLAS_Z), - zdotu_, BLAS_Z) - - dot_interface(dot_p1_s, dot_trans1_s, a*, dot_p2, dot_trans2, (BLAS_S), - sdot_ ,BLAS_S) - dot_interface(dot_p1_s, dot_trans1_s, a*, dot_p2, dot_trans2, (BLAS_D), - ddot_ ,BLAS_D) - dot_interface(dot_p1_s, dot_trans1_s, a*, dot_p2, dot_trans2, (BLAS_C), - cdotu_,BLAS_C) - dot_interface(dot_p1_s, dot_trans1_s, a*, dot_p2, dot_trans2, (BLAS_Z), - zdotu_,BLAS_Z) - - dot_interface(dot_p1, dot_trans1, (BLAS_S), dot_p2_s, dot_trans2_s, b*, - sdot_ ,BLAS_S) - dot_interface(dot_p1, dot_trans1, (BLAS_D), dot_p2_s, dot_trans2_s, b*, - ddot_ ,BLAS_D) - dot_interface(dot_p1, dot_trans1, (BLAS_C), dot_p2_s, dot_trans2_s, b*, - cdotu_,BLAS_C) - dot_interface(dot_p1, dot_trans1, (BLAS_Z), dot_p2_s, dot_trans2_s, b*, - zdotu_,BLAS_Z) - - dot_interface(dot_p1_s,dot_trans1_s,a*,dot_p2_s,dot_trans2_s,b*,sdot_ , - BLAS_S) - dot_interface(dot_p1_s,dot_trans1_s,a*,dot_p2_s,dot_trans2_s,b*,ddot_ , - BLAS_D) - dot_interface(dot_p1_s,dot_trans1_s,a*,dot_p2_s,dot_trans2_s,b*,cdotu_, - BLAS_C) - dot_interface(dot_p1_s,dot_trans1_s,a*,dot_p2_s,dot_trans2_s,b*,zdotu_, - BLAS_Z) - - - /* ********************************************************************* */ - /* vect_hp(x, y). */ - /* ********************************************************************* */ - -# define dotc_interface(param1, trans1, mult1, param2, trans2, mult2, \ - blas_name, base_type) \ - inline base_type vect_hp(param1(base_type), param2(base_type)) { \ - GMMLAPACK_TRACE("dotc_interface"); \ - trans1(base_type); trans2(base_type); long inc(1), n(long(vect_size(y)));\ - return mult1 mult2 blas_name(&n, &x[0], &inc, &y[0], &inc); \ - } - -# define dotc_p1(base_type) const std::vector &x -# define dotc_trans1(base_type) -# define dotc_p1_s(base_type) \ - const scaled_vector_const_ref, base_type > &x_ -# define dotc_trans1_s(base_type) \ - std::vector &x = \ - const_cast &>(*(linalg_origin(x_))); \ - base_type a(x_.r) - -# define dotc_p2(base_type) const std::vector &y -# define dotc_trans2(base_type) -# define dotc_p2_s(base_type) \ - const scaled_vector_const_ref, base_type > &y_ -# define dotc_trans2_s(base_type) \ - std::vector &y = \ - const_cast &>(*(linalg_origin(y_))); \ - base_type b(gmm::conj(y_.r)) - - dotc_interface(dotc_p1, dotc_trans1, (BLAS_S), dotc_p2, dotc_trans2, - (BLAS_S),sdot_ ,BLAS_S) - dotc_interface(dotc_p1, dotc_trans1, (BLAS_D), dotc_p2, dotc_trans2, - (BLAS_D),ddot_ ,BLAS_D) - dotc_interface(dotc_p1, dotc_trans1, (BLAS_C), dotc_p2, dotc_trans2, - (BLAS_C),cdotc_,BLAS_C) - dotc_interface(dotc_p1, dotc_trans1, (BLAS_Z), dotc_p2, dotc_trans2, - (BLAS_Z),zdotc_,BLAS_Z) - - dotc_interface(dotc_p1_s, dotc_trans1_s, a*, dotc_p2, dotc_trans2, - (BLAS_S),sdot_, BLAS_S) - dotc_interface(dotc_p1_s, dotc_trans1_s, a*, dotc_p2, dotc_trans2, - (BLAS_D),ddot_ , BLAS_D) - dotc_interface(dotc_p1_s, dotc_trans1_s, a*, dotc_p2, dotc_trans2, - (BLAS_C),cdotc_, BLAS_C) - dotc_interface(dotc_p1_s, dotc_trans1_s, a*, dotc_p2, dotc_trans2, - (BLAS_Z),zdotc_, BLAS_Z) - - dotc_interface(dotc_p1, dotc_trans1, (BLAS_S), dotc_p2_s, dotc_trans2_s, - b*,sdot_ , BLAS_S) - dotc_interface(dotc_p1, dotc_trans1, (BLAS_D), dotc_p2_s, dotc_trans2_s, - b*,ddot_ , BLAS_D) - dotc_interface(dotc_p1, dotc_trans1, (BLAS_C), dotc_p2_s, dotc_trans2_s, - b*,cdotc_, BLAS_C) - dotc_interface(dotc_p1, dotc_trans1, (BLAS_Z), dotc_p2_s, dotc_trans2_s, - b*,zdotc_, BLAS_Z) - - dotc_interface(dotc_p1_s,dotc_trans1_s,a*,dotc_p2_s,dotc_trans2_s,b*,sdot_ , - BLAS_S) - dotc_interface(dotc_p1_s,dotc_trans1_s,a*,dotc_p2_s,dotc_trans2_s,b*,ddot_ , - BLAS_D) - dotc_interface(dotc_p1_s,dotc_trans1_s,a*,dotc_p2_s,dotc_trans2_s,b*,cdotc_, - BLAS_C) - dotc_interface(dotc_p1_s,dotc_trans1_s,a*,dotc_p2_s,dotc_trans2_s,b*,zdotc_, - BLAS_Z) - - /* ********************************************************************* */ - /* add(x, y). */ - /* ********************************************************************* */ - -# define axpy_interface(param1, trans1, blas_name, base_type) \ - inline void add(param1(base_type), std::vector &y) { \ - GMMLAPACK_TRACE("axpy_interface"); \ - long inc(1), n(long(vect_size(y))); trans1(base_type); \ - if (n == 0) return; \ - blas_name(&n, &a, &x[0], &inc, &y[0], &inc); \ - } - -# define axpy_p1(base_type) const std::vector &x -# define axpy_trans1(base_type) base_type a(1) -# define axpy_p1_s(base_type) \ - const scaled_vector_const_ref, base_type > &x_ -# define axpy_trans1_s(base_type) \ - std::vector &x = \ - const_cast &>(*(linalg_origin(x_))); \ - base_type a(x_.r) - - axpy_interface(axpy_p1, axpy_trans1, saxpy_, BLAS_S) - axpy_interface(axpy_p1, axpy_trans1, daxpy_, BLAS_D) - axpy_interface(axpy_p1, axpy_trans1, caxpy_, BLAS_C) - axpy_interface(axpy_p1, axpy_trans1, zaxpy_, BLAS_Z) - - axpy_interface(axpy_p1_s, axpy_trans1_s, saxpy_, BLAS_S) - axpy_interface(axpy_p1_s, axpy_trans1_s, daxpy_, BLAS_D) - axpy_interface(axpy_p1_s, axpy_trans1_s, caxpy_, BLAS_C) - axpy_interface(axpy_p1_s, axpy_trans1_s, zaxpy_, BLAS_Z) - - - /* ********************************************************************* */ - /* mult_add(A, x, z). */ - /* ********************************************************************* */ - -# define gemv_interface(param1, trans1, param2, trans2, blas_name, \ - base_type, orien) \ - inline void mult_add_spec(param1(base_type), param2(base_type), \ - std::vector &z, orien) { \ - GMMLAPACK_TRACE("gemv_interface"); \ - trans1(base_type); trans2(base_type); base_type beta(1); \ - long m(long(mat_nrows(A))), lda(m), n(long(mat_ncols(A))), inc(1); \ - if (m && n) blas_name(&t, &m, &n, &alpha, &A(0,0), &lda, &x[0], &inc, \ - &beta, &z[0], &inc); \ - else gmm::clear(z); \ - } - - // First parameter -# define gem_p1_n(base_type) const dense_matrix &A -# define gem_trans1_n(base_type) const char t = 'N' -# define gem_p1_t(base_type) \ - const transposed_col_ref *> &A_ -# define gem_trans1_t(base_type) dense_matrix &A = \ - const_cast &>(*(linalg_origin(A_))); \ - const char t = 'T' -# define gem_p1_tc(base_type) \ - const transposed_col_ref *> &A_ -# define gem_p1_c(base_type) \ - const conjugated_col_matrix_const_ref > &A_ -# define gem_trans1_c(base_type) dense_matrix &A = \ - const_cast &>(*(linalg_origin(A_))); \ - const char t = 'C' - - // second parameter -# define gemv_p2_n(base_type) const std::vector &x -# define gemv_trans2_n(base_type) base_type alpha(1) -# define gemv_p2_s(base_type) \ - const scaled_vector_const_ref, base_type > &x_ -# define gemv_trans2_s(base_type) std::vector &x = \ - const_cast &>(*(linalg_origin(x_))); \ - base_type alpha(x_.r) - - // Z <- AX + Z. - gemv_interface(gem_p1_n, gem_trans1_n, gemv_p2_n, gemv_trans2_n, sgemv_, - BLAS_S, col_major) - gemv_interface(gem_p1_n, gem_trans1_n, gemv_p2_n, gemv_trans2_n, dgemv_, - BLAS_D, col_major) - gemv_interface(gem_p1_n, gem_trans1_n, gemv_p2_n, gemv_trans2_n, cgemv_, - BLAS_C, col_major) - gemv_interface(gem_p1_n, gem_trans1_n, gemv_p2_n, gemv_trans2_n, zgemv_, - BLAS_Z, col_major) - - // Z <- transposed(A)X + Z. - gemv_interface(gem_p1_t, gem_trans1_t, gemv_p2_n, gemv_trans2_n, sgemv_, - BLAS_S, row_major) - gemv_interface(gem_p1_t, gem_trans1_t, gemv_p2_n, gemv_trans2_n, dgemv_, - BLAS_D, row_major) - gemv_interface(gem_p1_t, gem_trans1_t, gemv_p2_n, gemv_trans2_n, cgemv_, - BLAS_C, row_major) - gemv_interface(gem_p1_t, gem_trans1_t, gemv_p2_n, gemv_trans2_n, zgemv_, - BLAS_Z, row_major) - - // Z <- transposed(const A)X + Z. - gemv_interface(gem_p1_tc, gem_trans1_t, gemv_p2_n, gemv_trans2_n, sgemv_, - BLAS_S, row_major) - gemv_interface(gem_p1_tc, gem_trans1_t, gemv_p2_n, gemv_trans2_n, dgemv_, - BLAS_D, row_major) - gemv_interface(gem_p1_tc, gem_trans1_t, gemv_p2_n, gemv_trans2_n, cgemv_, - BLAS_C, row_major) - gemv_interface(gem_p1_tc, gem_trans1_t, gemv_p2_n, gemv_trans2_n, zgemv_, - BLAS_Z, row_major) - - // Z <- conjugated(A)X + Z. - gemv_interface(gem_p1_c, gem_trans1_c, gemv_p2_n, gemv_trans2_n, sgemv_, - BLAS_S, row_major) - gemv_interface(gem_p1_c, gem_trans1_c, gemv_p2_n, gemv_trans2_n, dgemv_, - BLAS_D, row_major) - gemv_interface(gem_p1_c, gem_trans1_c, gemv_p2_n, gemv_trans2_n, cgemv_, - BLAS_C, row_major) - gemv_interface(gem_p1_c, gem_trans1_c, gemv_p2_n, gemv_trans2_n, zgemv_, - BLAS_Z, row_major) - - // Z <- A scaled(X) + Z. - gemv_interface(gem_p1_n, gem_trans1_n, gemv_p2_s, gemv_trans2_s, sgemv_, - BLAS_S, col_major) - gemv_interface(gem_p1_n, gem_trans1_n, gemv_p2_s, gemv_trans2_s, dgemv_, - BLAS_D, col_major) - gemv_interface(gem_p1_n, gem_trans1_n, gemv_p2_s, gemv_trans2_s, cgemv_, - BLAS_C, col_major) - gemv_interface(gem_p1_n, gem_trans1_n, gemv_p2_s, gemv_trans2_s, zgemv_, - BLAS_Z, col_major) - - // Z <- transposed(A) scaled(X) + Z. - gemv_interface(gem_p1_t, gem_trans1_t, gemv_p2_s, gemv_trans2_s, sgemv_, - BLAS_S, row_major) - gemv_interface(gem_p1_t, gem_trans1_t, gemv_p2_s, gemv_trans2_s, dgemv_, - BLAS_D, row_major) - gemv_interface(gem_p1_t, gem_trans1_t, gemv_p2_s, gemv_trans2_s, cgemv_, - BLAS_C, row_major) - gemv_interface(gem_p1_t, gem_trans1_t, gemv_p2_s, gemv_trans2_s, zgemv_, - BLAS_Z, row_major) - - // Z <- transposed(const A) scaled(X) + Z. - gemv_interface(gem_p1_tc, gem_trans1_t, gemv_p2_s, gemv_trans2_s, sgemv_, - BLAS_S, row_major) - gemv_interface(gem_p1_tc, gem_trans1_t, gemv_p2_s, gemv_trans2_s, dgemv_, - BLAS_D, row_major) - gemv_interface(gem_p1_tc, gem_trans1_t, gemv_p2_s, gemv_trans2_s, cgemv_, - BLAS_C, row_major) - gemv_interface(gem_p1_tc, gem_trans1_t, gemv_p2_s, gemv_trans2_s, zgemv_, - BLAS_Z, row_major) - - // Z <- conjugated(A) scaled(X) + Z. - gemv_interface(gem_p1_c, gem_trans1_c, gemv_p2_s, gemv_trans2_s, sgemv_, - BLAS_S, row_major) - gemv_interface(gem_p1_c, gem_trans1_c, gemv_p2_s, gemv_trans2_s, dgemv_, - BLAS_D, row_major) - gemv_interface(gem_p1_c, gem_trans1_c, gemv_p2_s, gemv_trans2_s, cgemv_, - BLAS_C, row_major) - gemv_interface(gem_p1_c, gem_trans1_c, gemv_p2_s, gemv_trans2_s, zgemv_, - BLAS_Z, row_major) - - - /* ********************************************************************* */ - /* mult(A, x, y). */ - /* ********************************************************************* */ - -# define gemv_interface2(param1, trans1, param2, trans2, blas_name, \ - base_type, orien) \ - inline void mult_spec(param1(base_type), param2(base_type), \ - std::vector &z, orien) { \ - GMMLAPACK_TRACE("gemv_interface2"); \ - trans1(base_type); trans2(base_type); base_type beta(0); \ - long m(long(mat_nrows(A))), lda(m), n(long(mat_ncols(A))), inc(1); \ - if (m && n) \ - blas_name(&t, &m, &n, &alpha, &A(0,0), &lda, &x[0], &inc, &beta, \ - &z[0], &inc); \ - else gmm::clear(z); \ - } - - // Y <- AX. - gemv_interface2(gem_p1_n, gem_trans1_n, gemv_p2_n, gemv_trans2_n, sgemv_, - BLAS_S, col_major) - gemv_interface2(gem_p1_n, gem_trans1_n, gemv_p2_n, gemv_trans2_n, dgemv_, - BLAS_D, col_major) - gemv_interface2(gem_p1_n, gem_trans1_n, gemv_p2_n, gemv_trans2_n, cgemv_, - BLAS_C, col_major) - gemv_interface2(gem_p1_n, gem_trans1_n, gemv_p2_n, gemv_trans2_n, zgemv_, - BLAS_Z, col_major) - - // Y <- transposed(A)X. - gemv_interface2(gem_p1_t, gem_trans1_t, gemv_p2_n, gemv_trans2_n, sgemv_, - BLAS_S, row_major) - gemv_interface2(gem_p1_t, gem_trans1_t, gemv_p2_n, gemv_trans2_n, dgemv_, - BLAS_D, row_major) - gemv_interface2(gem_p1_t, gem_trans1_t, gemv_p2_n, gemv_trans2_n, cgemv_, - BLAS_C, row_major) - gemv_interface2(gem_p1_t, gem_trans1_t, gemv_p2_n, gemv_trans2_n, zgemv_, - BLAS_Z, row_major) - - // Y <- transposed(const A)X. - gemv_interface2(gem_p1_tc, gem_trans1_t, gemv_p2_n, gemv_trans2_n, sgemv_, - BLAS_S, row_major) - gemv_interface2(gem_p1_tc, gem_trans1_t, gemv_p2_n, gemv_trans2_n, dgemv_, - BLAS_D, row_major) - gemv_interface2(gem_p1_tc, gem_trans1_t, gemv_p2_n, gemv_trans2_n, cgemv_, - BLAS_C, row_major) - gemv_interface2(gem_p1_tc, gem_trans1_t, gemv_p2_n, gemv_trans2_n, zgemv_, - BLAS_Z, row_major) - - // Y <- conjugated(A)X. - gemv_interface2(gem_p1_c, gem_trans1_c, gemv_p2_n, gemv_trans2_n, sgemv_, - BLAS_S, row_major) - gemv_interface2(gem_p1_c, gem_trans1_c, gemv_p2_n, gemv_trans2_n, dgemv_, - BLAS_D, row_major) - gemv_interface2(gem_p1_c, gem_trans1_c, gemv_p2_n, gemv_trans2_n, cgemv_, - BLAS_C, row_major) - gemv_interface2(gem_p1_c, gem_trans1_c, gemv_p2_n, gemv_trans2_n, zgemv_, - BLAS_Z, row_major) - - // Y <- A scaled(X). - gemv_interface2(gem_p1_n, gem_trans1_n, gemv_p2_s, gemv_trans2_s, sgemv_, - BLAS_S, col_major) - gemv_interface2(gem_p1_n, gem_trans1_n, gemv_p2_s, gemv_trans2_s, dgemv_, - BLAS_D, col_major) - gemv_interface2(gem_p1_n, gem_trans1_n, gemv_p2_s, gemv_trans2_s, cgemv_, - BLAS_C, col_major) - gemv_interface2(gem_p1_n, gem_trans1_n, gemv_p2_s, gemv_trans2_s, zgemv_, - BLAS_Z, col_major) - - // Y <- transposed(A) scaled(X). - gemv_interface2(gem_p1_t, gem_trans1_t, gemv_p2_s, gemv_trans2_s, sgemv_, - BLAS_S, row_major) - gemv_interface2(gem_p1_t, gem_trans1_t, gemv_p2_s, gemv_trans2_s, dgemv_, - BLAS_D, row_major) - gemv_interface2(gem_p1_t, gem_trans1_t, gemv_p2_s, gemv_trans2_s, cgemv_, - BLAS_C, row_major) - gemv_interface2(gem_p1_t, gem_trans1_t, gemv_p2_s, gemv_trans2_s, zgemv_, - BLAS_Z, row_major) - - // Y <- transposed(const A) scaled(X). - gemv_interface2(gem_p1_tc, gem_trans1_t, gemv_p2_s, gemv_trans2_s, sgemv_, - BLAS_S, row_major) - gemv_interface2(gem_p1_tc, gem_trans1_t, gemv_p2_s, gemv_trans2_s, dgemv_, - BLAS_D, row_major) - gemv_interface2(gem_p1_tc, gem_trans1_t, gemv_p2_s, gemv_trans2_s, cgemv_, - BLAS_C, row_major) - gemv_interface2(gem_p1_tc, gem_trans1_t, gemv_p2_s, gemv_trans2_s, zgemv_, - BLAS_Z, row_major) - - // Y <- conjugated(A) scaled(X). - gemv_interface2(gem_p1_c, gem_trans1_c, gemv_p2_s, gemv_trans2_s, sgemv_, - BLAS_S, row_major) - gemv_interface2(gem_p1_c, gem_trans1_c, gemv_p2_s, gemv_trans2_s, dgemv_, - BLAS_D, row_major) - gemv_interface2(gem_p1_c, gem_trans1_c, gemv_p2_s, gemv_trans2_s, cgemv_, - BLAS_C, row_major) - gemv_interface2(gem_p1_c, gem_trans1_c, gemv_p2_s, gemv_trans2_s, zgemv_, - BLAS_Z, row_major) - - - /* ********************************************************************* */ - /* Rank one update. */ - /* ********************************************************************* */ - -# define ger_interface(blas_name, base_type) \ - inline void rank_one_update(const dense_matrix &A, \ - const std::vector &V, \ - const std::vector &W) { \ - GMMLAPACK_TRACE("ger_interface"); \ - long m(long(mat_nrows(A))), lda = m, n(long(mat_ncols(A))); \ - long incx = 1, incy = 1; \ - base_type alpha(1); \ - if (m && n) \ - blas_name(&m, &n, &alpha, &V[0], &incx, &W[0], &incy, &A(0,0), &lda);\ - } - - ger_interface(sger_, BLAS_S) - ger_interface(dger_, BLAS_D) - ger_interface(cgerc_, BLAS_C) - ger_interface(zgerc_, BLAS_Z) - -# define ger_interface_sn(blas_name, base_type) \ - inline void rank_one_update(const dense_matrix &A, \ - gemv_p2_s(base_type), \ - const std::vector &W) { \ - GMMLAPACK_TRACE("ger_interface"); \ - gemv_trans2_s(base_type); \ - long m(long(mat_nrows(A))), lda = m, n(long(mat_ncols(A))); \ - long incx = 1, incy = 1; \ - if (m && n) \ - blas_name(&m, &n, &alpha, &x[0], &incx, &W[0], &incy, &A(0,0), &lda);\ - } - - ger_interface_sn(sger_, BLAS_S) - ger_interface_sn(dger_, BLAS_D) - ger_interface_sn(cgerc_, BLAS_C) - ger_interface_sn(zgerc_, BLAS_Z) - -# define ger_interface_ns(blas_name, base_type) \ - inline void rank_one_update(const dense_matrix &A, \ - const std::vector &V, \ - gemv_p2_s(base_type)) { \ - GMMLAPACK_TRACE("ger_interface"); \ - gemv_trans2_s(base_type); \ - long m(long(mat_nrows(A))), lda = m, n(long(mat_ncols(A))); \ - long incx = 1, incy = 1; \ - base_type al2 = gmm::conj(alpha); \ - if (m && n) \ - blas_name(&m, &n, &al2, &V[0], &incx, &x[0], &incy, &A(0,0), &lda); \ - } - - ger_interface_ns(sger_, BLAS_S) - ger_interface_ns(dger_, BLAS_D) - ger_interface_ns(cgerc_, BLAS_C) - ger_interface_ns(zgerc_, BLAS_Z) - - /* ********************************************************************* */ - /* dense matrix x dense matrix multiplication. */ - /* ********************************************************************* */ - -# define gemm_interface_nn(blas_name, base_type) \ - inline void mult_spec(const dense_matrix &A, \ - const dense_matrix &B, \ - dense_matrix &C, c_mult) { \ - GMMLAPACK_TRACE("gemm_interface_nn"); \ - const char t = 'N'; \ - long m(long(mat_nrows(A))), lda = m, k(long(mat_ncols(A))); \ - long n(long(mat_ncols(B))); \ - long ldb = k, ldc = m; \ - base_type alpha(1), beta(0); \ - if (m && k && n) \ - blas_name(&t, &t, &m, &n, &k, &alpha, \ - &A(0,0), &lda, &B(0,0), &ldb, &beta, &C(0,0), &ldc); \ - else gmm::clear(C); \ - } - - gemm_interface_nn(sgemm_, BLAS_S) - gemm_interface_nn(dgemm_, BLAS_D) - gemm_interface_nn(cgemm_, BLAS_C) - gemm_interface_nn(zgemm_, BLAS_Z) - - /* ********************************************************************* */ - /* transposed(dense matrix) x dense matrix multiplication. */ - /* ********************************************************************* */ - -# define gemm_interface_tn(blas_name, base_type, is_const) \ - inline void mult_spec( \ - const transposed_col_ref *> &A_,\ - const dense_matrix &B, \ - dense_matrix &C, rcmult) { \ - GMMLAPACK_TRACE("gemm_interface_tn"); \ - dense_matrix &A \ - = const_cast &>(*(linalg_origin(A_))); \ - const char t = 'T', u = 'N'; \ - long m(long(mat_ncols(A))), k(long(mat_nrows(A))), n(long(mat_ncols(B))); \ - long lda = k, ldb = k, ldc = m; \ - base_type alpha(1), beta(0); \ - if (m && k && n) \ - blas_name(&t, &u, &m, &n, &k, &alpha, \ - &A(0,0), &lda, &B(0,0), &ldb, &beta, &C(0,0), &ldc); \ - else gmm::clear(C); \ - } - - gemm_interface_tn(sgemm_, BLAS_S, dense_matrix) - gemm_interface_tn(dgemm_, BLAS_D, dense_matrix) - gemm_interface_tn(cgemm_, BLAS_C, dense_matrix) - gemm_interface_tn(zgemm_, BLAS_Z, dense_matrix) - gemm_interface_tn(sgemm_, BLAS_S, const dense_matrix) - gemm_interface_tn(dgemm_, BLAS_D, const dense_matrix) - gemm_interface_tn(cgemm_, BLAS_C, const dense_matrix) - gemm_interface_tn(zgemm_, BLAS_Z, const dense_matrix) - - /* ********************************************************************* */ - /* dense matrix x transposed(dense matrix) multiplication. */ - /* ********************************************************************* */ - -# define gemm_interface_nt(blas_name, base_type, is_const) \ - inline void mult_spec(const dense_matrix &A, \ - const transposed_col_ref *> &B_, \ - dense_matrix &C, r_mult) { \ - GMMLAPACK_TRACE("gemm_interface_nt"); \ - dense_matrix &B \ - = const_cast &>(*(linalg_origin(B_))); \ - const char t = 'N', u = 'T'; \ - long m(long(mat_nrows(A))), lda = m, k(long(mat_ncols(A))); \ - long n(long(mat_nrows(B))); \ - long ldb = n, ldc = m; \ - base_type alpha(1), beta(0); \ - if (m && k && n) \ - blas_name(&t, &u, &m, &n, &k, &alpha, \ - &A(0,0), &lda, &B(0,0), &ldb, &beta, &C(0,0), &ldc); \ - else gmm::clear(C); \ - } - - gemm_interface_nt(sgemm_, BLAS_S, dense_matrix) - gemm_interface_nt(dgemm_, BLAS_D, dense_matrix) - gemm_interface_nt(cgemm_, BLAS_C, dense_matrix) - gemm_interface_nt(zgemm_, BLAS_Z, dense_matrix) - gemm_interface_nt(sgemm_, BLAS_S, const dense_matrix) - gemm_interface_nt(dgemm_, BLAS_D, const dense_matrix) - gemm_interface_nt(cgemm_, BLAS_C, const dense_matrix) - gemm_interface_nt(zgemm_, BLAS_Z, const dense_matrix) - - /* ********************************************************************* */ - /* transposed(dense matrix) x transposed(dense matrix) multiplication. */ - /* ********************************************************************* */ - -# define gemm_interface_tt(blas_name, base_type, isA_const, isB_const) \ - inline void mult_spec( \ - const transposed_col_ref *> &A_, \ - const transposed_col_ref *> &B_, \ - dense_matrix &C, r_mult) { \ - GMMLAPACK_TRACE("gemm_interface_tt"); \ - dense_matrix &A \ - = const_cast &>(*(linalg_origin(A_))); \ - dense_matrix &B \ - = const_cast &>(*(linalg_origin(B_))); \ - const char t = 'T', u = 'T'; \ - long m(long(mat_ncols(A))), k(long(mat_nrows(A))), n(long(mat_nrows(B))); \ - long lda = k, ldb = n, ldc = m; \ - base_type alpha(1), beta(0); \ - if (m && k && n) \ - blas_name(&t, &u, &m, &n, &k, &alpha, \ - &A(0,0), &lda, &B(0,0), &ldb, &beta, &C(0,0), &ldc); \ - else gmm::clear(C); \ - } - - gemm_interface_tt(sgemm_, BLAS_S, dense_matrix, dense_matrix) - gemm_interface_tt(dgemm_, BLAS_D, dense_matrix, dense_matrix) - gemm_interface_tt(cgemm_, BLAS_C, dense_matrix, dense_matrix) - gemm_interface_tt(zgemm_, BLAS_Z, dense_matrix, dense_matrix) - gemm_interface_tt(sgemm_, BLAS_S, const dense_matrix, dense_matrix) - gemm_interface_tt(dgemm_, BLAS_D, const dense_matrix, dense_matrix) - gemm_interface_tt(cgemm_, BLAS_C, const dense_matrix, dense_matrix) - gemm_interface_tt(zgemm_, BLAS_Z, const dense_matrix, dense_matrix) - gemm_interface_tt(sgemm_, BLAS_S, dense_matrix, const dense_matrix) - gemm_interface_tt(dgemm_, BLAS_D, dense_matrix, const dense_matrix) - gemm_interface_tt(cgemm_, BLAS_C, dense_matrix, const dense_matrix) - gemm_interface_tt(zgemm_, BLAS_Z, dense_matrix, const dense_matrix) - gemm_interface_tt(sgemm_, BLAS_S, const dense_matrix, const dense_matrix) - gemm_interface_tt(dgemm_, BLAS_D, const dense_matrix, const dense_matrix) - gemm_interface_tt(cgemm_, BLAS_C, const dense_matrix, const dense_matrix) - gemm_interface_tt(zgemm_, BLAS_Z, const dense_matrix, const dense_matrix) - - - /* ********************************************************************* */ - /* conjugated(dense matrix) x dense matrix multiplication. */ - /* ********************************************************************* */ - -# define gemm_interface_cn(blas_name, base_type) \ - inline void mult_spec( \ - const conjugated_col_matrix_const_ref > &A_,\ - const dense_matrix &B, \ - dense_matrix &C, rcmult) { \ - GMMLAPACK_TRACE("gemm_interface_cn"); \ - dense_matrix &A \ - = const_cast &>(*(linalg_origin(A_))); \ - const char t = 'C', u = 'N'; \ - long m(long(mat_ncols(A))), k(long(mat_nrows(A))), n(long(mat_ncols(B))); \ - long lda = k, ldb = k, ldc = m; \ - base_type alpha(1), beta(0); \ - if (m && k && n) \ - blas_name(&t, &u, &m, &n, &k, &alpha, \ - &A(0,0), &lda, &B(0,0), &ldb, &beta, &C(0,0), &ldc); \ - else gmm::clear(C); \ - } - - gemm_interface_cn(sgemm_, BLAS_S) - gemm_interface_cn(dgemm_, BLAS_D) - gemm_interface_cn(cgemm_, BLAS_C) - gemm_interface_cn(zgemm_, BLAS_Z) - - /* ********************************************************************* */ - /* dense matrix x conjugated(dense matrix) multiplication. */ - /* ********************************************************************* */ - -# define gemm_interface_nc(blas_name, base_type) \ - inline void mult_spec(const dense_matrix &A, \ - const conjugated_col_matrix_const_ref > &B_,\ - dense_matrix &C, c_mult, row_major) { \ - GMMLAPACK_TRACE("gemm_interface_nc"); \ - dense_matrix &B \ - = const_cast &>(*(linalg_origin(B_))); \ - const char t = 'N', u = 'C'; \ - long m(long(mat_nrows(A))), lda = m, k(long(mat_ncols(A))); \ - long n(long(mat_nrows(B))), ldb = n, ldc = m; \ - base_type alpha(1), beta(0); \ - if (m && k && n) \ - blas_name(&t, &u, &m, &n, &k, &alpha, \ - &A(0,0), &lda, &B(0,0), &ldb, &beta, &C(0,0), &ldc); \ - else gmm::clear(C); \ - } - - gemm_interface_nc(sgemm_, BLAS_S) - gemm_interface_nc(dgemm_, BLAS_D) - gemm_interface_nc(cgemm_, BLAS_C) - gemm_interface_nc(zgemm_, BLAS_Z) - - /* ********************************************************************* */ - /* conjugated(dense matrix) x conjugated(dense matrix) multiplication. */ - /* ********************************************************************* */ - -# define gemm_interface_cc(blas_name, base_type) \ - inline void mult_spec( \ - const conjugated_col_matrix_const_ref > &A_,\ - const conjugated_col_matrix_const_ref > &B_,\ - dense_matrix &C, r_mult) { \ - GMMLAPACK_TRACE("gemm_interface_cc"); \ - dense_matrix &A \ - = const_cast &>(*(linalg_origin(A_))); \ - dense_matrix &B \ - = const_cast &>(*(linalg_origin(B_))); \ - const char t = 'C', u = 'C'; \ - long m(long(mat_ncols(A))), k(long(mat_nrows(A))), lda = k; \ - long n(long(mat_nrows(B))), ldb = n, ldc = m; \ - base_type alpha(1), beta(0); \ - if (m && k && n) \ - blas_name(&t, &u, &m, &n, &k, &alpha, \ - &A(0,0), &lda, &B(0,0), &ldb, &beta, &C(0,0), &ldc); \ - else gmm::clear(C); \ - } - - gemm_interface_cc(sgemm_, BLAS_S) - gemm_interface_cc(dgemm_, BLAS_D) - gemm_interface_cc(cgemm_, BLAS_C) - gemm_interface_cc(zgemm_, BLAS_Z) - - /* ********************************************************************* */ - /* Tri solve. */ - /* ********************************************************************* */ - -# define trsv_interface(f_name, loru, param1, trans1, blas_name, base_type)\ - inline void f_name(param1(base_type), std::vector &x, \ - size_type k, bool is_unit) { \ - GMMLAPACK_TRACE("trsv_interface"); \ - loru; trans1(base_type); char d = is_unit ? 'U' : 'N'; \ - long lda(long(mat_nrows(A))), inc(1), n = long(k); \ - if (lda) blas_name(&l, &t, &d, &n, &A(0,0), &lda, &x[0], &inc); \ - } - -# define trsv_upper const char l = 'U' -# define trsv_lower const char l = 'L' - - // X <- LOWER(A)^{-1}X. - trsv_interface(lower_tri_solve, trsv_lower, gem_p1_n, gem_trans1_n, - strsv_, BLAS_S) - trsv_interface(lower_tri_solve, trsv_lower, gem_p1_n, gem_trans1_n, - dtrsv_, BLAS_D) - trsv_interface(lower_tri_solve, trsv_lower, gem_p1_n, gem_trans1_n, - ctrsv_, BLAS_C) - trsv_interface(lower_tri_solve, trsv_lower, gem_p1_n, gem_trans1_n, - ztrsv_, BLAS_Z) - - // X <- UPPER(A)^{-1}X. - trsv_interface(upper_tri_solve, trsv_upper, gem_p1_n, gem_trans1_n, - strsv_, BLAS_S) - trsv_interface(upper_tri_solve, trsv_upper, gem_p1_n, gem_trans1_n, - dtrsv_, BLAS_D) - trsv_interface(upper_tri_solve, trsv_upper, gem_p1_n, gem_trans1_n, - ctrsv_, BLAS_C) - trsv_interface(upper_tri_solve, trsv_upper, gem_p1_n, gem_trans1_n, - ztrsv_, BLAS_Z) - - // X <- LOWER(transposed(A))^{-1}X. - trsv_interface(lower_tri_solve, trsv_upper, gem_p1_t, gem_trans1_t, - strsv_, BLAS_S) - trsv_interface(lower_tri_solve, trsv_upper, gem_p1_t, gem_trans1_t, - dtrsv_, BLAS_D) - trsv_interface(lower_tri_solve, trsv_upper, gem_p1_t, gem_trans1_t, - ctrsv_, BLAS_C) - trsv_interface(lower_tri_solve, trsv_upper, gem_p1_t, gem_trans1_t, - ztrsv_, BLAS_Z) - - // X <- UPPER(transposed(A))^{-1}X. - trsv_interface(upper_tri_solve, trsv_lower, gem_p1_t, gem_trans1_t, - strsv_, BLAS_S) - trsv_interface(upper_tri_solve, trsv_lower, gem_p1_t, gem_trans1_t, - dtrsv_, BLAS_D) - trsv_interface(upper_tri_solve, trsv_lower, gem_p1_t, gem_trans1_t, - ctrsv_, BLAS_C) - trsv_interface(upper_tri_solve, trsv_lower, gem_p1_t, gem_trans1_t, - ztrsv_, BLAS_Z) - - // X <- LOWER(transposed(const A))^{-1}X. - trsv_interface(lower_tri_solve, trsv_upper, gem_p1_tc, gem_trans1_t, - strsv_, BLAS_S) - trsv_interface(lower_tri_solve, trsv_upper, gem_p1_tc, gem_trans1_t, - dtrsv_, BLAS_D) - trsv_interface(lower_tri_solve, trsv_upper, gem_p1_tc, gem_trans1_t, - ctrsv_, BLAS_C) - trsv_interface(lower_tri_solve, trsv_upper, gem_p1_tc, gem_trans1_t, - ztrsv_, BLAS_Z) - - // X <- UPPER(transposed(const A))^{-1}X. - trsv_interface(upper_tri_solve, trsv_lower, gem_p1_tc, gem_trans1_t, - strsv_, BLAS_S) - trsv_interface(upper_tri_solve, trsv_lower, gem_p1_tc, gem_trans1_t, - dtrsv_, BLAS_D) - trsv_interface(upper_tri_solve, trsv_lower, gem_p1_tc, gem_trans1_t, - ctrsv_, BLAS_C) - trsv_interface(upper_tri_solve, trsv_lower, gem_p1_tc, gem_trans1_t, - ztrsv_, BLAS_Z) - - // X <- LOWER(conjugated(A))^{-1}X. - trsv_interface(lower_tri_solve, trsv_upper, gem_p1_c, gem_trans1_c, - strsv_, BLAS_S) - trsv_interface(lower_tri_solve, trsv_upper, gem_p1_c, gem_trans1_c, - dtrsv_, BLAS_D) - trsv_interface(lower_tri_solve, trsv_upper, gem_p1_c, gem_trans1_c, - ctrsv_, BLAS_C) - trsv_interface(lower_tri_solve, trsv_upper, gem_p1_c, gem_trans1_c, - ztrsv_, BLAS_Z) - - // X <- UPPER(conjugated(A))^{-1}X. - trsv_interface(upper_tri_solve, trsv_lower, gem_p1_c, gem_trans1_c, - strsv_, BLAS_S) - trsv_interface(upper_tri_solve, trsv_lower, gem_p1_c, gem_trans1_c, - dtrsv_, BLAS_D) - trsv_interface(upper_tri_solve, trsv_lower, gem_p1_c, gem_trans1_c, - ctrsv_, BLAS_C) - trsv_interface(upper_tri_solve, trsv_lower, gem_p1_c, gem_trans1_c, - ztrsv_, BLAS_Z) - -#endif -} - -#endif // GMM_BLAS_INTERFACE_H - -#endif // GMM_USES_BLAS diff --git a/gmm/gmm_condition_number.h b/gmm/gmm_condition_number.h deleted file mode 100644 index 0dac20e6b..000000000 --- a/gmm/gmm_condition_number.h +++ /dev/null @@ -1,147 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard, Julien Pommier - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_condition_number.h - @author Yves Renard , Julien Pommier - @date August 27, 2003. - @brief computation of the condition number of dense matrices. -*/ -#ifndef GMM_CONDITION_NUMBER_H__ -#define GMM_CONDITION_NUMBER_H__ - -#include "gmm_dense_qr.h" - -namespace gmm { - - /** computation of the condition number of dense matrices using SVD. - - Uses symmetric_qr_algorithm => dense matrices only. - - @param M a matrix. - @param emin smallest (in magnitude) eigenvalue - @param emax largest eigenvalue. - */ - template - typename number_traits::value_type>::magnitude_type - condition_number(const MAT& M, - typename number_traits::value_type>::magnitude_type& emin, - typename number_traits::value_type>::magnitude_type& emax) { - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - // Added because of errors in complex with zero det - if (sizeof(T) != sizeof(R) && gmm::abs(gmm::lu_det(M)) == R(0)) - return gmm::default_max(R()); - - size_type m = mat_nrows(M), n = mat_ncols(M); - emax = emin = R(0); - std::vector eig(m+n); - - if (m+n == 0) return R(0); - if (is_hermitian(M)) { - eig.resize(m); - gmm::symmetric_qr_algorithm(M, eig); - } - else { - dense_matrix B(m+n, m+n); // not very efficient ?? - gmm::copy(conjugated(M), sub_matrix(B, sub_interval(m, n), sub_interval(0, m))); - gmm::copy(M, sub_matrix(B, sub_interval(0, m), - sub_interval(m, n))); - gmm::symmetric_qr_algorithm(B, eig); - } - emin = emax = gmm::abs(eig[0]); - for (size_type i = 1; i < eig.size(); ++i) { - R e = gmm::abs(eig[i]); - emin = std::min(emin, e); - emax = std::max(emax, e); - } - // cout << "emin = " << emin << " emax = " << emax << endl; - if (emin == R(0)) return gmm::default_max(R()); - return emax / emin; - } - - template - typename number_traits::value_type>::magnitude_type - condition_number(const MAT& M) { - typename number_traits::value_type>::magnitude_type emax, emin; - return condition_number(M, emin, emax); - } - - template - typename number_traits::value_type>::magnitude_type - Frobenius_condition_number_sqr(const MAT& M) { - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - size_type m = mat_nrows(M), n = mat_ncols(M); - dense_matrix B(std::min(m,n), std::min(m,n)); - if (m < n) mult(M,gmm::conjugated(M),B); - else mult(gmm::conjugated(M),M,B); - R trB = abs(mat_trace(B)); - lu_inverse(B); - return trB*abs(mat_trace(B)); - } - - template - typename number_traits::value_type>::magnitude_type - Frobenius_condition_number(const MAT& M) - { return sqrt(Frobenius_condition_number_sqr(M)); } - - /** estimation of the condition number (TO BE DONE...) - */ - template - typename number_traits::value_type>::magnitude_type - condest(const MAT& M, - typename number_traits::value_type>::magnitude_type& emin, - typename number_traits::value_type>::magnitude_type& emax) { - return condition_number(M, emin, emax); - } - - template - typename number_traits::value_type>::magnitude_type - condest(const MAT& M) { - typename number_traits::value_type>::magnitude_type emax, emin; - return condest(M, emin, emax); - } -} - -#endif diff --git a/gmm/gmm_conjugated.h b/gmm/gmm_conjugated.h deleted file mode 100644 index 1e3e7fc61..000000000 --- a/gmm/gmm_conjugated.h +++ /dev/null @@ -1,398 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_conjugated.h - @author Yves Renard - @date September 18, 2003. - @brief handle conjugation of complex matrices/vectors. -*/ -#ifndef GMM_CONJUGATED_H__ -#define GMM_CONJUGATED_H__ - -#include "gmm_def.h" - -namespace gmm { - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - /* ********************************************************************* */ - /* Conjugated references on vectors */ - /* ********************************************************************* */ - - template struct conjugated_const_iterator { - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::pointer pointer; - typedef typename std::iterator_traits::reference reference; - typedef typename std::iterator_traits::difference_type difference_type; - typedef typename std::iterator_traits::iterator_category - iterator_category; - - IT it; - - conjugated_const_iterator(void) {} - conjugated_const_iterator(const IT &i) : it(i) {} - - inline size_type index(void) const { return it.index(); } - conjugated_const_iterator operator ++(int) - { conjugated_const_iterator tmp = *this; ++it; return tmp; } - conjugated_const_iterator operator --(int) - { conjugated_const_iterator tmp = *this; --it; return tmp; } - conjugated_const_iterator &operator ++() { ++it; return *this; } - conjugated_const_iterator &operator --() { --it; return *this; } - conjugated_const_iterator &operator +=(difference_type i) - { it += i; return *this; } - conjugated_const_iterator &operator -=(difference_type i) - { it -= i; return *this; } - conjugated_const_iterator operator +(difference_type i) const - { conjugated_const_iterator itb = *this; return (itb += i); } - conjugated_const_iterator operator -(difference_type i) const - { conjugated_const_iterator itb = *this; return (itb -= i); } - difference_type operator -(const conjugated_const_iterator &i) const - { return difference_type(it - i.it); } - - value_type operator *() const { return gmm::conj(*it); } - value_type operator [](size_type ii) const { return gmm::conj(it[ii]); } - - bool operator ==(const conjugated_const_iterator &i) const - { return (i.it == it); } - bool operator !=(const conjugated_const_iterator &i) const - { return (i.it != it); } - bool operator < (const conjugated_const_iterator &i) const - { return (it < i.it); } - }; - - template struct conjugated_vector_const_ref { - typedef conjugated_vector_const_ref this_type; - typedef typename linalg_traits::value_type value_type; - typedef typename linalg_traits::const_iterator iterator; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::origin_type origin_type; - - iterator begin_, end_; - const origin_type *origin; - size_type size_; - - conjugated_vector_const_ref(const V &v) - : begin_(vect_const_begin(v)), end_(vect_const_end(v)), - origin(linalg_origin(v)), - size_(vect_size(v)) {} - - reference operator[](size_type i) const - { return gmm::conj(linalg_traits::access(origin, begin_, end_, i)); } - }; - - template struct linalg_traits > { - typedef conjugated_vector_const_ref this_type; - typedef typename linalg_traits::origin_type origin_type; - typedef linalg_const is_reference; - typedef abstract_vector linalg_type; - typedef typename linalg_traits::value_type value_type; - typedef value_type reference; - typedef abstract_null_type iterator; - typedef conjugated_const_iterator::const_iterator> const_iterator; - typedef typename linalg_traits::storage_type storage_type; - typedef typename linalg_traits::index_sorted index_sorted; - static size_type size(const this_type &v) { return v.size_; } - static iterator begin(this_type &v) { return iterator(v.begin_); } - static const_iterator begin(const this_type &v) - { return const_iterator(v.begin_); } - static iterator end(this_type &v) - { return iterator(v.end_); } - static const_iterator end(const this_type &v) - { return const_iterator(v.end_); } - static value_type access(const origin_type *o, const const_iterator &it, - const const_iterator &ite, size_type i) - { return gmm::conj(linalg_traits::access(o, it.it, ite.it, i)); } - static const origin_type* origin(const this_type &v) { return v.origin; } - }; - - template std::ostream &operator << - (std::ostream &o, const conjugated_vector_const_ref& m) - { gmm::write(o,m); return o; } - - /* ********************************************************************* */ - /* Conjugated references on matrices */ - /* ********************************************************************* */ - - template struct conjugated_row_const_iterator { - typedef conjugated_row_const_iterator iterator; - typedef typename linalg_traits::const_row_iterator ITER; - typedef typename linalg_traits::value_type value_type; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - - ITER it; - - iterator operator ++(int) { iterator tmp = *this; it++; return tmp; } - iterator operator --(int) { iterator tmp = *this; it--; return tmp; } - iterator &operator ++() { it++; return *this; } - iterator &operator --() { it--; return *this; } - iterator &operator +=(difference_type i) { it += i; return *this; } - iterator &operator -=(difference_type i) { it -= i; return *this; } - iterator operator +(difference_type i) const - { iterator itt = *this; return (itt += i); } - iterator operator -(difference_type i) const - { iterator itt = *this; return (itt -= i); } - difference_type operator -(const iterator &i) const - { return it - i.it; } - - ITER operator *() const { return it; } - ITER operator [](int i) { return it + i; } - - bool operator ==(const iterator &i) const { return (it == i.it); } - bool operator !=(const iterator &i) const { return !(i == *this); } - bool operator < (const iterator &i) const { return (it < i.it); } - - conjugated_row_const_iterator(void) {} - conjugated_row_const_iterator(const ITER &i) : it(i) { } - - }; - - template struct conjugated_row_matrix_const_ref { - - typedef conjugated_row_matrix_const_ref this_type; - typedef typename linalg_traits::const_row_iterator iterator; - typedef typename linalg_traits::value_type value_type; - typedef typename linalg_traits::origin_type origin_type; - - iterator begin_, end_; - const origin_type *origin; - size_type nr, nc; - - conjugated_row_matrix_const_ref(const M &m) - : begin_(mat_row_begin(m)), end_(mat_row_end(m)), - origin(linalg_origin(m)), nr(mat_ncols(m)), nc(mat_nrows(m)) {} - - value_type operator()(size_type i, size_type j) const - { return gmm::conj(linalg_traits::access(begin_+j, i)); } - }; - - template std::ostream &operator << - (std::ostream &o, const conjugated_row_matrix_const_ref& m) - { gmm::write(o,m); return o; } - - - template struct conjugated_col_const_iterator { - typedef conjugated_col_const_iterator iterator; - typedef typename linalg_traits::const_col_iterator ITER; - typedef typename linalg_traits::value_type value_type; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - - ITER it; - - iterator operator ++(int) { iterator tmp = *this; it++; return tmp; } - iterator operator --(int) { iterator tmp = *this; it--; return tmp; } - iterator &operator ++() { it++; return *this; } - iterator &operator --() { it--; return *this; } - iterator &operator +=(difference_type i) { it += i; return *this; } - iterator &operator -=(difference_type i) { it -= i; return *this; } - iterator operator +(difference_type i) const - { iterator itt = *this; return (itt += i); } - iterator operator -(difference_type i) const - { iterator itt = *this; return (itt -= i); } - difference_type operator -(const iterator &i) const - { return it - i.it; } - - ITER operator *() const { return it; } - ITER operator [](int i) { return it + i; } - - bool operator ==(const iterator &i) const { return (it == i.it); } - bool operator !=(const iterator &i) const { return !(i == *this); } - bool operator < (const iterator &i) const { return (it < i.it); } - - conjugated_col_const_iterator(void) {} - conjugated_col_const_iterator(const ITER &i) : it(i) { } - - }; - - template struct conjugated_col_matrix_const_ref { - - typedef conjugated_col_matrix_const_ref this_type; - typedef typename linalg_traits::const_col_iterator iterator; - typedef typename linalg_traits::value_type value_type; - typedef typename linalg_traits::origin_type origin_type; - - iterator begin_, end_; - const origin_type *origin; - size_type nr, nc; - - conjugated_col_matrix_const_ref(const M &m) - : begin_(mat_col_begin(m)), end_(mat_col_end(m)), - origin(linalg_origin(m)), nr(mat_ncols(m)), nc(mat_nrows(m)) {} - - value_type operator()(size_type i, size_type j) const - { return gmm::conj(linalg_traits::access(begin_+i, j)); } - }; - - - - template std::ostream &operator << - (std::ostream &o, const conjugated_col_matrix_const_ref& m) - { gmm::write(o,m); return o; } - - - template struct conjugated_return__ { - typedef conjugated_row_matrix_const_ref return_type; - }; - template struct conjugated_return__ { - typedef conjugated_col_matrix_const_ref return_type; - }; - template struct conjugated_return_ { - typedef const L & return_type; - }; - template - struct conjugated_return_, abstract_vector> { - typedef conjugated_vector_const_ref return_type; - }; - template - struct conjugated_return_ { - typedef typename conjugated_return__::sub_orientation>::potype - >::return_type return_type; - }; - template struct conjugated_return { - typedef typename - conjugated_return_::value_type, - typename linalg_traits::linalg_type - >::return_type return_type; - }; - - ///@endcond - /** return a conjugated view of the input matrix or vector. */ - template inline - typename conjugated_return::return_type - conjugated(const L &v) { - return conjugated(v, typename linalg_traits::value_type(), - typename linalg_traits::linalg_type()); - } - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - template inline - const L & conjugated(const L &v, T, LT) { return v; } - - template inline - conjugated_vector_const_ref conjugated(const L &v, std::complex, - abstract_vector) - { return conjugated_vector_const_ref(v); } - - template inline - typename conjugated_return__::sub_orientation>::potype>::return_type - conjugated(const L &v, T, abstract_matrix) { - return conjugated(v, typename principal_orientation_type::sub_orientation>::potype()); - } - - template inline - conjugated_row_matrix_const_ref conjugated(const L &v, row_major) - { return conjugated_row_matrix_const_ref(v); } - - template inline - conjugated_col_matrix_const_ref conjugated(const L &v, col_major) - { return conjugated_col_matrix_const_ref(v); } - - template - struct linalg_traits > { - typedef conjugated_row_matrix_const_ref this_type; - typedef typename linalg_traits::origin_type origin_type; - typedef linalg_const is_reference; - typedef abstract_matrix linalg_type; - typedef typename linalg_traits::value_type value_type; - typedef value_type reference; - typedef typename linalg_traits::storage_type storage_type; - typedef typename org_type::const_sub_row_type>::t vector_type; - typedef conjugated_vector_const_ref sub_col_type; - typedef conjugated_vector_const_ref const_sub_col_type; - typedef conjugated_row_const_iterator col_iterator; - typedef conjugated_row_const_iterator const_col_iterator; - typedef abstract_null_type const_sub_row_type; - typedef abstract_null_type sub_row_type; - typedef abstract_null_type const_row_iterator; - typedef abstract_null_type row_iterator; - typedef col_major sub_orientation; - typedef typename linalg_traits::index_sorted index_sorted; - static inline size_type ncols(const this_type &m) { return m.nc; } - static inline size_type nrows(const this_type &m) { return m.nr; } - static inline const_sub_col_type col(const const_col_iterator &it) - { return conjugated(linalg_traits::row(it.it)); } - static inline const_col_iterator col_begin(const this_type &m) - { return const_col_iterator(m.begin_); } - static inline const_col_iterator col_end(const this_type &m) - { return const_col_iterator(m.end_); } - static inline const origin_type* origin(const this_type &m) - { return m.origin; } - static value_type access(const const_col_iterator &it, size_type i) - { return gmm::conj(linalg_traits::access(it.it, i)); } - }; - - template - struct linalg_traits > { - typedef conjugated_col_matrix_const_ref this_type; - typedef typename linalg_traits::origin_type origin_type; - typedef linalg_const is_reference; - typedef abstract_matrix linalg_type; - typedef typename linalg_traits::value_type value_type; - typedef value_type reference; - typedef typename linalg_traits::storage_type storage_type; - typedef typename org_type::const_sub_col_type>::t vector_type; - typedef conjugated_vector_const_ref sub_row_type; - typedef conjugated_vector_const_ref const_sub_row_type; - typedef conjugated_col_const_iterator row_iterator; - typedef conjugated_col_const_iterator const_row_iterator; - typedef abstract_null_type const_sub_col_type; - typedef abstract_null_type sub_col_type; - typedef abstract_null_type const_col_iterator; - typedef abstract_null_type col_iterator; - typedef row_major sub_orientation; - typedef typename linalg_traits::index_sorted index_sorted; - static inline size_type nrows(const this_type &m) { return m.nr; } - static inline size_type ncols(const this_type &m) { return m.nc; } - static inline const_sub_row_type row(const const_row_iterator &it) - { return conjugated(linalg_traits::col(it.it)); } - static inline const_row_iterator row_begin(const this_type &m) - { return const_row_iterator(m.begin_); } - static inline const_row_iterator row_end(const this_type &m) - { return const_row_iterator(m.end_); } - static inline const origin_type* origin(const this_type &m) - { return m.origin; } - static value_type access(const const_row_iterator &it, size_type i) - { return gmm::conj(linalg_traits::access(it.it, i)); } - }; - - ///@endcond - - -} - -#endif // GMM_CONJUGATED_H__ diff --git a/gmm/gmm_def.h b/gmm/gmm_def.h deleted file mode 100644 index 28e1c3ebf..000000000 --- a/gmm/gmm_def.h +++ /dev/null @@ -1,1122 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_def.h - @author Yves Renard - @date October 13, 2002. - @brief Basic definitions and tools of GMM. -*/ -#ifndef GMM_DEF_H__ -#define GMM_DEF_H__ - -#include "gmm_ref.h" -#include - -#ifndef M_PI -# define M_E 2.7182818284590452354 /* e */ -# define M_LOG2E 1.4426950408889634074 /* 1/ln(2) */ -# define M_LOG10E 0.43429448190325182765 /* 1/ln(10) */ -# define M_LN2 0.69314718055994530942 /* ln(2) */ -# define M_LN10 2.30258509299404568402 /* ln(10) */ -# define M_PI 3.14159265358979323846 /* pi */ -# define M_PI_2 1.57079632679489661923 /* pi/2 */ -# define M_PI_4 0.78539816339744830962 /* pi/4 */ -# define M_1_PI 0.31830988618379067154 /* 1/pi */ -# define M_2_PI 0.63661977236758134308 /* 2/pi */ -# define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ -# define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ -# define M_SQRT1_2 0.70710678118654752440 /* sqrt(2)/2 */ -#endif - -#ifndef M_PIl -# define M_PIl 3.1415926535897932384626433832795029L /* pi */ -# define M_PI_2l 1.5707963267948966192313216916397514L /* pi/2 */ -# define M_PI_4l 0.7853981633974483096156608458198757L /* pi/4 */ -# define M_1_PIl 0.3183098861837906715377675267450287L /* 1/pi */ -# define M_2_PIl 0.6366197723675813430755350534900574L /* 2/pi */ -# define M_2_SQRTPIl 1.1283791670955125738961589031215452L /* 2/sqrt(pi) */ -#endif - -namespace gmm { - - typedef size_t size_type; - - /* ******************************************************************** */ - /* Specifier types */ - /* ******************************************************************** */ - /* not perfectly null, required by aCC 3.33 */ - struct abstract_null_type { - abstract_null_type(int=0) {} - template void operator()(A,B,C) {} - }; // specify an information lake. - - struct linalg_true {}; - struct linalg_false {}; - - template struct linalg_and - { typedef linalg_false bool_type; }; - template <> struct linalg_and - { typedef linalg_true bool_type; }; - template struct linalg_or - { typedef linalg_true bool_type; }; - template <> struct linalg_and - { typedef linalg_false bool_type; }; - - struct linalg_const {}; // A reference is either linalg_const, - struct linalg_modifiable {}; // linalg_modifiable or linalg_false. - - struct abstract_vector {}; // The object is a vector - struct abstract_matrix {}; // The object is a matrix - - struct abstract_sparse {}; // sparse matrix or vector - struct abstract_skyline {}; // 'sky-line' matrix or vector - struct abstract_dense {}; // dense matrix or vector - struct abstract_indirect {}; // matrix given by the product with a vector - - struct row_major {}; // matrix with a row access. - struct col_major {}; // matrix with a column access - struct row_and_col {}; // both accesses but row preference - struct col_and_row {}; // both accesses but column preference - - template struct transposed_type; - template<> struct transposed_type {typedef col_major t_type;}; - template<> struct transposed_type {typedef row_major t_type;}; - template<> struct transposed_type {typedef col_and_row t_type;}; - template<> struct transposed_type {typedef row_and_col t_type;}; - - template struct principal_orientation_type - { typedef abstract_null_type potype; }; - template<> struct principal_orientation_type - { typedef row_major potype; }; - template<> struct principal_orientation_type - { typedef col_major potype; }; - template<> struct principal_orientation_type - { typedef row_major potype; }; - template<> struct principal_orientation_type - { typedef col_major potype; }; - - // template struct linalg_traits; - template struct linalg_traits { - typedef abstract_null_type this_type; - typedef abstract_null_type linalg_type; - typedef abstract_null_type value_type; - typedef abstract_null_type is_reference; - typedef abstract_null_type& reference; - typedef abstract_null_type* iterator; - typedef const abstract_null_type* const_iterator; - typedef abstract_null_type index_sorted; - typedef abstract_null_type storage_type; - typedef abstract_null_type origin_type; - typedef abstract_null_type const_sub_row_type; - typedef abstract_null_type sub_row_type; - typedef abstract_null_type const_row_iterator; - typedef abstract_null_type row_iterator; - typedef abstract_null_type const_sub_col_type; - typedef abstract_null_type sub_col_type; - typedef abstract_null_type const_col_iterator; - typedef abstract_null_type col_iterator; - typedef abstract_null_type sub_orientation; - }; - - template struct vect_ref_type; - template struct vect_ref_type

{ - typedef typename linalg_traits::reference access_type; - typedef typename linalg_traits::iterator iterator; - }; - template struct vect_ref_type { - typedef typename linalg_traits::value_type access_type; - typedef typename linalg_traits::const_iterator iterator; - }; - - template struct const_pointer; - template struct const_pointer

- { typedef const P* pointer; }; - template struct const_pointer - { typedef const P* pointer; }; - - template struct modifiable_pointer; - template struct modifiable_pointer

- { typedef P* pointer; }; - template struct modifiable_pointer - { typedef P* pointer; }; - - template struct const_reference; - template struct const_reference - { typedef const R &reference; }; - template struct const_reference - { typedef const R &reference; }; - - - inline bool is_sparse(abstract_sparse) { return true; } - inline bool is_sparse(abstract_dense) { return false; } - inline bool is_sparse(abstract_skyline) { return true; } - inline bool is_sparse(abstract_indirect) { return false; } - - template inline bool is_sparse(const L &) - { return is_sparse(typename linalg_traits::storage_type()); } - - inline bool is_row_matrix_(row_major) { return true; } - inline bool is_row_matrix_(col_major) { return false; } - inline bool is_row_matrix_(row_and_col) { return true; } - inline bool is_row_matrix_(col_and_row) { return true; } - - template inline bool is_row_matrix(const L &) - { return is_row_matrix_(typename linalg_traits::sub_orientation()); } - - inline bool is_col_matrix_(row_major) { return false; } - inline bool is_col_matrix_(col_major) { return true; } - inline bool is_col_matrix_(row_and_col) { return true; } - inline bool is_col_matrix_(col_and_row) { return true; } - - template inline bool is_col_matrix(const L &) - { return is_col_matrix_(typename linalg_traits::sub_orientation()); } - - inline bool is_col_matrix(row_major) { return false; } - inline bool is_col_matrix(col_major) { return true; } - inline bool is_row_matrix(row_major) { return true; } - inline bool is_row_matrix(col_major) { return false; } - - template inline bool is_const_reference(L) { return false; } - inline bool is_const_reference(linalg_const) { return true; } - - - template struct is_gmm_interfaced_ { - typedef linalg_true result; - }; - - template<> struct is_gmm_interfaced_ { - typedef linalg_false result; - }; - - template struct is_gmm_interfaced { - typedef typename is_gmm_interfaced_::this_type >::result result; - }; - - /* ******************************************************************** */ - /* Original type from a pointer or a reference. */ - /* ******************************************************************** */ - - template struct org_type { typedef V t; }; - template struct org_type { typedef V t; }; - template struct org_type { typedef V t; }; - template struct org_type { typedef V t; }; - template struct org_type { typedef V t; }; - - /* ******************************************************************** */ - /* Types to deal with const object representing a modifiable reference */ - /* ******************************************************************** */ - - template struct mref_type_ - { typedef abstract_null_type return_type; }; - template struct mref_type_ - { typedef typename org_type::t & return_type; }; - template struct mref_type_ - { typedef const typename org_type::t & return_type; }; - template struct mref_type_ - { typedef const typename org_type::t & return_type; }; - template struct mref_type_ - { typedef const typename org_type::t & return_type; }; - template struct mref_type_ - { typedef typename org_type::t & return_type; }; - template struct mref_type_ - { typedef typename org_type::t & return_type; }; - - template struct mref_type { - typedef typename std::iterator_traits::value_type L; - typedef typename mref_type_::is_reference>::return_type return_type; - }; - - template typename mref_type::return_type - linalg_cast(const L &l) - { return const_cast::return_type>(l); } - - template typename mref_type::return_type linalg_cast(L &l) - { return const_cast::return_type>(l); } - - template struct cref_type_ - { typedef abstract_null_type return_type; }; - template struct cref_type_ - { typedef typename org_type::t & return_type; }; - template struct cref_type { - typedef typename cref_type_::is_reference>::return_type return_type; - }; - - template typename cref_type::return_type - linalg_const_cast(const L &l) - { return const_cast::return_type>(l); } - - - // To be used to select between a reference or a const refercence for - // the return type of a function - // select_return return C1 if L is a const reference, - // C2 otherwise. - // select_return return C2 if L is a modifiable reference - // C1 otherwise. - template struct select_return_ { - typedef abstract_null_type return_type; - }; - template - struct select_return_ { typedef C1 return_type; }; - template - struct select_return_ { typedef C2 return_type; }; - template struct select_return { - typedef typename std::iterator_traits::value_type L; - typedef typename select_return_::return_type>::return_type return_type; - }; - - - // To be used to select between a reference or a const refercence inside - // a structure or a linagl_traits - // select_ref return C1 if L is a const reference, - // C2 otherwise. - // select_ref return C2 in any case. - template struct select_ref_ - { typedef abstract_null_type ref_type; }; - template - struct select_ref_ { typedef C1 ref_type; }; - template - struct select_ref_ { typedef C2 ref_type; }; - template struct select_ref { - typedef typename std::iterator_traits::value_type L; - typedef typename select_ref_::return_type>::ref_type ref_type; - }; - template - struct select_ref - { typedef C1 ref_type; }; - - - template struct is_a_reference_ - { typedef linalg_true reference; }; - template<> struct is_a_reference_ - { typedef linalg_false reference; }; - - template struct is_a_reference { - typedef typename is_a_reference_::is_reference> - ::reference reference; - }; - - - template inline bool is_original_linalg(const L &) - { return is_original_linalg(typename is_a_reference::reference()); } - inline bool is_original_linalg(linalg_false) { return true; } - inline bool is_original_linalg(linalg_true) { return false; } - - - template struct which_reference - { typedef abstract_null_type is_reference; }; - template struct which_reference - { typedef linalg_modifiable is_reference; }; - template struct which_reference - { typedef linalg_const is_reference; }; - - - template struct select_orientation_ - { typedef abstract_null_type return_type; }; - template - struct select_orientation_ - { typedef C1 return_type; }; - template - struct select_orientation_ - { typedef C2 return_type; }; - template struct select_orientation { - typedef typename select_orientation_::sub_orientation>::potype>::return_type return_type; - }; - - /* ******************************************************************** */ - /* Operations on scalars */ - /* ******************************************************************** */ - - template inline T sqr(T a) { return T(a * a); } - template inline T abs(T a) { return (a < T(0)) ? T(-a) : a; } - template inline T abs(std::complex a) - { T x = a.real(), y = a.imag(); return T(::sqrt(x*x+y*y)); } - template inline T abs_sqr(T a) { return T(a*a); } - template inline T abs_sqr(std::complex a) - { return gmm::sqr(a.real()) + gmm::sqr(a.imag()); } - template inline T pos(T a) { return (a < T(0)) ? T(0) : a; } - template inline T neg(T a) { return (a < T(0)) ? T(-a) : T(0); } - template inline T sgn(T a) { return (a < T(0)) ? T(-1) : T(1); } - template inline T Heaviside(T a) { return (a < T(0)) ? T(0) : T(1); } - inline double random() { return double(rand())/(RAND_MAX+0.5); } - template inline T random(T) - { return T(rand()*2.0)/(T(RAND_MAX)+T(1)/T(2)) - T(1); } - template inline std::complex random(std::complex) - { return std::complex(gmm::random(T()), gmm::random(T())); } - template inline T irandom(T max) - { return T(gmm::random() * double(max)); } - template inline T conj(T a) { return a; } - template inline std::complex conj(std::complex a) - { return std::conj(a); } - template inline T real(T a) { return a; } - template inline T real(std::complex a) { return a.real(); } - template inline T imag(T ) { return T(0); } - template inline T imag(std::complex a) { return a.imag(); } - template inline T sqrt(T a) { return T(::sqrt(a)); } - template inline std::complex sqrt(std::complex a) { - T x = a.real(), y = a.imag(); - if (x == T(0)) { - T t = T(::sqrt(gmm::abs(y) / T(2))); - return std::complex(t, y < T(0) ? -t : t); - } - T t = T(::sqrt(T(2) * (gmm::abs(a) + gmm::abs(x)))), u = t / T(2); - return x > T(0) ? std::complex(u, y / t) - : std::complex(gmm::abs(y) / t, y < T(0) ? -u : u); - } - using std::swap; - - - template struct number_traits { - typedef T magnitude_type; - }; - - template struct number_traits > { - typedef T magnitude_type; - }; - - template inline T conj_product(T a, T b) { return a * b; } - template inline - std::complex conj_product(std::complex a, std::complex b) - { return std::conj(a) * b; } // to be optimized ? - - template inline bool is_complex(T) { return false; } - template inline bool is_complex(std::complex ) - { return true; } - -# define magnitude_of_linalg(M) typename number_traits::value_type>::magnitude_type - - /* ******************************************************************** */ - /* types promotion */ - /* ******************************************************************** */ - - /* should be completed for more specific cases etc */ - template - struct strongest_numeric_type_aux { - typedef T1 T; - }; - template - struct strongest_numeric_type_aux { - typedef T2 T; - }; - - template - struct strongest_numeric_type { - typedef typename - strongest_numeric_type_auxsizeof(T2))>::T T; - }; - template - struct strongest_numeric_type > { - typedef typename number_traits::magnitude_type R1; - typedef std::complex::T > T; - }; - template - struct strongest_numeric_type,T2 > { - typedef typename number_traits::magnitude_type R2; - typedef std::complex::T > T; - }; - template - struct strongest_numeric_type,std::complex > { - typedef std::complex::T > T; - }; - - template<> struct strongest_numeric_type { typedef float T; }; - template<> struct strongest_numeric_type { typedef float T; }; - template<> struct strongest_numeric_type { typedef float T; }; - template<> struct strongest_numeric_type { typedef float T; }; - template<> struct strongest_numeric_type { typedef double T; }; - template<> struct strongest_numeric_type { typedef double T; }; - - template - struct strongest_value_type { - typedef typename - strongest_numeric_type::value_type, - typename linalg_traits::value_type>::T - value_type; - }; - template - struct strongest_value_type3 { - typedef typename - strongest_value_type::value_type>::value_type - value_type; - }; - - - - /* ******************************************************************** */ - /* Basic vectors used */ - /* ******************************************************************** */ - - template struct dense_vector_type - { typedef std::vector vector_type; }; - - template class wsvector; - template class rsvector; - template class dsvector; - template struct sparse_vector_type - { typedef wsvector vector_type; }; - - template class slvector; - template class dense_matrix; - template class row_matrix; - template class col_matrix; - - - /* ******************************************************************** */ - /* Selects a temporary vector type */ - /* V if V is a valid vector type, */ - /* wsvector if V is a reference on a sparse vector, */ - /* std::vector if V is a reference on a dense vector. */ - /* ******************************************************************** */ - - - template - struct temporary_vector_ { - typedef abstract_null_type vector_type; - }; - template - struct temporary_vector_ - { typedef wsvector::value_type> vector_type; }; - template - struct temporary_vector_ - { typedef slvector::value_type> vector_type; }; - template - struct temporary_vector_ - { typedef std::vector::value_type> vector_type; }; - template - struct temporary_vector_ - { typedef V vector_type; }; - template - struct temporary_vector_ - { typedef std::vector::value_type> vector_type; }; - template - struct temporary_vector_ - { typedef wsvector::value_type> vector_type; }; - - template struct temporary_vector { - typedef typename temporary_vector_::reference, - typename linalg_traits::storage_type, - typename linalg_traits::linalg_type, - V>::vector_type vector_type; - }; - - /* ******************************************************************** */ - /* Selects a temporary matrix type */ - /* M if M is a valid matrix type, */ - /* row_matrix if M is a reference on a sparse matrix, */ - /* dense_matrix if M is a reference on a dense matrix. */ - /* ******************************************************************** */ - - - template - struct temporary_matrix_ { typedef abstract_null_type matrix_type; }; - template - struct temporary_matrix_ { - typedef typename linalg_traits::value_type T; - typedef row_matrix > matrix_type; - }; - template - struct temporary_matrix_ { - typedef typename linalg_traits::value_type T; - typedef row_matrix > matrix_type; - }; - template - struct temporary_matrix_ - { typedef dense_matrix::value_type> matrix_type; }; - template - struct temporary_matrix_ - { typedef V matrix_type; }; - - template struct temporary_matrix { - typedef typename temporary_matrix_::reference, - typename linalg_traits::storage_type, - typename linalg_traits::linalg_type, - V>::matrix_type matrix_type; - }; - - - template - struct temporary_col_matrix_ { typedef abstract_null_type matrix_type; }; - template - struct temporary_col_matrix_ { - typedef typename linalg_traits::value_type T; - typedef col_matrix > matrix_type; - }; - template - struct temporary_col_matrix_ { - typedef typename linalg_traits::value_type T; - typedef col_matrix > matrix_type; - }; - template - struct temporary_col_matrix_ - { typedef dense_matrix::value_type> matrix_type; }; - - template struct temporary_col_matrix { - typedef typename temporary_col_matrix_< - typename linalg_traits::storage_type, - typename linalg_traits::linalg_type, - V>::matrix_type matrix_type; - }; - - - - - template - struct temporary_row_matrix_ { typedef abstract_null_type matrix_type; }; - template - struct temporary_row_matrix_ { - typedef typename linalg_traits::value_type T; - typedef row_matrix > matrix_type; - }; - template - struct temporary_row_matrix_ { - typedef typename linalg_traits::value_type T; - typedef row_matrix > matrix_type; - }; - template - struct temporary_row_matrix_ - { typedef dense_matrix::value_type> matrix_type; }; - - template struct temporary_row_matrix { - typedef typename temporary_row_matrix_< - typename linalg_traits::storage_type, - typename linalg_traits::linalg_type, - V>::matrix_type matrix_type; - }; - - - - /* ******************************************************************** */ - /* Selects a temporary dense vector type */ - /* V if V is a valid dense vector type, */ - /* std::vector if V is a reference or another type of vector */ - /* ******************************************************************** */ - - template - struct temporary_dense_vector_ { typedef abstract_null_type vector_type; }; - template - struct temporary_dense_vector_ - { typedef std::vector::value_type> vector_type; }; - template - struct temporary_dense_vector_ - { typedef std::vector::value_type> vector_type; }; - template - struct temporary_dense_vector_ - { typedef std::vector::value_type> vector_type; }; - template - struct temporary_dense_vector_ - { typedef V vector_type; }; - - template struct temporary_dense_vector { - typedef typename temporary_dense_vector_::reference, - typename linalg_traits::storage_type, V>::vector_type vector_type; - }; - - /* ******************************************************************** */ - /* Selects a temporary sparse vector type */ - /* V if V is a valid sparse vector type, */ - /* wsvector if V is a reference or another type of vector */ - /* ******************************************************************** */ - - template - struct temporary_sparse_vector_ { typedef abstract_null_type vector_type; }; - template - struct temporary_sparse_vector_ - { typedef wsvector::value_type> vector_type; }; - template - struct temporary_sparse_vector_ - { typedef V vector_type; }; - template - struct temporary_sparse_vector_ - { typedef wsvector::value_type> vector_type; }; - template - struct temporary_sparse_vector_ - { typedef wsvector::value_type> vector_type; }; - - template struct temporary_sparse_vector { - typedef typename temporary_sparse_vector_::reference, - typename linalg_traits::storage_type, V>::vector_type vector_type; - }; - - /* ******************************************************************** */ - /* Selects a temporary sky-line vector type */ - /* V if V is a valid sky-line vector type, */ - /* slvector if V is a reference or another type of vector */ - /* ******************************************************************** */ - - template - struct temporary_skyline_vector_ - { typedef abstract_null_type vector_type; }; - template - struct temporary_skyline_vector_ - { typedef slvector::value_type> vector_type; }; - template - struct temporary_skyline_vector_ - { typedef V vector_type; }; - template - struct temporary_skyline_vector_ - { typedef slvector::value_type> vector_type; }; - template - struct temporary_skyline_vector_ - { typedef slvector::value_type> vector_type; }; - - template struct temporary_skylines_vector { - typedef typename temporary_skyline_vector_::reference, - typename linalg_traits::storage_type, V>::vector_type vector_type; - }; - - /* ********************************************************************* */ - /* Definition & Comparison of origins. */ - /* ********************************************************************* */ - - template - typename select_return::origin_type *, - typename linalg_traits::origin_type *, - L *>::return_type - linalg_origin(L &l) - { return linalg_traits::origin(linalg_cast(l)); } - - template - typename select_return::origin_type *, - typename linalg_traits::origin_type *, - const L *>::return_type - linalg_origin(const L &l) - { return linalg_traits::origin(linalg_cast(l)); } - - template - bool same_porigin(PT1, PT2) { return false; } - - template - bool same_porigin(PT pt1, PT pt2) { return (pt1 == pt2); } - - template - bool same_origin(const L1 &l1, const L2 &l2) - { return same_porigin(linalg_origin(l1), linalg_origin(l2)); } - - - /* ******************************************************************** */ - /* Miscellaneous */ - /* ******************************************************************** */ - - template inline size_type vect_size(const V &v) - { return linalg_traits::size(v); } - - template inline size_type mat_nrows(const MAT &m) - { return linalg_traits::nrows(m); } - - template inline size_type mat_ncols(const MAT &m) - { return linalg_traits::ncols(m); } - - - template inline - typename select_return::const_iterator, - typename linalg_traits::iterator, V *>::return_type - vect_begin(V &v) - { return linalg_traits::begin(linalg_cast(v)); } - - template inline - typename select_return::const_iterator, - typename linalg_traits::iterator, const V *>::return_type - vect_begin(const V &v) - { return linalg_traits::begin(linalg_cast(v)); } - - template inline - typename linalg_traits::const_iterator - vect_const_begin(const V &v) - { return linalg_traits::begin(v); } - - template inline - typename select_return::const_iterator, - typename linalg_traits::iterator, V *>::return_type - vect_end(V &v) - { return linalg_traits::end(linalg_cast(v)); } - - template inline - typename select_return::const_iterator, - typename linalg_traits::iterator, const V *>::return_type - vect_end(const V &v) - { return linalg_traits::end(linalg_cast(v)); } - - template inline - typename linalg_traits::const_iterator - vect_const_end(const V &v) - { return linalg_traits::end(v); } - - template inline - typename select_return::const_row_iterator, - typename linalg_traits::row_iterator, M *>::return_type - mat_row_begin(M &m) { return linalg_traits::row_begin(linalg_cast(m)); } - - template inline - typename select_return::const_row_iterator, - typename linalg_traits::row_iterator, const M *>::return_type - mat_row_begin(const M &m) - { return linalg_traits::row_begin(linalg_cast(m)); } - - template inline typename linalg_traits::const_row_iterator - mat_row_const_begin(const M &m) - { return linalg_traits::row_begin(m); } - - template inline - typename select_return::const_row_iterator, - typename linalg_traits::row_iterator, M *>::return_type - mat_row_end(M &v) { - return linalg_traits::row_end(linalg_cast(v)); - } - - template inline - typename select_return::const_row_iterator, - typename linalg_traits::row_iterator, const M *>::return_type - mat_row_end(const M &v) { - return linalg_traits::row_end(linalg_cast(v)); - } - - template inline - typename linalg_traits::const_row_iterator - mat_row_const_end(const M &v) - { return linalg_traits::row_end(v); } - - template inline - typename select_return::const_col_iterator, - typename linalg_traits::col_iterator, M *>::return_type - mat_col_begin(M &v) { - return linalg_traits::col_begin(linalg_cast(v)); - } - - template inline - typename select_return::const_col_iterator, - typename linalg_traits::col_iterator, const M *>::return_type - mat_col_begin(const M &v) { - return linalg_traits::col_begin(linalg_cast(v)); - } - - template inline - typename linalg_traits::const_col_iterator - mat_col_const_begin(const M &v) - { return linalg_traits::col_begin(v); } - - template inline - typename linalg_traits::const_col_iterator - mat_col_const_end(const M &v) - { return linalg_traits::col_end(v); } - - template inline - typename select_return::const_col_iterator, - typename linalg_traits::col_iterator, - M *>::return_type - mat_col_end(M &m) - { return linalg_traits::col_end(linalg_cast(m)); } - - template inline - typename select_return::const_col_iterator, - typename linalg_traits::col_iterator, - const M *>::return_type - mat_col_end(const M &m) - { return linalg_traits::col_end(linalg_cast(m)); } - - template inline - typename select_return::const_sub_row_type, - typename linalg_traits::sub_row_type, - const MAT *>::return_type - mat_row(const MAT &m, size_type i) - { return linalg_traits::row(mat_row_begin(m) + i); } - - template inline - typename select_return::const_sub_row_type, - typename linalg_traits::sub_row_type, - MAT *>::return_type - mat_row(MAT &m, size_type i) - { return linalg_traits::row(mat_row_begin(m) + i); } - - template inline - typename linalg_traits::const_sub_row_type - mat_const_row(const MAT &m, size_type i) - { return linalg_traits::row(mat_row_const_begin(m) + i); } - - template inline - typename select_return::const_sub_col_type, - typename linalg_traits::sub_col_type, - const MAT *>::return_type - mat_col(const MAT &m, size_type i) - { return linalg_traits::col(mat_col_begin(m) + i); } - - - template inline - typename select_return::const_sub_col_type, - typename linalg_traits::sub_col_type, - MAT *>::return_type - mat_col(MAT &m, size_type i) - { return linalg_traits::col(mat_col_begin(m) + i); } - - template inline - typename linalg_traits::const_sub_col_type - mat_const_col(const MAT &m, size_type i) - { return linalg_traits::col(mat_col_const_begin(m) + i); } - - /* ********************************************************************* */ - /* Set to begin end set to end for iterators on non-const sparse vectors.*/ - /* ********************************************************************* */ - - template inline - void set_to_begin(IT &it, ORG o, VECT *, linalg_false) - { it = vect_begin(*o); } - - template inline - void set_to_begin(IT &it, ORG o, const VECT *, linalg_false) - { it = vect_const_begin(*o); } - - template inline - void set_to_end(IT &it, ORG o, VECT *, linalg_false) - { it = vect_end(*o); } - - template inline - void set_to_end(IT &it, ORG o, const VECT *, linalg_false) - { it = vect_const_end(*o); } - - - template inline - void set_to_begin(IT &, ORG, VECT *, linalg_const) { } - - template inline - void set_to_begin(IT &, ORG, const VECT *, linalg_const) { } - - template inline - void set_to_end(IT &, ORG, VECT *, linalg_const) { } - - template inline - void set_to_end(IT &, ORG, const VECT *, linalg_const) { } - - template inline - void set_to_begin(IT &, ORG, VECT *v, linalg_modifiable) - { GMM_ASSERT3(!is_sparse(*v), "internal_error"); (void)v; } - - template inline - void set_to_begin(IT &, ORG, const VECT *v, linalg_modifiable) - { GMM_ASSERT3(!is_sparse(*v), "internal_error"); (void)v; } - - template inline - void set_to_end(IT &, ORG, VECT *v, linalg_modifiable) - { GMM_ASSERT3(!is_sparse(*v), "internal_error"); (void)v; } - - template inline - void set_to_end(IT &, ORG, const VECT *v, linalg_modifiable) - { GMM_ASSERT3(!is_sparse(*v), "internal_error"); (void)v; } - - /* ******************************************************************** */ - /* General index for certain algorithms. */ - /* ******************************************************************** */ - - template - size_type index_of_it(const IT &it, size_type, abstract_sparse) - { return it.index(); } - template - size_type index_of_it(const IT &it, size_type, abstract_skyline) - { return it.index(); } - template - size_type index_of_it(const IT &, size_type k, abstract_dense) - { return k; } - - /* ********************************************************************* */ - /* Numeric limits. */ - /* ********************************************************************* */ - - template inline T default_tol(T) { - using namespace std; - static T tol(10); - if (tol == T(10)) { - if (numeric_limits::is_specialized) - tol = numeric_limits::epsilon(); - else { - int i=int(sizeof(T)/4); while(i-- > 0) tol*=T(1E-8); - GMM_WARNING1("The numeric type " /*<< typeid(T).name()*/ - << " has no numeric_limits defined !!\n" - << "Taking " << tol << " as default tolerance"); - } - } - return tol; - } - template inline T default_tol(std::complex) - { return default_tol(T()); } - - template inline T default_min(T) { - using namespace std; - static T mi(10); - if (mi == T(10)) { - if (numeric_limits::is_specialized) - mi = std::numeric_limits::min(); - else { - mi = T(0); - GMM_WARNING1("The numeric type " /*<< typeid(T).name()*/ - << " has no numeric_limits defined !!\n" - << "Taking 0 as default minimum"); - } - } - return mi; - } - template inline T default_min(std::complex) - { return default_min(T()); } - - template inline T default_max(T) { - using namespace std; - static T mi(10); - if (mi == T(10)) { - if (numeric_limits::is_specialized) - mi = std::numeric_limits::max(); - else { - mi = T(1); - GMM_WARNING1("The numeric type " /*<< typeid(T).name()*/ - << " has no numeric_limits defined !!\n" - << "Taking 1 as default maximum !"); - } - } - return mi; - } - template inline T default_max(std::complex) - { return default_max(T()); } - - - /* - use safe_divide to avoid NaNs when dividing very small complex - numbers, for example - std::complex(1e-23,1e-30)/std::complex(1e-23,1e-30) - */ - template inline T safe_divide(T a, T b) { return a/b; } - template inline std::complex - safe_divide(std::complex a, std::complex b) { - T m = std::max(gmm::abs(b.real()), gmm::abs(b.imag())); - a = std::complex(a.real()/m, a.imag()/m); - b = std::complex(b.real()/m, b.imag()/m); - return a / b; - } - - - /* ******************************************************************** */ - /* Write */ - /* ******************************************************************** */ - - template struct cast_char_type { typedef T return_type; }; - template <> struct cast_char_type { typedef int return_type; }; - template <> struct cast_char_type - { typedef unsigned int return_type; }; - template inline typename cast_char_type::return_type - cast_char(const T &c) { return typename cast_char_type::return_type(c); } - - - template inline void write(std::ostream &o, const L &l) - { write(o, l, typename linalg_traits::linalg_type()); } - - template void write(std::ostream &o, const L &l, - abstract_vector) { - o << "vector(" << vect_size(l) << ") ["; - write(o, l, typename linalg_traits::storage_type()); - o << " ]"; - } - - template void write(std::ostream &o, const L &l, - abstract_sparse) { - typename linalg_traits::const_iterator it = vect_const_begin(l), - ite = vect_const_end(l); - for (; it != ite; ++it) - o << " (r" << it.index() << ", " << cast_char(*it) << ")"; - } - - template void write(std::ostream &o, const L &l, - abstract_dense) { - typename linalg_traits::const_iterator it = vect_const_begin(l), - ite = vect_const_end(l); - if (it != ite) o << " " << cast_char(*it++); - for (; it != ite; ++it) o << ", " << cast_char(*it); - } - - template void write(std::ostream &o, const L &l, - abstract_skyline) { - typedef typename linalg_traits::const_iterator const_iterator; - const_iterator it = vect_const_begin(l), ite = vect_const_end(l); - if (it != ite) { - o << ""; - if (it != ite) o << " " << cast_char(*it++); - for (; it != ite; ++it) { o << ", " << cast_char(*it); } - } - } - - template inline void write(std::ostream &o, const L &l, - abstract_matrix) { - write(o, l, typename linalg_traits::sub_orientation()); - } - - - template void write(std::ostream &o, const L &l, - row_major) { - o << "matrix(" << mat_nrows(l) << ", " << mat_ncols(l) << ")" << endl; - for (size_type i = 0; i < mat_nrows(l); ++i) { - o << "("; - write(o, mat_const_row(l, i), typename linalg_traits::storage_type()); - o << " )\n"; - } - } - - template inline - void write(std::ostream &o, const L &l, row_and_col) - { write(o, l, row_major()); } - - template inline - void write(std::ostream &o, const L &l, col_and_row) - { write(o, l, row_major()); } - - template void write(std::ostream &o, const L &l, col_major) { - o << "matrix(" << mat_nrows(l) << ", " << mat_ncols(l) << ")" << endl; - for (size_type i = 0; i < mat_nrows(l); ++i) { - o << "("; - if (is_sparse(l)) { // not optimized ... - for (size_type j = 0; j < mat_ncols(l); ++j) - if (l(i,j) != typename linalg_traits::value_type(0)) - o << " (r" << j << ", " << l(i,j) << ")"; - } - else { - if (mat_ncols(l) != 0) o << ' ' << l(i, 0); - for (size_type j = 1; j < mat_ncols(l); ++j) o << ", " << l(i, j); - } - o << " )\n"; - } - } - -} - -#endif // GMM_DEF_H__ diff --git a/gmm/gmm_dense_Householder.h b/gmm/gmm_dense_Householder.h deleted file mode 100644 index 4dcb3cd24..000000000 --- a/gmm/gmm_dense_Householder.h +++ /dev/null @@ -1,317 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard, Caroline Lecalvez - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_dense_Householder.h - @author Caroline Lecalvez - @author Yves Renard - @date June 5, 2003. - @brief Householder for dense matrices. -*/ - -#ifndef GMM_DENSE_HOUSEHOLDER_H -#define GMM_DENSE_HOUSEHOLDER_H - -#include "gmm_kernel.h" - -namespace gmm { - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - /* ********************************************************************* */ - /* Rank one update (complex and real version) */ - /* ********************************************************************* */ - - template - inline void rank_one_update(Matrix &A, const VecX& x, - const VecY& y, row_major) { - typedef typename linalg_traits::value_type T; - size_type N = mat_nrows(A); - GMM_ASSERT2(N <= vect_size(x) && mat_ncols(A) <= vect_size(y), - "dimensions mismatch"); - typename linalg_traits::const_iterator itx = vect_const_begin(x); - for (size_type i = 0; i < N; ++i, ++itx) { - typedef typename linalg_traits::sub_row_type row_type; - row_type row = mat_row(A, i); - typename linalg_traits::t>::iterator - it = vect_begin(row), ite = vect_end(row); - typename linalg_traits::const_iterator ity = vect_const_begin(y); - T tx = *itx; - for (; it != ite; ++it, ++ity) *it += conj_product(*ity, tx); - } - } - - template - inline void rank_one_update(Matrix &A, const VecX& x, - const VecY& y, col_major) { - typedef typename linalg_traits::value_type T; - size_type M = mat_ncols(A); - GMM_ASSERT2(mat_nrows(A) <= vect_size(x) && M <= vect_size(y), - "dimensions mismatch"); - typename linalg_traits::const_iterator ity = vect_const_begin(y); - for (size_type i = 0; i < M; ++i, ++ity) { - typedef typename linalg_traits::sub_col_type col_type; - col_type col = mat_col(A, i); - typename linalg_traits::t>::iterator - it = vect_begin(col), ite = vect_end(col); - typename linalg_traits::const_iterator itx = vect_const_begin(x); - T ty = *ity; - for (; it != ite; ++it, ++itx) *it += conj_product(ty, *itx); - } - } - - ///@endcond - template - inline void rank_one_update(const Matrix &AA, const VecX& x, - const VecY& y) { - Matrix& A = const_cast(AA); - rank_one_update(A, x, y, typename principal_orientation_type::sub_orientation>::potype()); - } - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - /* ********************************************************************* */ - /* Rank two update (complex and real version) */ - /* ********************************************************************* */ - - template - inline void rank_two_update(Matrix &A, const VecX& x, - const VecY& y, row_major) { - typedef typename linalg_traits::value_type value_type; - size_type N = mat_nrows(A); - GMM_ASSERT2(N <= vect_size(x) && mat_ncols(A) <= vect_size(y), - "dimensions mismatch"); - typename linalg_traits::const_iterator itx1 = vect_const_begin(x); - typename linalg_traits::const_iterator ity2 = vect_const_begin(y); - for (size_type i = 0; i < N; ++i, ++itx1, ++ity2) { - typedef typename linalg_traits::sub_row_type row_type; - row_type row = mat_row(A, i); - typename linalg_traits::t>::iterator - it = vect_begin(row), ite = vect_end(row); - typename linalg_traits::const_iterator itx2 = vect_const_begin(x); - typename linalg_traits::const_iterator ity1 = vect_const_begin(y); - value_type tx = *itx1, ty = *ity2; - for (; it != ite; ++it, ++ity1, ++itx2) - *it += conj_product(*ity1, tx) + conj_product(*itx2, ty); - } - } - - template - inline void rank_two_update(Matrix &A, const VecX& x, - const VecY& y, col_major) { - typedef typename linalg_traits::value_type value_type; - size_type M = mat_ncols(A); - GMM_ASSERT2(mat_nrows(A) <= vect_size(x) && M <= vect_size(y), - "dimensions mismatch"); - typename linalg_traits::const_iterator itx2 = vect_const_begin(x); - typename linalg_traits::const_iterator ity1 = vect_const_begin(y); - for (size_type i = 0; i < M; ++i, ++ity1, ++itx2) { - typedef typename linalg_traits::sub_col_type col_type; - col_type col = mat_col(A, i); - typename linalg_traits::t>::iterator - it = vect_begin(col), ite = vect_end(col); - typename linalg_traits::const_iterator itx1 = vect_const_begin(x); - typename linalg_traits::const_iterator ity2 = vect_const_begin(y); - value_type ty = *ity1, tx = *itx2; - for (; it != ite; ++it, ++itx1, ++ity2) - *it += conj_product(ty, *itx1) + conj_product(tx, *ity2); - } - } - - ///@endcond - template - inline void rank_two_update(const Matrix &AA, const VecX& x, - const VecY& y) { - Matrix& A = const_cast(AA); - rank_two_update(A, x, y, typename principal_orientation_type::sub_orientation>::potype()); - } - ///@cond DOXY_SHOW_ALL_FUNCTIONS - - /* ********************************************************************* */ - /* Householder vector computation (complex and real version) */ - /* ********************************************************************* */ - - template void house_vector(const VECT &VV) { - VECT &V = const_cast(VV); - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - R mu = vect_norm2(V), abs_v0 = gmm::abs(V[0]); - if (mu != R(0)) - gmm::scale(V, (abs_v0 == R(0)) ? T(R(1) / mu) - : (safe_divide(T(abs_v0), V[0]) / (abs_v0 + mu))); - if (gmm::real(V[vect_size(V)-1]) * R(0) != R(0)) gmm::clear(V); - V[0] = T(1); - } - - template void house_vector_last(const VECT &VV) { - VECT &V = const_cast(VV); - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - size_type m = vect_size(V); - R mu = vect_norm2(V), abs_v0 = gmm::abs(V[m-1]); - if (mu != R(0)) - gmm::scale(V, (abs_v0 == R(0)) ? T(R(1) / mu) - : ((abs_v0 / V[m-1]) / (abs_v0 + mu))); - if (gmm::real(V[0]) * R(0) != R(0)) gmm::clear(V); - V[m-1] = T(1); - } - - /* ********************************************************************* */ - /* Householder updates (complex and real version) */ - /* ********************************************************************* */ - - // multiply A to the left by the reflector stored in V. W is a temporary. - template inline - void row_house_update(const MAT &AA, const VECT1 &V, const VECT2 &WW) { - VECT2 &W = const_cast(WW); MAT &A = const_cast(AA); - typedef typename linalg_traits::value_type value_type; - typedef typename number_traits::magnitude_type magnitude_type; - - gmm::mult(conjugated(A), - scaled(V, value_type(magnitude_type(-2)/vect_norm2_sqr(V))), W); - rank_one_update(A, V, W); - } - - // multiply A to the right by the reflector stored in V. W is a temporary. - template inline - void col_house_update(const MAT &AA, const VECT1 &V, const VECT2 &WW) { - VECT2 &W = const_cast(WW); MAT &A = const_cast(AA); - typedef typename linalg_traits::value_type value_type; - typedef typename number_traits::magnitude_type magnitude_type; - - gmm::mult(A, - scaled(V, value_type(magnitude_type(-2)/vect_norm2_sqr(V))), W); - rank_one_update(A, W, V); - } - - ///@endcond - - /* ********************************************************************* */ - /* Hessenberg reduction with Householder. */ - /* ********************************************************************* */ - - template - void Hessenberg_reduction(const MAT1& AA, const MAT2 &QQ, bool compute_Q){ - MAT1& A = const_cast(AA); MAT2& Q = const_cast(QQ); - typedef typename linalg_traits::value_type value_type; - if (compute_Q) gmm::copy(identity_matrix(), Q); - size_type n = mat_nrows(A); if (n < 2) return; - std::vector v(n), w(n); - sub_interval SUBK(0,n); - for (size_type k = 1; k+1 < n; ++k) { - sub_interval SUBI(k, n-k), SUBJ(k-1,n-k+1); - v.resize(n-k); - for (size_type j = k; j < n; ++j) v[j-k] = A(j, k-1); - house_vector(v); - row_house_update(sub_matrix(A, SUBI, SUBJ), v, sub_vector(w, SUBJ)); - col_house_update(sub_matrix(A, SUBK, SUBI), v, w); - // is it possible to "unify" the two on the common part of the matrix? - if (compute_Q) col_house_update(sub_matrix(Q, SUBK, SUBI), v, w); - } - } - - /* ********************************************************************* */ - /* Householder tridiagonalization for symmetric matrices */ - /* ********************************************************************* */ - - template - void Householder_tridiagonalization(const MAT1 &AA, const MAT2 &QQ, - bool compute_q) { - MAT1 &A = const_cast(AA); MAT2 &Q = const_cast(QQ); - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - size_type n = mat_nrows(A); if (n < 2) return; - std::vector v(n), p(n), w(n), ww(n); - sub_interval SUBK(0,n); - - for (size_type k = 1; k+1 < n; ++k) { // not optimized ... - sub_interval SUBI(k, n-k); - v.resize(n-k); p.resize(n-k); w.resize(n-k); - for (size_type l = k; l < n; ++l) - { v[l-k] = w[l-k] = A(l, k-1); A(l, k-1) = A(k-1, l) = T(0); } - house_vector(v); - R norm = vect_norm2_sqr(v); - A(k-1, k) = gmm::conj(A(k, k-1) = w[0] - T(2)*v[0]*vect_hp(w, v)/norm); - - gmm::mult(sub_matrix(A, SUBI), gmm::scaled(v, T(-2) / norm), p); - gmm::add(p, gmm::scaled(v, -vect_hp(v, p) / norm), w); - rank_two_update(sub_matrix(A, SUBI), v, w); - // it should be possible to compute only the upper or lower part - - if (compute_q) col_house_update(sub_matrix(Q, SUBK, SUBI), v, ww); - } - } - - /* ********************************************************************* */ - /* Real and complex Givens rotations */ - /* ********************************************************************* */ - - template void Givens_rotation(T a, T b, T &c, T &s) { - typedef typename number_traits::magnitude_type R; - R aa = gmm::abs(a), bb = gmm::abs(b); - if (bb == R(0)) { c = T(1); s = T(0); return; } - if (aa == R(0)) { c = T(0); s = b / bb; return; } - if (bb > aa) - { T t = -safe_divide(a,b); s = T(R(1) / (sqrt(R(1)+gmm::abs_sqr(t)))); c = s * t; } - else - { T t = -safe_divide(b,a); c = T(R(1) / (sqrt(R(1)+gmm::abs_sqr(t)))); s = c * t; } - } - - // Apply Q* v - template inline - void Apply_Givens_rotation_left(T &x, T &y, T c, T s) - { T t1=x, t2=y; x = gmm::conj(c)*t1 - gmm::conj(s)*t2; y = c*t2 + s*t1; } - - // Apply v^T Q - template inline - void Apply_Givens_rotation_right(T &x, T &y, T c, T s) - { T t1=x, t2=y; x = c*t1 - s*t2; y = gmm::conj(c)*t2 + gmm::conj(s)*t1; } - - template - void row_rot(const MAT &AA, T c, T s, size_type i, size_type k) { - MAT &A = const_cast(AA); // can be specialized for row matrices - for (size_type j = 0; j < mat_ncols(A); ++j) - Apply_Givens_rotation_left(A(i,j), A(k,j), c, s); - } - - template - void col_rot(const MAT &AA, T c, T s, size_type i, size_type k) { - MAT &A = const_cast(AA); // can be specialized for column matrices - for (size_type j = 0; j < mat_nrows(A); ++j) - Apply_Givens_rotation_right(A(j,i), A(j,k), c, s); - } - -} - -#endif - diff --git a/gmm/gmm_dense_lu.h b/gmm/gmm_dense_lu.h deleted file mode 100644 index 1c6269adb..000000000 --- a/gmm/gmm_dense_lu.h +++ /dev/null @@ -1,288 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -// This file is a modified version of lu.h from MTL. -// See http://osl.iu.edu/research/mtl/ -// Following the corresponding Copyright notice. -//=========================================================================== -// -// Copyright (c) 1998-2001, University of Notre Dame. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of Notre Dame nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE TRUSTEES OF INDIANA UNIVERSITY AND -// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES -// OF INDIANA UNIVERSITY AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//=========================================================================== - -/**@file gmm_dense_lu.h - @author Andrew Lumsdaine, Jeremy G. Siek, Lie-Quan Lee, Y. Renard - @date June 5, 2003. - @brief LU factorizations and determinant computation for dense matrices. -*/ -#ifndef GMM_DENSE_LU_H -#define GMM_DENSE_LU_H - -#include "gmm_dense_Householder.h" - -namespace gmm { - - /* ********************************************************************** */ - /* IPVT structure. */ - /* ********************************************************************** */ - // For compatibility with lapack version with 64 or 32 bit integer. - // Should be replaced by std::vector if 32 bit integer version - // of lapack is not used anymore (and lapack_ipvt_int set to size_type) - - // Do not use iterators of this interface container - class lapack_ipvt : public std::vector { - bool is_int64; - size_type &operator[](size_type i) - { return std::vector::operator[](i); } - size_type operator[] (size_type i) const - { return std::vector::operator[](i); } - void begin(void) const {} - void begin(void) {} - void end(void) const {} - void end(void) {} - - public: - void set_to_int32() { is_int64 = false; } - const size_type *pfirst() const - { return &(*(std::vector::begin())); } - size_type *pfirst() { return &(*(std::vector::begin())); } - - lapack_ipvt(size_type n) : std::vector(n), is_int64(true) {} - - size_type get(size_type i) const { - const size_type *p = pfirst(); - return is_int64 ? p[i] : size_type(((const int *)(p))[i]); - } - void set(size_type i, size_type val) { - size_type *p = pfirst(); - if (is_int64) p[i] = val; else ((int *)(p))[i] = int(val); - } - }; -} - -#include "gmm_opt.h" - -namespace gmm { - - /** LU Factorization of a general (dense) matrix (real or complex). - - This is the outer product (a level-2 operation) form of the LU - Factorization with pivoting algorithm . This is equivalent to - LAPACK's dgetf2. Also see "Matrix Computations" 3rd Ed. by Golub - and Van Loan section 3.2.5 and especially page 115. - - The pivot indices in ipvt are indexed starting from 1 - so that this is compatible with LAPACK (Fortran). - */ - template - size_type lu_factor(DenseMatrix& A, lapack_ipvt& ipvt) { - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - size_type info(0), i, j, jp, M(mat_nrows(A)), N(mat_ncols(A)); - size_type NN = std::min(M, N); - std::vector c(M), r(N); - - GMM_ASSERT2(ipvt.size()+1 >= NN, "IPVT too small"); - for (i = 0; i+1 < NN; ++i) ipvt.set(i, i); - - if (M || N) { - for (j = 0; j+1 < NN; ++j) { - R max = gmm::abs(A(j,j)); jp = j; - for (i = j+1; i < M; ++i) /* find pivot. */ - if (gmm::abs(A(i,j)) > max) { jp = i; max = gmm::abs(A(i,j)); } - ipvt.set(j, jp + 1); - - if (max == R(0)) { info = j + 1; break; } - if (jp != j) for (i = 0; i < N; ++i) std::swap(A(jp, i), A(j, i)); - - for (i = j+1; i < M; ++i) { A(i, j) /= A(j,j); c[i-j-1] = -A(i, j); } - for (i = j+1; i < N; ++i) r[i-j-1] = A(j, i); // avoid the copy ? - rank_one_update(sub_matrix(A, sub_interval(j+1, M-j-1), - sub_interval(j+1, N-j-1)), c, conjugated(r)); - } - ipvt.set(NN-1, NN); - } - return info; - } - - /** LU Solve : Solve equation Ax=b, given an LU factored matrix.*/ - // Thanks to Valient Gough for this routine! - template - void lu_solve(const DenseMatrix &LU, const Pvector& pvector, - VectorX &x, const VectorB &b) { - typedef typename linalg_traits::value_type T; - copy(b, x); - for(size_type i = 0; i < pvector.size(); ++i) { - size_type perm = pvector.get(i)-1; // permutations stored in 1's offset - if(i != perm) { T aux = x[i]; x[i] = x[perm]; x[perm] = aux; } - } - /* solve Ax = b -> LUx = b -> Ux = L^-1 b. */ - lower_tri_solve(LU, x, true); - upper_tri_solve(LU, x, false); - } - - template - void lu_solve(const DenseMatrix &A, VectorX &x, const VectorB &b) { - typedef typename linalg_traits::value_type T; - dense_matrix B(mat_nrows(A), mat_ncols(A)); - lapack_ipvt ipvt(mat_nrows(A)); - gmm::copy(A, B); - size_type info = lu_factor(B, ipvt); - GMM_ASSERT1(!info, "Singular system, pivot = " << info); - lu_solve(B, ipvt, x, b); - } - - template - void lu_solve_transposed(const DenseMatrix &LU, const Pvector& pvector, - VectorX &x, const VectorB &b) { - typedef typename linalg_traits::value_type T; - copy(b, x); - lower_tri_solve(transposed(LU), x, false); - upper_tri_solve(transposed(LU), x, true); - for(size_type i = pvector.size(); i > 0; --i) { - size_type perm = pvector.get(i-1)-1; // permutations stored in 1's offset - if(i-1 != perm) { T aux = x[i-1]; x[i-1] = x[perm]; x[perm] = aux; } - } - } - - - ///@cond DOXY_SHOW_ALL_FUNCTIONS - template - void lu_inverse(const DenseMatrixLU& LU, const Pvector& pvector, - DenseMatrix& AInv, col_major) { - typedef typename linalg_traits::value_type T; - std::vector tmp(pvector.size(), T(0)); - std::vector result(pvector.size()); - for(size_type i = 0; i < pvector.size(); ++i) { - tmp[i] = T(1); - lu_solve(LU, pvector, result, tmp); - copy(result, mat_col(AInv, i)); - tmp[i] = T(0); - } - } - - template - void lu_inverse(const DenseMatrixLU& LU, const Pvector& pvector, - DenseMatrix& AInv, row_major) { - typedef typename linalg_traits::value_type T; - std::vector tmp(pvector.size(), T(0)); - std::vector result(pvector.size()); - for(size_type i = 0; i < pvector.size(); ++i) { - tmp[i] = T(1); // to be optimized !! - // on peut sur le premier tri solve reduire le systeme - // et peut etre faire un solve sur une serie de vecteurs au lieu - // de vecteur a vecteur (accumulation directe de l'inverse dans la - // matrice au fur et a mesure du calcul ... -> evite la copie finale - lu_solve_transposed(LU, pvector, result, tmp); - copy(result, mat_row(AInv, i)); - tmp[i] = T(0); - } - } - ///@endcond - - /** Given an LU factored matrix, build the inverse of the matrix. */ - template - void lu_inverse(const DenseMatrixLU& LU, const Pvector& pvector, - const DenseMatrix& AInv_) { - DenseMatrix& AInv = const_cast(AInv_); - lu_inverse(LU, pvector, AInv, typename principal_orientation_type::sub_orientation>::potype()); - } - - /** Given a dense matrix, build the inverse of the matrix, and - return the determinant */ - template - typename linalg_traits::value_type - lu_inverse(const DenseMatrix& A_, bool doassert = true) { - typedef typename linalg_traits::value_type T; - DenseMatrix& A = const_cast(A_); - dense_matrix B(mat_nrows(A), mat_ncols(A)); - lapack_ipvt ipvt(mat_nrows(A)); - gmm::copy(A, B); - size_type info = lu_factor(B, ipvt); - if (doassert) GMM_ASSERT1(!info, "Non invertible matrix, pivot = "< - typename linalg_traits::value_type - lu_det(const DenseMatrixLU& LU, const Pvector &pvector) { - typedef typename linalg_traits::value_type T; - T det(1); - for (size_type j = 0; j < std::min(mat_nrows(LU), mat_ncols(LU)); ++j) - det *= LU(j,j); - for(size_type i = 0; i < pvector.size(); ++i) - if (i != size_type(pvector.get(i)-1)) { det = -det; } - return det; - } - - template - typename linalg_traits::value_type - lu_det(const DenseMatrix& A) { - typedef typename linalg_traits::value_type T; - dense_matrix B(mat_nrows(A), mat_ncols(A)); - lapack_ipvt ipvt(mat_nrows(A)); - gmm::copy(A, B); - lu_factor(B, ipvt); - return lu_det(B, ipvt); - } - -} - -#endif - diff --git a/gmm/gmm_dense_matrix_functions.h b/gmm/gmm_dense_matrix_functions.h deleted file mode 100644 index 6005918a4..000000000 --- a/gmm/gmm_dense_matrix_functions.h +++ /dev/null @@ -1,302 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2014-2017 Konstantinos Poulios - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_dense_matrix_functions.h - @author Konstantinos Poulios - @date December 10, 2014. - @brief Common matrix functions for dense matrices. -*/ -#ifndef GMM_DENSE_MATRIX_FUNCTIONS_H -#define GMM_DENSE_MATRIX_FUNCTIONS_H - - -namespace gmm { - - - /** - Matrix square root for upper triangular matrices (from GNU Octave). - */ - template - void sqrtm_utri_inplace(dense_matrix& A) - { - typedef typename number_traits::magnitude_type R; - bool singular = false; - - // The following code is equivalent to this triple loop: - // - // n = rows (A); - // for j = 1:n - // A(j,j) = sqrt (A(j,j)); - // for i = j-1:-1:1 - // A(i,j) /= (A(i,i) + A(j,j)); - // k = 1:i-1; - // t storing a A(k,j) -= A(k,i) * A(i,j); - // endfor - // endfor - - R tol = R(0); // default_tol(R()) * gmm::mat_maxnorm(A); - - const size_type n = mat_nrows(A); - for (int j=0; j < int(n); j++) { - typename dense_matrix::iterator colj = A.begin() + j*n; - if (gmm::abs(colj[j]) > tol) - colj[j] = gmm::sqrt(colj[j]); - else - singular = true; - - for (int i=j-1; i >= 0; i--) { - typename dense_matrix::const_iterator coli = A.begin() + i*n; - T colji = colj[i] = safe_divide(colj[i], (coli[i] + colj[j])); - for (int k = 0; k < i; k++) - colj[k] -= coli[k] * colji; - } - } - - if (singular) - GMM_WARNING1("Matrix is singular, may not have a square root"); - } - - - template - void sqrtm(const dense_matrix >& A, - dense_matrix >& SQRTMA) - { - GMM_ASSERT1(gmm::mat_nrows(A) == gmm::mat_ncols(A), - "Matrix square root requires a square matrix"); - gmm::resize(SQRTMA, gmm::mat_nrows(A), gmm::mat_ncols(A)); - dense_matrix > S(A), Q(A), TMP(A); - #if defined(GMM_USES_LAPACK) - schur(TMP, S, Q); - #else - GMM_ASSERT1(false, "Please recompile with lapack and blas librairies " - "to use sqrtm matrix function."); - #endif - sqrtm_utri_inplace(S); - gmm::mult(Q, S, TMP); - gmm::mult(TMP, gmm::transposed(Q), SQRTMA); - } - - template - void sqrtm(const dense_matrix& A, - dense_matrix >& SQRTMA) - { - dense_matrix > cA(mat_nrows(A), mat_ncols(A)); - gmm::copy(A, gmm::real_part(cA)); - sqrtm(cA, SQRTMA); - } - - template - void sqrtm(const dense_matrix& A, dense_matrix& SQRTMA) - { - dense_matrix > cA(mat_nrows(A), mat_ncols(A)); - gmm::copy(A, gmm::real_part(cA)); - dense_matrix > cSQRTMA(cA); - sqrtm(cA, cSQRTMA); - gmm::resize(SQRTMA, gmm::mat_nrows(A), gmm::mat_ncols(A)); - gmm::copy(gmm::real_part(cSQRTMA), SQRTMA); -// dense_matrix >::const_reference -// it = cSQRTMA.begin(), ite = cSQRTMA.end(); -// dense_matrix >::reference -// rit = SQRTMA.begin(); -// for (; it != ite; ++it, ++rit) *rit = it->real(); - } - - - /** - Matrix logarithm for upper triangular matrices (from GNU/Octave) - */ - template - void logm_utri_inplace(dense_matrix& S) - { - typedef typename number_traits::magnitude_type R; - - size_type n = gmm::mat_nrows(S); - GMM_ASSERT1(n == gmm::mat_ncols(S), - "Matrix logarithm is not defined for non-square matrices"); - for (size_type i=0; i < n-1; ++i) - if (gmm::abs(S(i+1,i)) > default_tol(T())) { - GMM_ASSERT1(false, "An upper triangular matrix is expected"); - break; - } - for (size_type i=0; i < n-1; ++i) - if (gmm::real(S(i,i)) <= -default_tol(R()) && - gmm::abs(gmm::imag(S(i,i))) <= default_tol(R())) { - GMM_ASSERT1(false, "Principal matrix logarithm is not defined " - "for matrices with negative eigenvalues"); - break; - } - - // Algorithm 11.9 in "Function of matrices", by N. Higham - R theta[] = { R(0),R(0),R(1.61e-2),R(5.38e-2),R(1.13e-1),R(1.86e-1),R(2.6429608311114350e-1) }; - - R scaling(1); - size_type p(0), m(6), opt_iters(100); - for (size_type k=0; k < opt_iters; ++k, scaling *= R(2)) { - dense_matrix auxS(S); - for (size_type i = 0; i < n; ++i) auxS(i,i) -= R(1); - R tau = gmm::mat_norm1(auxS); - if (tau <= theta[6]) { - ++p; - size_type j1(6), j2(6); - for (size_type j=0; j < 6; ++j) - if (tau <= theta[j]) { j1 = j; break; } - for (size_type j=0; j < j1; ++j) - if (tau <= 2*theta[j]) { j2 = j; break; } - if (j1 - j2 <= 1 || p == 2) { m = j1; break; } - } - sqrtm_utri_inplace(S); - if (k == opt_iters-1) - GMM_WARNING1 ("Maximum number of square roots exceeded; " - "the calculated matrix logarithm may still be accurate"); - } - - for (size_type i = 0; i < n; ++i) S(i,i) -= R(1); - - if (m > 0) { - - std::vector nodes, wts; - switch(m) { - case 0: { - R nodes_[] = { R(0.5) }; - R wts_[] = { R(1) }; - nodes.assign(nodes_, nodes_+m+1); - wts.assign(wts_, wts_+m+1); - } break; - case 1: { - R nodes_[] = { R(0.211324865405187),R(0.788675134594813) }; - R wts_[] = { R(0.5),R(0.5) }; - nodes.assign(nodes_, nodes_+m+1); - wts.assign(wts_, wts_+m+1); - } break; - case 2: { - R nodes_[] = { R(0.112701665379258),R(0.500000000000000),R(0.887298334620742) }; - R wts_[] = { R(0.277777777777778),R(0.444444444444444),R(0.277777777777778) }; - nodes.assign(nodes_, nodes_+m+1); - wts.assign(wts_, wts_+m+1); - } break; - case 3: { - R nodes_[] = { R(0.0694318442029737),R(0.3300094782075718),R(0.6699905217924281),R(0.9305681557970263) }; - R wts_[] = { R(0.173927422568727),R(0.326072577431273),R(0.326072577431273),R(0.173927422568727) }; - nodes.assign(nodes_, nodes_+m+1); - wts.assign(wts_, wts_+m+1); - } break; - case 4: { - R nodes_[] = { R(0.0469100770306681),R(0.2307653449471584),R(0.5000000000000000),R(0.7692346550528415),R(0.9530899229693319) }; - R wts_[] = { R(0.118463442528095),R(0.239314335249683),R(0.284444444444444),R(0.239314335249683),R(0.118463442528094) }; - nodes.assign(nodes_, nodes_+m+1); - wts.assign(wts_, wts_+m+1); - } break; - case 5: { - R nodes_[] = { R(0.0337652428984240),R(0.1693953067668678),R(0.3806904069584015),R(0.6193095930415985),R(0.8306046932331322),R(0.9662347571015761) }; - R wts_[] = { R(0.0856622461895853),R(0.1803807865240693),R(0.2339569672863452),R(0.2339569672863459),R(0.1803807865240693),R(0.0856622461895852) }; - nodes.assign(nodes_, nodes_+m+1); - wts.assign(wts_, wts_+m+1); - } break; - case 6: { - R nodes_[] = { R(0.0254460438286208),R(0.1292344072003028),R(0.2970774243113015),R(0.4999999999999999),R(0.7029225756886985),R(0.8707655927996973),R(0.9745539561713792) }; - R wts_[] = { R(0.0647424830844348),R(0.1398526957446384),R(0.1909150252525594),R(0.2089795918367343),R(0.1909150252525595),R(0.1398526957446383),R(0.0647424830844349) }; - nodes.assign(nodes_, nodes_+m+1); - wts.assign(wts_, wts_+m+1); - } break; - } - - dense_matrix auxS1(S), auxS2(S); - std::vector auxvec(n); - gmm::clear(S); - for (size_type j=0; j <= m; ++j) { - gmm::copy(gmm::scaled(auxS1, nodes[j]), auxS2); - gmm::add(gmm::identity_matrix(), auxS2); - // S += wts[i] * auxS1 * inv(auxS2) - for (size_type i=0; i < n; ++i) { - gmm::copy(gmm::mat_row(auxS1, i), auxvec); - gmm::lower_tri_solve(gmm::transposed(auxS2), auxvec, false); - gmm::add(gmm::scaled(auxvec, wts[j]), gmm::mat_row(S, i)); - } - } - } - gmm::scale(S, scaling); - } - - /** - Matrix logarithm (from GNU/Octave) - */ - template - void logm(const dense_matrix& A, dense_matrix& LOGMA) - { - typedef typename number_traits::magnitude_type R; - size_type n = gmm::mat_nrows(A); - GMM_ASSERT1(n == gmm::mat_ncols(A), - "Matrix logarithm is not defined for non-square matrices"); - dense_matrix S(A), Q(A); - #if defined(GMM_USES_LAPACK) - schur(A, S, Q); // A = Q * S * Q^T - #else - GMM_ASSERT1(false, "Please recompile with lapack and blas librairies " - "to use logm matrix function."); - #endif - - bool convert_to_complex(false); - if (!is_complex(T())) - for (size_type i=0; i < n-1; ++i) - if (gmm::abs(S(i+1,i)) > default_tol(T())) { - convert_to_complex = true; - break; - } - - gmm::resize(LOGMA, n, n); - if (convert_to_complex) { - dense_matrix > cS(n,n), cQ(n,n), auxmat(n,n); - gmm::copy(gmm::real_part(S), gmm::real_part(cS)); - gmm::copy(gmm::real_part(Q), gmm::real_part(cQ)); - block2x2_reduction(cS, cQ, default_tol(R())*R(3)); - for (size_type j=0; j < n-1; ++j) - for (size_type i=j+1; i < n; ++i) - cS(i,j) = T(0); - logm_utri_inplace(cS); - gmm::mult(cQ, cS, auxmat); - gmm::mult(auxmat, gmm::transposed(cQ), cS); - // Remove small complex values which may have entered calculation - gmm::copy(gmm::real_part(cS), LOGMA); -// GMM_ASSERT1(gmm::mat_norm1(gmm::imag_part(cS)) < n*default_tol(T()), -// "Internal error, imag part should be zero"); - } else { - dense_matrix auxmat(n,n); - logm_utri_inplace(S); - gmm::mult(Q, S, auxmat); - gmm::mult(auxmat, gmm::transposed(Q), LOGMA); - } - - } - -} - -#endif - diff --git a/gmm/gmm_dense_qr.h b/gmm/gmm_dense_qr.h deleted file mode 100644 index 9de7dbeb8..000000000 --- a/gmm/gmm_dense_qr.h +++ /dev/null @@ -1,789 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_dense_qr.h - @author Caroline Lecalvez, Caroline.Lecalvez@gmm.insa-tlse.fr, Yves Renard - @date September 12, 2003. - @brief Dense QR factorization. -*/ -#ifndef GMM_DENSE_QR_H -#define GMM_DENSE_QR_H - -#include "gmm_dense_Householder.h" - -namespace gmm { - - - /** - QR factorization using Householder method (complex and real version). - */ - template - void qr_factor(const MAT1 &A_) { - MAT1 &A = const_cast(A_); - typedef typename linalg_traits::value_type value_type; - - size_type m = mat_nrows(A), n = mat_ncols(A); - GMM_ASSERT2(m >= n, "dimensions mismatch"); - - std::vector W(m), V(m); - - for (size_type j = 0; j < n; ++j) { - sub_interval SUBI(j, m-j), SUBJ(j, n-j); - V.resize(m-j); W.resize(n-j); - - for (size_type i = j; i < m; ++i) V[i-j] = A(i, j); - house_vector(V); - - row_house_update(sub_matrix(A, SUBI, SUBJ), V, W); - for (size_type i = j+1; i < m; ++i) A(i, j) = V[i-j]; - } - } - - - // QR comes from QR_factor(QR) where the upper triangular part stands for R - // and the lower part contains the Householder reflectors. - // A <- AQ - template - void apply_house_right(const MAT1 &QR, const MAT2 &A_) { - MAT2 &A = const_cast(A_); - typedef typename linalg_traits::value_type T; - size_type m = mat_nrows(QR), n = mat_ncols(QR); - GMM_ASSERT2(m == mat_ncols(A), "dimensions mismatch"); - if (m == 0) return; - std::vector V(m), W(mat_nrows(A)); - V[0] = T(1); - for (size_type j = 0; j < n; ++j) { - V.resize(m-j); - for (size_type i = j+1; i < m; ++i) V[i-j] = QR(i, j); - col_house_update(sub_matrix(A, sub_interval(0, mat_nrows(A)), - sub_interval(j, m-j)), V, W); - } - } - - // QR comes from QR_factor(QR) where the upper triangular part stands for R - // and the lower part contains the Householder reflectors. - // A <- Q*A - template - void apply_house_left(const MAT1 &QR, const MAT2 &A_) { - MAT2 &A = const_cast(A_); - typedef typename linalg_traits::value_type T; - size_type m = mat_nrows(QR), n = mat_ncols(QR); - GMM_ASSERT2(m == mat_nrows(A), "dimensions mismatch"); - if (m == 0) return; - std::vector V(m), W(mat_ncols(A)); - V[0] = T(1); - for (size_type j = 0; j < n; ++j) { - V.resize(m-j); - for (size_type i = j+1; i < m; ++i) V[i-j] = QR(i, j); - row_house_update(sub_matrix(A, sub_interval(j, m-j), - sub_interval(0, mat_ncols(A))), V, W); - } - } - - /** Compute the QR factorization, where Q is assembled. */ - template - void qr_factor(const MAT1 &A, const MAT2 &QQ, const MAT3 &RR) { - MAT2 &Q = const_cast(QQ); MAT3 &R = const_cast(RR); - typedef typename linalg_traits::value_type value_type; - - size_type m = mat_nrows(A), n = mat_ncols(A); - GMM_ASSERT2(m >= n, "dimensions mismatch"); - gmm::copy(A, Q); - - std::vector W(m); - dense_matrix VV(m, n); - - for (size_type j = 0; j < n; ++j) { - sub_interval SUBI(j, m-j), SUBJ(j, n-j); - - for (size_type i = j; i < m; ++i) VV(i,j) = Q(i, j); - house_vector(sub_vector(mat_col(VV,j), SUBI)); - - row_house_update(sub_matrix(Q, SUBI, SUBJ), - sub_vector(mat_col(VV,j), SUBI), sub_vector(W, SUBJ)); - } - - gmm::copy(sub_matrix(Q, sub_interval(0, n), sub_interval(0, n)), R); - gmm::copy(identity_matrix(), Q); - - for (size_type j = n-1; j != size_type(-1); --j) { - sub_interval SUBI(j, m-j), SUBJ(j, n-j); - row_house_update(sub_matrix(Q, SUBI, SUBJ), - sub_vector(mat_col(VV,j), SUBI), sub_vector(W, SUBJ)); - } - } - - ///@cond DOXY_SHOW_ALL_FUNCTIONS - template - void extract_eig(const MAT &A, VECT &V, Ttol tol, TA, TV) { - size_type n = mat_nrows(A); - if (n == 0) return; - tol *= Ttol(2); - Ttol tol_i = tol * gmm::abs(A(0,0)), tol_cplx = tol_i; - for (size_type i = 0; i < n; ++i) { - if (i < n-1) { - tol_i = (gmm::abs(A(i,i))+gmm::abs(A(i+1,i+1)))*tol; - tol_cplx = std::max(tol_cplx, tol_i); - } - if ((i < n-1) && gmm::abs(A(i+1,i)) >= tol_i) { - TA tr = A(i,i) + A(i+1, i+1); - TA det = A(i,i)*A(i+1, i+1) - A(i,i+1)*A(i+1, i); - TA delta = tr*tr - TA(4) * det; - if (delta < -tol_cplx) { - GMM_WARNING1("A complex eigenvalue has been detected : " - << std::complex(tr/TA(2), gmm::sqrt(-delta)/TA(2))); - V[i] = V[i+1] = tr / TA(2); - } - else { - delta = std::max(TA(0), delta); - V[i ] = TA(tr + gmm::sqrt(delta))/ TA(2); - V[i+1] = TA(tr - gmm::sqrt(delta))/ TA(2); - } - ++i; - } - else - V[i] = TV(A(i,i)); - } - } - - template - void extract_eig(const MAT &A, VECT &V, Ttol tol, TA, std::complex) { - size_type n = mat_nrows(A); - tol *= Ttol(2); - for (size_type i = 0; i < n; ++i) - if ((i == n-1) || - gmm::abs(A(i+1,i)) < (gmm::abs(A(i,i))+gmm::abs(A(i+1,i+1)))*tol) - V[i] = std::complex(A(i,i)); - else { - TA tr = A(i,i) + A(i+1, i+1); - TA det = A(i,i)*A(i+1, i+1) - A(i,i+1)*A(i+1, i); - TA delta = tr*tr - TA(4) * det; - if (delta < TA(0)) { - V[i] = std::complex(tr / TA(2), gmm::sqrt(-delta) / TA(2)); - V[i+1] = std::complex(tr / TA(2), -gmm::sqrt(-delta)/ TA(2)); - } - else { - V[i ] = TA(tr + gmm::sqrt(delta)) / TA(2); - V[i+1] = TA(tr - gmm::sqrt(delta)) / TA(2); - } - ++i; - } - } - - template - void extract_eig(const MAT &A, VECT &V, Ttol tol, std::complex, TV) { - typedef std::complex T; - size_type n = mat_nrows(A); - if (n == 0) return; - tol *= Ttol(2); - Ttol tol_i = tol * gmm::abs(A(0,0)), tol_cplx = tol_i; - for (size_type i = 0; i < n; ++i) { - if (i < n-1) { - tol_i = (gmm::abs(A(i,i))+gmm::abs(A(i+1,i+1)))*tol; - tol_cplx = std::max(tol_cplx, tol_i); - } - if ((i == n-1) || gmm::abs(A(i+1,i)) < tol_i) { - if (gmm::abs(std::imag(A(i,i))) > tol_cplx) - GMM_WARNING1("A complex eigenvalue has been detected : " - << T(A(i,i)) << " : " << gmm::abs(std::imag(A(i,i))) - / gmm::abs(std::real(A(i,i))) << " : " << tol_cplx); - V[i] = std::real(A(i,i)); - } - else { - T tr = A(i,i) + A(i+1, i+1); - T det = A(i,i)*A(i+1, i+1) - A(i,i+1)*A(i+1, i); - T delta = tr*tr - TA(4) * det; - T a1 = (tr + gmm::sqrt(delta)) / TA(2); - T a2 = (tr - gmm::sqrt(delta)) / TA(2); - if (gmm::abs(std::imag(a1)) > tol_cplx) - GMM_WARNING1("A complex eigenvalue has been detected : " << a1); - if (gmm::abs(std::imag(a2)) > tol_cplx) - GMM_WARNING1("A complex eigenvalue has been detected : " << a2); - - V[i] = std::real(a1); V[i+1] = std::real(a2); - ++i; - } - } - } - - template - void extract_eig(const MAT &A, VECT &V, Ttol tol, - std::complex, std::complex) { - size_type n = mat_nrows(A); - tol *= Ttol(2); - for (size_type i = 0; i < n; ++i) - if ((i == n-1) || - gmm::abs(A(i+1,i)) < (gmm::abs(A(i,i))+gmm::abs(A(i+1,i+1)))*tol) - V[i] = std::complex(A(i,i)); - else { - std::complex tr = A(i,i) + A(i+1, i+1); - std::complex det = A(i,i)*A(i+1, i+1) - A(i,i+1)*A(i+1, i); - std::complex delta = tr*tr - TA(4) * det; - V[i] = (tr + gmm::sqrt(delta)) / TA(2); - V[i+1] = (tr - gmm::sqrt(delta)) / TA(2); - ++i; - } - } - - ///@endcond - /** - Compute eigenvalue vector. - */ - template inline - void extract_eig(const MAT &A, const VECT &V, Ttol tol) { - extract_eig(A, const_cast(V), tol, - typename linalg_traits::value_type(), - typename linalg_traits::value_type()); - } - - /* ********************************************************************* */ - /* Stop criterion for QR algorithms */ - /* ********************************************************************* */ - - template - void qr_stop_criterion(MAT &A, size_type &p, size_type &q, Ttol tol) { - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - R rmin = default_min(R()) * R(2); - size_type n = mat_nrows(A); - if (n <= 2) { q = n; p = 0; } - else { - for (size_type i = 1; i < n-q; ++i) - if (gmm::abs(A(i,i-1)) < (gmm::abs(A(i,i))+ gmm::abs(A(i-1,i-1)))*tol - || gmm::abs(A(i,i-1)) < rmin) - A(i,i-1) = T(0); - - while ((q < n-1 && A(n-1-q, n-2-q) == T(0)) || - (q < n-2 && A(n-2-q, n-3-q) == T(0))) ++q; - if (q >= n-2) q = n; - p = n-q; if (p) --p; if (p) --p; - while (p > 0 && A(p,p-1) != T(0)) --p; - } - } - - template inline - void symmetric_qr_stop_criterion(const MAT &AA, size_type &p, size_type &q, - Ttol tol) { - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - R rmin = default_min(R()) * R(2); - MAT& A = const_cast(AA); - size_type n = mat_nrows(A); - if (n <= 1) { q = n; p = 0; } - else { - for (size_type i = 1; i < n-q; ++i) - if (gmm::abs(A(i,i-1)) < (gmm::abs(A(i,i))+ gmm::abs(A(i-1,i-1)))*tol - || gmm::abs(A(i,i-1)) < rmin) - A(i,i-1) = T(0); - - while (q < n-1 && A(n-1-q, n-2-q) == T(0)) ++q; - if (q >= n-1) q = n; - p = n-q; if (p) --p; if (p) --p; - while (p > 0 && A(p,p-1) != T(0)) --p; - } - } - - template inline - void symmetric_qr_stop_criterion(const VECT1 &diag, const VECT2 &sdiag_, - size_type &p, size_type &q, Ttol tol) { - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - R rmin = default_min(R()) * R(2); - VECT2 &sdiag = const_cast(sdiag_); - size_type n = vect_size(diag); - if (n <= 1) { q = n; p = 0; return; } - for (size_type i = 1; i < n-q; ++i) - if (gmm::abs(sdiag[i-1]) < (gmm::abs(diag[i])+ gmm::abs(diag[i-1]))*tol - || gmm::abs(sdiag[i-1]) < rmin) - sdiag[i-1] = T(0); - while (q < n-1 && sdiag[n-2-q] == T(0)) ++q; - if (q >= n-1) q = n; - p = n-q; if (p) --p; if (p) --p; - while (p > 0 && sdiag[p-1] != T(0)) --p; - } - - /* ********************************************************************* */ - /* 2x2 blocks reduction for Schur vectors */ - /* ********************************************************************* */ - - template - void block2x2_reduction(MATH &H, MATQ &Q, Ttol tol) { - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - size_type n = mat_nrows(H), nq = mat_nrows(Q); - if (n < 2) return; - sub_interval SUBQ(0, nq), SUBL(0, 2); - std::vector v(2), w(std::max(n, nq)); v[0] = T(1); - tol *= Ttol(2); - Ttol tol_i = tol * gmm::abs(H(0,0)), tol_cplx = tol_i; - for (size_type i = 0; i < n-1; ++i) { - tol_i = (gmm::abs(H(i,i))+gmm::abs(H(i+1,i+1)))*tol; - tol_cplx = std::max(tol_cplx, tol_i); - - if (gmm::abs(H(i+1,i)) > tol_i) { // 2x2 block detected - T tr = (H(i+1, i+1) - H(i,i)) / T(2); - T delta = tr*tr + H(i,i+1)*H(i+1, i); - - if (is_complex(T()) || gmm::real(delta) >= R(0)) { - sub_interval SUBI(i, 2); - T theta = (tr - gmm::sqrt(delta)) / H(i+1,i); - R a = gmm::abs(theta); - v[1] = (a == R(0)) ? T(-1) - : gmm::conj(theta) * (R(1) - gmm::sqrt(a*a + R(1)) / a); - row_house_update(sub_matrix(H, SUBI), v, sub_vector(w, SUBL)); - col_house_update(sub_matrix(H, SUBI), v, sub_vector(w, SUBL)); - col_house_update(sub_matrix(Q, SUBQ, SUBI), v, sub_vector(w, SUBQ)); - } - ++i; - } - } - } - - /* ********************************************************************* */ - /* Basic qr algorithm. */ - /* ********************************************************************* */ - - #define tol_type_for_qr typename number_traits::value_type>::magnitude_type - #define default_tol_for_qr \ - (gmm::default_tol(tol_type_for_qr()) * tol_type_for_qr(3)) - - // QR method for real or complex square matrices based on QR factorisation. - // eigval has to be a complex vector if A has complex eigeinvalues. - // Very slow method. Use implicit_qr_method instead. - template - void rudimentary_qr_algorithm(const MAT1 &A, const VECT &eigval_, - const MAT2 &eigvect_, - tol_type_for_qr tol = default_tol_for_qr, - bool compvect = true) { - VECT &eigval = const_cast(eigval_); - MAT2 &eigvect = const_cast(eigvect_); - - typedef typename linalg_traits::value_type value_type; - - size_type n = mat_nrows(A), p, q = 0, ite = 0; - dense_matrix Q(n, n), R(n,n), A1(n,n); - gmm::copy(A, A1); - - Hessenberg_reduction(A1, eigvect, compvect); - qr_stop_criterion(A1, p, q, tol); - - while (q < n) { - qr_factor(A1, Q, R); - gmm::mult(R, Q, A1); - if (compvect) { gmm::mult(eigvect, Q, R); gmm::copy(R, eigvect); } - - qr_stop_criterion(A1, p, q, tol); - ++ite; - GMM_ASSERT1(ite < n*1000, "QR algorithm failed"); - } - if (compvect) block2x2_reduction(A1, Q, tol); - extract_eig(A1, eigval, tol); - } - - template - void rudimentary_qr_algorithm(const MAT1 &a, VECT &eigval, - tol_type_for_qr tol = default_tol_for_qr) { - dense_matrix::value_type> m(0,0); - rudimentary_qr_algorithm(a, eigval, m, tol, false); - } - - /* ********************************************************************* */ - /* Francis QR step. */ - /* ********************************************************************* */ - - template - void Francis_qr_step(const MAT1& HH, const MAT2 &QQ, bool compute_Q) { - MAT1& H = const_cast(HH); MAT2& Q = const_cast(QQ); - typedef typename linalg_traits::value_type value_type; - size_type n = mat_nrows(H), nq = mat_nrows(Q); - - std::vector v(3), w(std::max(n, nq)); - - value_type s = H(n-2, n-2) + H(n-1, n-1); - value_type t = H(n-2, n-2) * H(n-1, n-1) - H(n-2, n-1) * H(n-1, n-2); - value_type x = H(0, 0) * H(0, 0) + H(0,1) * H(1, 0) - s * H(0,0) + t; - value_type y = H(1, 0) * (H(0,0) + H(1,1) - s); - value_type z = H(1, 0) * H(2, 1); - - sub_interval SUBQ(0, nq); - - for (size_type k = 0; k < n - 2; ++k) { - v[0] = x; v[1] = y; v[2] = z; - house_vector(v); - size_type r = std::min(k+4, n), q = (k==0) ? 0 : k-1; - sub_interval SUBI(k, 3), SUBJ(0, r), SUBK(q, n-q); - - row_house_update(sub_matrix(H, SUBI, SUBK), v, sub_vector(w, SUBK)); - col_house_update(sub_matrix(H, SUBJ, SUBI), v, sub_vector(w, SUBJ)); - - if (compute_Q) - col_house_update(sub_matrix(Q, SUBQ, SUBI), v, sub_vector(w, SUBQ)); - - x = H(k+1, k); y = H(k+2, k); - if (k < n-3) z = H(k+3, k); - } - sub_interval SUBI(n-2,2), SUBJ(0, n), SUBK(n-3,3), SUBL(0, 3); - v.resize(2); - v[0] = x; v[1] = y; - house_vector(v); - row_house_update(sub_matrix(H, SUBI, SUBK), v, sub_vector(w, SUBL)); - col_house_update(sub_matrix(H, SUBJ, SUBI), v, sub_vector(w, SUBJ)); - if (compute_Q) - col_house_update(sub_matrix(Q, SUBQ, SUBI), v, sub_vector(w, SUBQ)); - } - - /* ********************************************************************* */ - /* Wilkinson Double shift QR step (from Lapack). */ - /* ********************************************************************* */ - - template - void Wilkinson_double_shift_qr_step(const MAT1& HH, const MAT2 &QQ, - Ttol tol, bool exc, bool compute_Q) { - MAT1& H = const_cast(HH); MAT2& Q = const_cast(QQ); - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - size_type n = mat_nrows(H), nq = mat_nrows(Q), m; - std::vector v(3), w(std::max(n, nq)); - const R dat1(0.75), dat2(-0.4375); - T h33, h44, h43h34, v1(0), v2(0), v3(0); - - if (exc) { /* Exceptional shift. */ - R s = gmm::abs(H(n-1, n-2)) + gmm::abs(H(n-2, n-3)); - h33 = h44 = dat1 * s; - h43h34 = dat2*s*s; - } - else { /* Wilkinson double shift. */ - h44 = H(n-1,n-1); h33 = H(n-2, n-2); - h43h34 = H(n-1, n-2) * H(n-2, n-1); - } - - /* Look for two consecutive small subdiagonal elements. */ - /* Determine the effect of starting the double-shift QR iteration at */ - /* row m, and see if this would make H(m-1, m-2) negligible. */ - for (m = n-2; m != 0; --m) { - T h11 = H(m-1, m-1), h22 = H(m, m); - T h21 = H(m, m-1), h12 = H(m-1, m); - T h44s = h44 - h11, h33s = h33 - h11; - v1 = (h33s*h44s-h43h34) / h21 + h12; - v2 = h22 - h11 - h33s - h44s; - v3 = H(m+1, m); - R s = gmm::abs(v1) + gmm::abs(v2) + gmm::abs(v3); - v1 /= s; v2 /= s; v3 /= s; - if (m == 1) break; - T h00 = H(m-2, m-2); - T h10 = H(m-1, m-2); - R tst1 = gmm::abs(v1)*(gmm::abs(h00)+gmm::abs(h11)+gmm::abs(h22)); - if (gmm::abs(h10)*(gmm::abs(v2)+gmm::abs(v3)) <= tol * tst1) break; - } - - /* Double shift QR step. */ - sub_interval SUBQ(0, nq); - for (size_type k = (m == 0) ? 0 : m-1; k < n-2; ++k) { - v[0] = v1; v[1] = v2; v[2] = v3; - house_vector(v); - size_type r = std::min(k+4, n), q = (k==0) ? 0 : k-1; - sub_interval SUBI(k, 3), SUBJ(0, r), SUBK(q, n-q); - - row_house_update(sub_matrix(H, SUBI, SUBK), v, sub_vector(w, SUBK)); - col_house_update(sub_matrix(H, SUBJ, SUBI), v, sub_vector(w, SUBJ)); - if (k > m-1) { H(k+1, k-1) = T(0); if (k < n-3) H(k+2, k-1) = T(0); } - - if (compute_Q) - col_house_update(sub_matrix(Q, SUBQ, SUBI), v, sub_vector(w, SUBQ)); - - v1 = H(k+1, k); v2 = H(k+2, k); - if (k < n-3) v3 = H(k+3, k); - } - sub_interval SUBI(n-2,2), SUBJ(0, n), SUBK(n-3,3), SUBL(0, 3); - v.resize(2); v[0] = v1; v[1] = v2; - house_vector(v); - row_house_update(sub_matrix(H, SUBI, SUBK), v, sub_vector(w, SUBL)); - col_house_update(sub_matrix(H, SUBJ, SUBI), v, sub_vector(w, SUBJ)); - if (compute_Q) - col_house_update(sub_matrix(Q, SUBQ, SUBI), v, sub_vector(w, SUBQ)); - } - - /* ********************************************************************* */ - /* Implicit QR algorithm. */ - /* ********************************************************************* */ - - // QR method for real or complex square matrices based on an - // implicit QR factorisation. eigval has to be a complex vector - // if A has complex eigenvalues. Complexity about 10n^3, 25n^3 if - // eigenvectors are computed - template - void implicit_qr_algorithm(const MAT1 &A, const VECT &eigval_, - const MAT2 &Q_, - tol_type_for_qr tol = default_tol_for_qr, - bool compvect = true) { - VECT &eigval = const_cast(eigval_); - MAT2 &Q = const_cast(Q_); - typedef typename linalg_traits::value_type value_type; - - size_type n(mat_nrows(A)), q(0), q_old, p(0), ite(0), its(0); - dense_matrix H(n,n); - sub_interval SUBK(0,0); - - gmm::copy(A, H); - Hessenberg_reduction(H, Q, compvect); - qr_stop_criterion(H, p, q, tol); - - while (q < n) { - sub_interval SUBI(p, n-p-q), SUBJ(0, mat_ncols(Q)); - if (compvect) SUBK = SUBI; -// Francis_qr_step(sub_matrix(H, SUBI), -// sub_matrix(Q, SUBJ, SUBK), compvect); - Wilkinson_double_shift_qr_step(sub_matrix(H, SUBI), - sub_matrix(Q, SUBJ, SUBK), - tol, (its == 10 || its == 20), compvect); - q_old = q; - qr_stop_criterion(H, p, q, tol*2); - if (q != q_old) its = 0; - ++its; ++ite; - GMM_ASSERT1(ite < n*100, "QR algorithm failed"); - } - if (compvect) block2x2_reduction(H, Q, tol); - extract_eig(H, eigval, tol); - } - - - template - void implicit_qr_algorithm(const MAT1 &a, VECT &eigval, - tol_type_for_qr tol = default_tol_for_qr) { - dense_matrix::value_type> m(1,1); - implicit_qr_algorithm(a, eigval, m, tol, false); - } - - /* ********************************************************************* */ - /* Implicit symmetric QR step with Wilkinson Shift. */ - /* ********************************************************************* */ - - template - void symmetric_Wilkinson_qr_step(const MAT1& MM, const MAT2 &ZZ, - bool compute_z) { - MAT1& M = const_cast(MM); MAT2& Z = const_cast(ZZ); - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - size_type n = mat_nrows(M); - - for (size_type i = 0; i < n; ++i) { - M(i, i) = T(gmm::real(M(i, i))); - if (i > 0) { - T a = (M(i, i-1) + gmm::conj(M(i-1, i)))/R(2); - M(i, i-1) = a; M(i-1, i) = gmm::conj(a); - } - } - - R d = gmm::real(M(n-2, n-2) - M(n-1, n-1)) / R(2); - R e = gmm::abs_sqr(M(n-1, n-2)); - R nu = d + gmm::sgn(d)*gmm::sqrt(d*d+e); - if (nu == R(0)) { M(n-1, n-2) = T(0); return; } - R mu = gmm::real(M(n-1, n-1)) - e / nu; - T x = M(0,0) - T(mu), z = M(1, 0), c, s; - - for (size_type k = 1; k < n; ++k) { - Givens_rotation(x, z, c, s); - - if (k > 1) Apply_Givens_rotation_left(M(k-1,k-2), M(k,k-2), c, s); - Apply_Givens_rotation_left(M(k-1,k-1), M(k,k-1), c, s); - Apply_Givens_rotation_left(M(k-1,k ), M(k,k ), c, s); - if (k < n-1) Apply_Givens_rotation_left(M(k-1,k+1), M(k,k+1), c, s); - if (k > 1) Apply_Givens_rotation_right(M(k-2,k-1), M(k-2,k), c, s); - Apply_Givens_rotation_right(M(k-1,k-1), M(k-1,k), c, s); - Apply_Givens_rotation_right(M(k ,k-1), M(k,k) , c, s); - if (k < n-1) Apply_Givens_rotation_right(M(k+1,k-1), M(k+1,k), c, s); - - if (compute_z) col_rot(Z, c, s, k-1, k); - if (k < n-1) { x = M(k, k-1); z = M(k+1, k-1); } - } - - } - - template - void symmetric_Wilkinson_qr_step(const VECT1& diag_, const VECT2& sdiag_, - const MAT &ZZ, bool compute_z) { - VECT1& diag = const_cast(diag_); - VECT2& sdiag = const_cast(sdiag_); - MAT& Z = const_cast(ZZ); - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - size_type n = vect_size(diag); - R d = (diag[n-2] - diag[n-1]) / R(2); - R e = gmm::abs_sqr(sdiag[n-2]); - R nu = d + gmm::sgn(d)*gmm::sqrt(d*d+e); - if (nu == R(0)) { sdiag[n-2] = T(0); return; } - R mu = diag[n-1] - e / nu; - T x = diag[0] - T(mu), z = sdiag[0], c, s; - - T a01(0), a02(0); - T a10(0), a11(diag[0]), a12(gmm::conj(sdiag[0])), a13(0); - T a20(0), a21(sdiag[0]), a22(diag[1]), a23(gmm::conj(sdiag[1])); - T a31(0), a32(sdiag[1]); - - for (size_type k = 1; k < n; ++k) { - Givens_rotation(x, z, c, s); - - if (k > 1) Apply_Givens_rotation_left(a10, a20, c, s); - Apply_Givens_rotation_left(a11, a21, c, s); - Apply_Givens_rotation_left(a12, a22, c, s); - if (k < n-1) Apply_Givens_rotation_left(a13, a23, c, s); - - if (k > 1) Apply_Givens_rotation_right(a01, a02, c, s); - Apply_Givens_rotation_right(a11, a12, c, s); - Apply_Givens_rotation_right(a21, a22, c, s); - if (k < n-1) Apply_Givens_rotation_right(a31, a32, c, s); - - if (compute_z) col_rot(Z, c, s, k-1, k); - - diag[k-1] = gmm::real(a11); - diag[k] = gmm::real(a22); - if (k > 1) sdiag[k-2] = (gmm::conj(a01) + a10) / R(2); - sdiag[k-1] = (gmm::conj(a12) + a21) / R(2); - - x = sdiag[k-1]; z = (gmm::conj(a13) + a31) / R(2); - - a01 = a12; a02 = a13; - a10 = a21; a11 = a22; a12 = a23; a13 = T(0); - a20 = a31; a21 = a32; a31 = T(0); - - if (k < n-1) { - sdiag[k] = (gmm::conj(a23) + a32) / R(2); - a22 = T(diag[k+1]); a32 = sdiag[k+1]; a23 = gmm::conj(a32); - } - } - } - - /* ********************************************************************* */ - /* Implicit QR algorithm for symmetric or hermitian matrices. */ - /* ********************************************************************* */ - - // implicit QR method for real square symmetric matrices or complex - // hermitian matrices. - // eigval has to be a complex vector if A has complex eigeinvalues. - // complexity about 4n^3/3, 9n^3 if eigenvectors are computed - template - void symmetric_qr_algorithm_old(const MAT1 &A, const VECT &eigval_, - const MAT2 &eigvect_, - tol_type_for_qr tol = default_tol_for_qr, - bool compvect = true) { - VECT &eigval = const_cast(eigval_); - MAT2 &eigvect = const_cast(eigvect_); - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - if (compvect) gmm::copy(identity_matrix(), eigvect); - size_type n = mat_nrows(A), q = 0, p, ite = 0; - dense_matrix Tri(n, n); - gmm::copy(A, Tri); - - Householder_tridiagonalization(Tri, eigvect, compvect); - - symmetric_qr_stop_criterion(Tri, p, q, tol); - - while (q < n) { - - sub_interval SUBI(p, n-p-q), SUBJ(0, mat_ncols(eigvect)), SUBK(p, n-p-q); - if (!compvect) SUBK = sub_interval(0,0); - symmetric_Wilkinson_qr_step(sub_matrix(Tri, SUBI), - sub_matrix(eigvect, SUBJ, SUBK), compvect); - - symmetric_qr_stop_criterion(Tri, p, q, tol*R(2)); - ++ite; - GMM_ASSERT1(ite < n*100, "QR algorithm failed. Probably, your matrix" - " is not real symmetric or complex hermitian"); - } - - extract_eig(Tri, eigval, tol); - } - - template - void symmetric_qr_algorithm(const MAT1 &A, const VECT &eigval_, - const MAT2 &eigvect_, - tol_type_for_qr tol = default_tol_for_qr, - bool compvect = true) { - VECT &eigval = const_cast(eigval_); - MAT2 &eigvect = const_cast(eigvect_); - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - size_type n = mat_nrows(A), q = 0, p, ite = 0; - if (compvect) gmm::copy(identity_matrix(), eigvect); - if (n == 0) return; - if (n == 1) { eigval[0]=gmm::real(A(0,0)); return; } - dense_matrix Tri(n, n); - gmm::copy(A, Tri); - - Householder_tridiagonalization(Tri, eigvect, compvect); - - std::vector diag(n); - std::vector sdiag(n); - for (size_type i = 0; i < n; ++i) - { diag[i] = gmm::real(Tri(i, i)); if (i+1 < n) sdiag[i] = Tri(i+1, i); } - - symmetric_qr_stop_criterion(diag, sdiag, p, q, tol); - - while (q < n) { - sub_interval SUBI(p, n-p-q), SUBJ(0, mat_ncols(eigvect)), SUBK(p, n-p-q); - if (!compvect) SUBK = sub_interval(0,0); - - symmetric_Wilkinson_qr_step(sub_vector(diag, SUBI), - sub_vector(sdiag, SUBI), - sub_matrix(eigvect, SUBJ, SUBK), compvect); - - symmetric_qr_stop_criterion(diag, sdiag, p, q, tol*R(3)); - ++ite; - GMM_ASSERT1(ite < n*100, "QR algorithm failed."); - } - - gmm::copy(diag, eigval); - } - - - template - void symmetric_qr_algorithm(const MAT1 &a, VECT &eigval, - tol_type_for_qr tol = default_tol_for_qr) { - dense_matrix::value_type> m(0,0); - symmetric_qr_algorithm(a, eigval, m, tol, false); - } - - -} - -#endif - diff --git a/gmm/gmm_dense_sylvester.h b/gmm/gmm_dense_sylvester.h deleted file mode 100644 index 3b184ccbf..000000000 --- a/gmm/gmm_dense_sylvester.h +++ /dev/null @@ -1,174 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/** @file gmm_dense_sylvester.h - @author Yves Renard - @date June 5, 2003. - @brief Sylvester equation solver. -*/ -#ifndef GMM_DENSE_SYLVESTER_H -#define GMM_DENSE_SYLVESTER_H - -#include "gmm_kernel.h" - -namespace gmm { - - /* ********************************************************************* */ - /* Kronecker system matrix. */ - /* ********************************************************************* */ - template - void kron(const MAT1 &m1, const MAT2 &m2, const MAT3 &m3_, - bool init = true) { - MAT3 &m3 = const_cast(m3_); - size_type m = mat_nrows(m1), n = mat_ncols(m1); - size_type l = mat_nrows(m2), k = mat_ncols(m2); - - GMM_ASSERT2(mat_nrows(m3) == m*l && mat_ncols(m3) == n*k, - "dimensions mismatch"); - - for (size_type i = 0; i < m; ++i) - for (size_type j = 0; j < m; ++j) - if (init) - gmm::copy(gmm::scaled(m2, m1(i,j)), - gmm::sub_matrix(m3, sub_interval(l*i, l), - sub_interval(k*j, k))); - else - gmm::add(gmm::scaled(m2, m1(i,j)), - gmm::sub_matrix(m3, sub_interval(l*i, l), - sub_interval(k*j, k))); - } - - - /* ********************************************************************* */ - /* Copy a matrix into a vector. */ - /* ********************************************************************* */ - - template - colmatrix_to_vector(const MAT &A, VECT &v, col_major) { - size_type m = mat_nrows(A), n = mat_ncols(A); - GMM_ASSERT2(m*n == vect_size(v), "dimensions mismatch"); - for (size_type i = 0; i < n; ++i) - gmm::copy(mat_col(A, i), sub_vector(v, sub_interval(i*m, m))); - } - - template - colmatrix_to_vector(const MAT &A, VECT &v, row_and_col) - { colmatrix_to_vector(A, v, col_major()); } - - template - colmatrix_to_vector(const MAT &A, VECT &v, col_and_row) - { colmatrix_to_vector(A, v, col_major()); } - - template - colmatrix_to_vector(const MAT &A, VECT &v, row_major) { - size_type m = mat_nrows(mat), n = mat_ncols(A); - GMM_ASSERT2(m*n == vect_size(v), "dimensions mismatch"); - for (size_type i = 0; i < m; ++i) - gmm::copy(mat_row(A, i), sub_vector(v, sub_slice(i, n, m))); - } - - template inline - colmatrix_to_vector(const MAT &A, const VECT &v_) { - VECT &v = const_cast(v_); - colmatrix_to_vector(A, v, typename linalg_traits::sub_orientation()); - } - - - /* ********************************************************************* */ - /* Copy a vector into a matrix. */ - /* ********************************************************************* */ - - template - vector_to_colmatrix(const VECT &v, MAT &A, col_major) { - size_type m = mat_nrows(A), n = mat_ncols(A); - GMM_ASSERT2(m*n == vect_size(v), "dimensions mismatch"); - for (size_type i = 0; i < n; ++i) - gmm::copy(sub_vector(v, sub_interval(i*m, m)), mat_col(A, i)); - } - - template - vector_to_colmatrix(const VECT &v, MAT &A, row_and_col) - { vector_to_colmatrix(v, A, col_major()); } - - template - vector_to_colmatrix(const VECT &v, MAT &A, col_and_row) - { vector_to_colmatrix(v, A, col_major()); } - - template - vector_to_colmatrix(const VECT &v, MAT &A, row_major) { - size_type m = mat_nrows(mat), n = mat_ncols(A); - GMM_ASSERT2(m*n == vect_size(v), "dimensions mismatch"); - for (size_type i = 0; i < m; ++i) - gmm::copy(sub_vector(v, sub_slice(i, n, m)), mat_row(A, i)); - } - - template inline - vector_to_colmatrix(const VECT &v, const MAT &A_) { - MAT &A = const_cast(A_); - vector_to_colmatrix(v, A, typename linalg_traits::sub_orientation()); - } - - /* ********************************************************************* */ - /* Solve sylvester equation. */ - /* ********************************************************************* */ - - // very prohibitive solver, to be replaced ... - template - void sylvester(const MAT1 &m1, const MAT2 &m2, const MAT3 &m3, - const MAT4 &m4_) { - typedef typename linalg_traits::value_type T; - - MAT3 &m4 = const_cast(m4_); - size_type m = mat_nrows(m1), n = mat_ncols(m1); - size_type l = mat_nrows(m2), k = mat_ncols(m2); - - GMM_ASSERT2(m == n && l == k && m == mat_nrows(m3) && - l == mat_ncols(m3) && m == mat_nrows(m4) && l == mat_ncols(m4), - "dimensions mismatch"); - - gmm::dense_matrix akronb(m*l, m*l); - gmm::dense_matrix idm(m, m), idl(l,l); - gmm::copy(identity_matrix(), idm); - gmm::copy(identity_matrix(), idl); - std::vector x(m*l), c(m*l); - - kron(idl, m1, akronb); - kron(gmm::transposed(m2), idm, akronb, false); - - colmatrix_to_vector(m3, c); - lu_solve(akronb, c, x); - vector_to_colmatrix(x, m4); - - } -} - -#endif - diff --git a/gmm/gmm_domain_decomp.h b/gmm/gmm_domain_decomp.h deleted file mode 100644 index 89c1841cf..000000000 --- a/gmm/gmm_domain_decomp.h +++ /dev/null @@ -1,165 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2004-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/** @file gmm_domain_decomp.h - @author Yves Renard - @date May 21, 2004. - @brief Domain decomposition. -*/ -#ifndef GMM_DOMAIN_DECOMP_H__ -#define GMM_DOMAIN_DECOMP_H__ - -#include "gmm_kernel.h" -#include - - -namespace gmm { - - /** This function separates into small boxes of size msize with a ratio - * of overlap (in [0,1[) a set of points. The result is given into a - * vector of sparse matrices vB. - */ - template - void rudimentary_regular_decomposition(std::vector pts, - double msize, - double overlap, - std::vector &vB) { - typedef typename linalg_traits::value_type value_type; - typedef abstract_null_type void_type; - typedef std::map map_type; - - size_type nbpts = pts.size(); - if (!nbpts || pts[0].size() == 0) { vB.resize(0); return; } - int dim = int(pts[0].size()); - - // computation of the global box and the number of sub-domains - Point pmin = pts[0], pmax = pts[0]; - for (size_type i = 1; i < nbpts; ++i) - for (int k = 0; k < dim; ++k) { - pmin[k] = std::min(pmin[k], pts[i][k]); - pmax[k] = std::max(pmax[k], pts[i][k]); - } - - std::vector nbsub(dim), mult(dim); - std::vector pts1(dim), pts2(dim); - size_type nbtotsub = 1; - for (int k = 0; k < dim; ++k) { - nbsub[k] = size_type((pmax[k] - pmin[k]) / msize)+1; - mult[k] = nbtotsub; nbtotsub *= nbsub[k]; - } - - std::vector subs(nbtotsub); - // points ventilation - std::vector ns(dim), na(dim), nu(dim); - for (size_type i = 0; i < nbpts; ++i) { - for (int k = 0; k < dim; ++k) { - double a = (pts[i][k] - pmin[k]) / msize; - ns[k] = size_type(a) - 1; na[k] = 0; - pts1[k] = int(a + overlap); pts2[k] = int(ceil(a-1.0-overlap)); - } - size_type sum = 0; - do { - bool ok = 1; - for (int k = 0; k < dim; ++k) - if ((ns[k] >= nbsub[k]) || (pts1[k] < int(ns[k])) - || (pts2[k] > int(ns[k]))) { ok = false; break; } - if (ok) { - size_type ind = ns[0]; - for (int k=1; k < dim; ++k) ind += ns[k]*mult[k]; - subs[ind][i] = void_type(); - } - for (int k = 0; k < dim; ++k) { - if (na[k] < 2) { na[k]++; ns[k]++; ++sum; break; } - na[k] = 0; ns[k] -= 2; sum -= 2; - } - } while (sum); - } - // delete too small domains. - size_type nbmaxinsub = 0; - for (size_type i = 0; i < nbtotsub; ++i) - nbmaxinsub = std::max(nbmaxinsub, subs[i].size()); - - std::fill(ns.begin(), ns.end(), size_type(0)); - for (size_type i = 0; i < nbtotsub; ++i) { - if (subs[i].size() > 0 && subs[i].size() < nbmaxinsub / 10) { - - for (int k = 0; k < dim; ++k) nu[k] = ns[k]; - size_type nbmax = 0, imax = 0; - - for (int l = 0; l < dim; ++l) { - nu[l]--; - for (int m = 0; m < 2; ++m, nu[l]+=2) { - bool ok = true; - for (int k = 0; k < dim && ok; ++k) - if (nu[k] >= nbsub[k]) ok = false; - if (ok) { - size_type ind = ns[0]; - for (int k=1; k < dim; ++k) ind += ns[k]*mult[k]; - if (subs[ind].size() > nbmax) - { nbmax = subs[ind].size(); imax = ind; } - } - } - nu[l]--; - } - - if (nbmax > subs[i].size()) { - for (map_type::iterator it=subs[i].begin(); it!=subs[i].end(); ++it) - subs[imax][it->first] = void_type(); - subs[i].clear(); - } - } - for (int k = 0; k < dim; ++k) - { ns[k]++; if (ns[k] < nbsub[k]) break; ns[k] = 0; } - } - - // delete empty domains. - size_type effnb = 0; - for (size_type i = 0; i < nbtotsub; ++i) { - if (subs[i].size() > 0) - { if (i != effnb) std::swap(subs[i], subs[effnb]); ++effnb; } - } - - // build matrices - subs.resize(effnb); - vB.resize(effnb); - for (size_type i = 0; i < effnb; ++i) { - clear(vB[i]); resize(vB[i], nbpts, subs[i].size()); - size_type j = 0; - for (map_type::iterator it=subs[i].begin(); it!=subs[i].end(); ++it, ++j) - vB[i](it->first, j) = value_type(1); - } - } - - -} - - -#endif diff --git a/gmm/gmm_except.h b/gmm/gmm_except.h deleted file mode 100644 index f19e87f3f..000000000 --- a/gmm/gmm_except.h +++ /dev/null @@ -1,406 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/** @file gmm_except.h - @author Yves Renard - @author Julien Pommier - @date September 01, 2002. - @brief Definition of basic exceptions. -*/ - -#ifndef GMM_EXCEPT_H__ -#define GMM_EXCEPT_H__ - -#include -#include "gmm_std.h" -#include "gmm_feedback_management.h" - - -//provides external implementation of gmm_exception and logging. - -namespace gmm { - -/* *********************************************************************** */ -/* GetFEM++ generic errors. */ -/* *********************************************************************** */ - - // std logic_error with error level information - class gmm_error: public std::logic_error { - public: - gmm_error(const std::string& what_arg, int errorLevel = 1): - std::logic_error (what_arg), errorLevel_(errorLevel) {} - int errLevel() {return errorLevel_;} - - private: - int errorLevel_; - }; - -#ifdef GETFEM_HAVE_PRETTY_FUNCTION -# define GMM_PRETTY_FUNCTION __PRETTY_FUNCTION__ -#elif _MSC_VER -# define GMM_PRETTY_FUNCTION __FUNCTION__ -#else -# define GMM_PRETTY_FUNCTION "" -#endif - - - // Errors : GMM_THROW should not be used on its own. - // GMM_ASSERT1 : Non-maskable errors. Typically for in/ouput and - // when the test do not significantly reduces the performance. - // GMM_ASSERT2 : All tests which are potentially performance - // consuming. Not hidden by default. Hidden when NDEBUG is - // defined. - // GMM_ASSERT3 : For internal checks. Hidden by default. Active - // only when DEBUG_MODE is defined. - // __EXCEPTIONS is defined by gcc, _CPPUNWIND is defined by visual c++ -#if defined(__EXCEPTIONS) || defined(_CPPUNWIND) - inline void short_error_throw(const char *file, int line, const char *func, - const char *errormsg) { - std::stringstream msg__; - msg__ << "Error in " << file << ", line " << line << " " << func - << ": \n" << errormsg << std::ends; - throw gmm::gmm_error(msg__.str()); - } -# define GMM_THROW_(type, errormsg) { \ - std::stringstream msg__; \ - msg__ << "Error in " << __FILE__ << ", line " \ - << __LINE__ << " " << GMM_PRETTY_FUNCTION << ": \n" \ - << errormsg << std::ends; \ - throw (type)(msg__.str()); \ - } - -# define GMM_THROW_AT_LEVEL(errormsg, level) \ - { \ - std::stringstream msg; \ - msg << "Error in " << __FILE__ << ", line " \ - << __LINE__ << " " << GMM_PRETTY_FUNCTION << ": \n" \ - << errormsg << std::ends; \ - throw gmm::gmm_error(msg.str(), level); \ - } - -#else -#ifndef _MSC_VER -# define abort_no_return() ::abort() -#else -// apparently ::abort() on windows is not declared with __declspec(noreturn) so the compiler spits a lot of warnings when abort is used. -# define abort_no_return() { assert("GMM ABORT"==0); throw "GMM ABORT"; } -#endif - - inline void short_error_throw(const char *file, int line, const char *func, - const char *errormsg) { - std::stringstream msg__; - msg__ << "Error in " << file << ", line " << line << " " << func - << ": \n" << errormsg << std::ends; - std::cerr << msg__.str() << std::endl; - abort_no_return(); - } - -# define GMM_THROW_(type, errormsg) { \ - std::stringstream msg__; \ - msg__ << "Error in " << __FILE__ << ", line " \ - << __LINE__ << " " << GMM_PRETTY_FUNCTION << ": \n" \ - << errormsg; \ - std::cerr << msg__.str() << std::endl; \ - abort_no_return(); \ - } - -# define GMM_THROW_AT_LEVEL(errormsg, level) \ - { \ - std::stringstream msg__; \ - msg__ << "Error in " << __FILE__ << ", line " \ - << __LINE__ << " " << GMM_PRETTY_FUNCTION << ": \n" \ - << errormsg << " at level " << level; \ - std::cerr << msg__.str() << std::endl; \ - abort_no_return(); \ - } -#endif - - -inline void GMM_THROW() {} -#define GMM_THROW(a, b) { GMM_THROW_(a,b); gmm::GMM_THROW(); } - -# define GMM_THROW_DEFAULT(errormsg) GMM_THROW_AT_LEVEL(errormsg, 1) - -// This allows not to compile some assertions -#ifndef GMM_ASSERT_LEVEL -#if defined(NDEBUG) -# define GMM_ASSERT_LEVEL 1 -#elif defined(DEBUG_MODE) -# define GMM_ASSERT_LEVEL 3 -#else -# define GMM_ASSERT_LEVEL 2 -#endif -#endif - - -# define GMM_ASSERT1(test, errormsg) { if (!(test)) GMM_THROW_AT_LEVEL(errormsg, 1); } - -#if GMM_ASSERT_LEVEL < 2 -# define GMM_ASSERT2(test, errormsg) {} -# define GMM_ASSERT3(test, errormsg) {} -#elif GMM_ASSERT_LEVEL < 3 -# define GMM_ASSERT2(test, errormsg){ if (!(test)) GMM_THROW_AT_LEVEL(errormsg, 2); } -# define GMM_ASSERT3(test, errormsg){} -#else -# define GMM_ASSERT2(test, errormsg){ if (!(test)) GMM_THROW_AT_LEVEL(errormsg, 2); } -# define GMM_ASSERT3(test, errormsg){ if (!(test)) GMM_THROW_AT_LEVEL(errormsg, 3); } -#endif - -/* *********************************************************************** */ -/* GetFEM++ warnings. */ -/* *********************************************************************** */ - - // This allows not to compile some Warnings -#ifndef GMM_WARNING_LEVEL -# define GMM_WARNING_LEVEL 4 -#endif - - // Warning levels : 0 always printed - // 1 very important : specify a possible error in the code. - // 2 important : specify a default of optimization for inst. - // 3 remark - // 4 ignored by default. - -#define GMM_WARNING_MSG(level_, thestr) { \ - std::stringstream msg__; \ - msg__ << "Level " << level_ << " Warning in " << __FILE__ << ", line " \ - << __LINE__ << ": " << thestr; \ - gmm::feedback_manager::manage()->send(msg__.str(), gmm::FeedbackType::WARNING, level_); \ -} - -#define GMM_WARNING0(thestr) GMM_WARNING_MSG(0, thestr) - - -#if GMM_WARNING_LEVEL > 0 -# define GMM_WARNING1(thestr) \ - { if (1 <= gmm::feedback_manager::warning_level()) GMM_WARNING_MSG(1, thestr) } -#else -# define GMM_WARNING1(thestr) {} -#endif - -#if GMM_WARNING_LEVEL > 1 -# define GMM_WARNING2(thestr) \ - { if (2 <= gmm::feedback_manager::warning_level()) GMM_WARNING_MSG(2, thestr) } -#else -# define GMM_WARNING2(thestr) {} -#endif - -#if GMM_WARNING_LEVEL > 2 -# define GMM_WARNING3(thestr) \ - { if (3 <= gmm::feedback_manager::warning_level()) GMM_WARNING_MSG(3, thestr) } -#else -# define GMM_WARNING3(thestr) {} -#endif - -#if GMM_WARNING_LEVEL > 3 -# define GMM_WARNING4(thestr) \ - { if (4 <= gmm::feedback_manager::warning_level()) GMM_WARNING_MSG(4, thestr) } -#else -# define GMM_WARNING4(thestr) {} -#endif - -/* *********************************************************************** */ -/* GetFEM++ traces. */ -/* *********************************************************************** */ - - // This allow not too compile some Warnings -#ifndef GMM_TRACES_LEVEL -# define GMM_TRACES_LEVEL 4 -#endif - - // Traces levels : 0 always printed - // 1 Susceptible to occur once in a program. - // 2 Susceptible to occur occasionnaly in a program (10). - // 3 Susceptible to occur often (100). - // 4 Susceptible to occur very often (>1000). - -#define GMM_TRACE_MSG_MPI // for Parallelized version -#define GMM_TRACE_MSG(level_, thestr) { \ - GMM_TRACE_MSG_MPI { \ - std::stringstream msg__; \ - msg__ << "Trace " << level_ << " in " << __FILE__ << ", line " \ - << __LINE__ << ": " << thestr; \ - gmm::feedback_manager::send(msg__.str(), gmm::FeedbackType::TRACE, level_); \ - } \ -} - -#define GMM_TRACE_SIMPLE_MSG(level_, thestr) { \ - GMM_TRACE_MSG_MPI { \ - std::stringstream msg__; \ - msg__ << "Trace " << level_ << ": " << thestr; \ - gmm::feedback_manager::send(msg__.str(), gmm::FeedbackType::TRACE, level_); \ - } \ -} - -#define GMM_TRACE0(thestr) GMM_TRACE_MSG(0, thestr) -#define GMM_SIMPLE_TRACE0(thestr) GMM_TRACE_MSG_SIMPLE(0, thestr) - -#if GMM_TRACES_LEVEL > 0 -# define GMM_TRACE1(thestr) \ - { if (1 <= gmm::feedback_manager::traces_level()) GMM_TRACE_MSG(1, thestr) } -# define GMM_SIMPLE_TRACE1(thestr) \ - { if (1 <= gmm::feedback_manager::traces_level()) GMM_TRACE_SIMPLE_MSG(1, thestr) } -#else -# define GMM_TRACE1(thestr) {} -# define GMM_SIMPLE_TRACE1(thestr) {} -#endif - -#if GMM_TRACES_LEVEL > 1 -# define GMM_TRACE2(thestr) \ - { if (2 <= gmm::feedback_manager::traces_level()) GMM_TRACE_MSG(2, thestr) } -# define GMM_SIMPLE_TRACE2(thestr) \ - { if (2 <= gmm::feedback_manager::traces_level()) GMM_TRACE_SIMPLE_MSG(2, thestr) } -#else -# define GMM_TRACE2(thestr) {} -# define GMM_SIMPLE_TRACE2(thestr) {} -#endif - -#if GMM_TRACES_LEVEL > 2 -# define GMM_TRACE3(thestr) \ - { if (3 <= gmm::feedback_manager::traces_level()) GMM_TRACE_MSG(3, thestr) } -# define GMM_SIMPLE_TRACE3(thestr) \ - { if (3 <= gmm::feedback_manager::traces_level()) GMM_TRACE_SIMPLE_MSG(3, thestr) } -#else -# define GMM_TRACE3(thestr) {} -# define GMM_SIMPLE_TRACE3(thestr) {} -#endif - -#if GMM_TRACES_LEVEL > 3 -# define GMM_TRACE4(thestr) \ - { if (4 <= gmm::feedback_manager::traces_level()) GMM_TRACE_MSG(4, thestr) } -# define GMM_SIMPLE_TRACE4(thestr) \ - { if (4 <= gmm::feedback_manager::traces_level()) GMM_TRACE_SIMPLE_MSG(4, thestr) } -#else -# define GMM_TRACE4(thestr) {} -# define GMM_SIMPLE_TRACE4(thestr) {} -#endif - -#define GMM_STANDARD_CATCH_ERROR \ - catch(gmm::gmm_error e) \ - { \ - std::stringstream strStream; \ - strStream << "============================================\n"; \ - strStream << "| A GMM error has been detected !!! |\n"; \ - strStream << "============================================\n"; \ - strStream << e.what() << std::endl << std::endl; \ - gmm::feedback_manager::send(strStream.str(), \ - gmm::FeedbackType::ASSERT, e.errLevel()); \ - gmm::feedback_manager::terminating_action(); \ - } \ - catch(std::logic_error e) \ - { \ - std::stringstream strStream; \ - strStream << "============================================\n"; \ - strStream << "| An error has been detected !!! |\n"; \ - strStream << "============================================\n"; \ - strStream << e.what() << std::endl << std::endl; \ - gmm::feedback_manager::send(strStream.str(), \ - gmm::FeedbackType::ASSERT, 0); \ - gmm::feedback_manager::terminating_action(); \ - } \ - catch(std::runtime_error e) \ - { \ - std::stringstream strStream; \ - strStream << "============================================\n"; \ - strStream << "| A runtime error has been detected !!! |\n"; \ - strStream << "============================================\n"; \ - strStream << e.what() << std::endl << std::endl; \ - gmm::feedback_manager::send(strStream.str(), \ - gmm::FeedbackType::ASSERT, 0); \ - gmm::feedback_manager::terminating_action(); \ - } \ - catch(std::bad_alloc) \ - { \ - std::stringstream strStream; \ - strStream << "============================================\n"; \ - strStream << "| A bad allocation has been detected !!! |\n"; \ - strStream << "============================================\n"; \ - gmm::feedback_manager::send(strStream.str(), \ - gmm::FeedbackType::ASSERT, 0); \ - gmm::feedback_manager::terminating_action(); \ - } \ - catch(std::bad_typeid) \ - { \ - std::stringstream strStream; \ - strStream << "============================================\n"; \ - strStream << "| A bad typeid has been detected !!! |\n"; \ - strStream << "============================================\n"; \ - gmm::feedback_manager::send(strStream.str(), \ - gmm::FeedbackType::ASSERT, 0); \ - gmm::feedback_manager::terminating_action(); \ - } \ - catch(std::bad_exception) \ - { \ - std::stringstream strStream; \ - strStream << "============================================\n"; \ - strStream << "| A bad exception has been detected !!! |\n"; \ - strStream << "============================================\n"; \ - gmm::feedback_manager::send(strStream.str(), \ - gmm::FeedbackType::ASSERT, 0); \ - gmm::feedback_manager::terminating_action(); \ - } \ - catch(std::bad_cast) \ - { \ - std::stringstream strStream; \ - strStream << "============================================\n"; \ - strStream << "| A bad_cast has been detected !!! |\n"; \ - strStream << "============================================\n"; \ - gmm::feedback_manager::send(strStream.str(), \ - gmm::FeedbackType::ASSERT, 0); \ - gmm::feedback_manager::terminating_action(); \ - } \ - catch(...) \ - { \ - std::stringstream strStream; \ - strStream << "============================================\n"; \ - strStream << "| An unknown error has been detected !!! |\n"; \ - strStream << "============================================\n"; \ - gmm::feedback_manager::send(strStream.str(), \ - gmm::FeedbackType::ASSERT, 0); \ - gmm::feedback_manager::terminating_action(); \ - } - // catch(ios_base::failure) { - // std::cerr << "============================================\n"; - // std::cerr << "| A ios_base::failure has been detected !!!|\n"; - // std::cerr << "============================================\n"; - // exit(1); - // } - -#if defined(__GNUC__) && (__GNUC__ > 3) -# define GMM_SET_EXCEPTION_DEBUG \ - std::set_terminate(__gnu_cxx::__verbose_terminate_handler); -#else -# define GMM_SET_EXCEPTION_DEBUG -#endif - -} // namespace gmm - -#endif /* GMM_EXCEPT_H__ */ diff --git a/gmm/gmm_feedback_management.h b/gmm/gmm_feedback_management.h deleted file mode 100644 index d401aa130..000000000 --- a/gmm/gmm_feedback_management.h +++ /dev/null @@ -1,174 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/** @file gmm_feedback_management.h - @date July 03, 2017. - @brief Support for run time management of trace, warning and assert - feedback. -*/ - -#ifndef GMM_FEEDBACK_MANAGEMENT_H__ -#define GMM_FEEDBACK_MANAGEMENT_H__ -#include -#include -#include - -namespace gmm { - -/* *********************************************************************** */ -/* GetFEM++ warnings. */ -/* *********************************************************************** */ - -// This allows to dynamically hide warnings -struct warning_level { - static int level(int l = -2) - { static int level_ = 3; return (l != -2) ? (level_ = l) : level_; } -}; - -inline void set_warning_level(int l) { warning_level::level(l>0 ? l : 0); } -inline int get_warning_level(void) { return warning_level::level(-2); } - -/* *********************************************************************** */ -/* GetFEM++ traces. */ -/* *********************************************************************** */ - -// This allows to dynamically hide traces -struct traces_level { - static int level(int l = -2) - { static int level_ = 3; return (l != -2) ? (level_ = l) : level_; } -}; - -inline void set_traces_level(int l) { traces_level::level(l>0 ? l : 0); } -inline int get_traces_level(void) { return traces_level::level(); } - - -/* *********************************************************************** */ -/* GetFEM++ feedback management */ -/* *********************************************************************** */ - -enum class FeedbackType { - TRACE = 0, - WARNING, - ASSERT -}; - -// Abstract class providing feedback management interface. -// The interface consist of three functions: -// * for sending feedback message -// * for getting traces level -// * for getting warning level -// * for action to be done after feedback is handled -struct base_feedback_handler { - virtual ~base_feedback_handler() = default; - virtual void send(const std::string &message, FeedbackType messageType, size_t level) = 0; - virtual size_t traces_level() { return get_traces_level(); } - virtual size_t warning_level() { return get_warning_level(); } - virtual void terminating_action() = 0; -}; - - -// Provides the default implementation of feedback handling. -struct default_feedback_handler final : public base_feedback_handler { - void send(const std::string &message, FeedbackType, size_t) override { - std::cerr << message << std::endl; - } - void terminating_action() override { - std::exit(1); - } -}; - -// This class acts as a run-time dispatcher for sending feedback -// messages and getting trace and warning levels. -class feedback_manager { -public: - // Management actions - enum Action { - SET, // Sets the feedback handler, releasing the one previously set. - GET, // Returns currently managed handler (it is still managed). - REPLACE, // Replace manager with a new one, stop managing the old one - // and returns it unmanaged to the caller. The caller is - // then responsible for managing the memory of the handler. - }; - - // Steals the pointer to a messenger object that provides - // feedback handling implementation. - // - // Example: - // feedback_manager::manage(new default_feedback_handler); - // - static base_feedback_handler* manage(enum Action action=GET, base_feedback_handler *pHandler=nullptr); - static void send(const std::string &message, FeedbackType type, size_t level); - static size_t traces_level(); - static size_t warning_level(); - // Action to be taken when feedback handling is done - static void terminating_action(); -}; - -// Depending on action either gets, sets or replaces feedback handler. Setting handler to null resets -// it to gmm::default_feedback_handler. -inline base_feedback_handler* feedback_manager::manage(enum Action action, base_feedback_handler *pHandler) { - static std::unique_ptr pHandler_ = - std::unique_ptr(new default_feedback_handler); - base_feedback_handler *rethandler = nullptr; - switch(action) { - case SET: - pHandler_.reset(pHandler != nullptr ? pHandler : new default_feedback_handler); - rethandler = pHandler_.get(); - break; - case GET: - rethandler = pHandler_.get(); - break; - case REPLACE: - rethandler = pHandler_.release(); - pHandler_.reset(pHandler != nullptr ? pHandler : new default_feedback_handler); - break; - } - return rethandler; -} - -inline void feedback_manager::send(const std::string &message, FeedbackType type, size_t level) { - feedback_manager::manage()->send(message, type, level); -} - -inline void feedback_manager::terminating_action() { - feedback_manager::manage()->terminating_action(); -} - -inline size_t feedback_manager::traces_level() { - return feedback_manager::manage()->traces_level(); -} - -inline size_t feedback_manager::warning_level() { - return feedback_manager::manage()->warning_level(); -} - -} // namespace gmm -#endif /* GMM_FEEDBACK_MANAGEMENT_H__ */ diff --git a/gmm/gmm_inoutput.h b/gmm/gmm_inoutput.h deleted file mode 100644 index 0e27b17cc..000000000 --- a/gmm/gmm_inoutput.h +++ /dev/null @@ -1,1176 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard, Julien Pommier - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_inoutput.h - @author Yves Renard - @author Julien Pommier - @date July 8, 2003. - @brief Input/output on sparse matrices - - Support Harwell-Boeing and Matrix-Market formats. -*/ -#ifndef GMM_INOUTPUT_H -#define GMM_INOUTPUT_H - -#include -#include "gmm_kernel.h" -namespace gmm { - - /*************************************************************************/ - /* */ - /* Functions to read and write Harwell Boeing format. */ - /* */ - /*************************************************************************/ - - // Fri Aug 15 16:29:47 EDT 1997 - // - // Harwell-Boeing File I/O in C - // V. 1.0 - // - // National Institute of Standards and Technology, MD. - // K.A. Remington - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // NOTICE - // - // Permission to use, copy, modify, and distribute this software and - // its documentation for any purpose and without fee is hereby granted - // provided that the above copyright notice appear in all copies and - // that both the copyright notice and this permission notice appear in - // supporting documentation. - // - // Neither the Author nor the Institution (National Institute of Standards - // and Technology) make any representations about the suitability of this - // software for any purpose. This software is provided "as is" without - // expressed or implied warranty. - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - inline void IOHBTerminate(const char *a) { GMM_ASSERT1(false, a);} - - inline bool is_complex_double__(std::complex) { return true; } - inline bool is_complex_double__(double) { return false; } - - inline int ParseIfmt(const char *fmt, int* perline, int* width) { - if (SECURE_NONCHAR_SSCANF(fmt, " (%dI%d)", perline, width) != 2) { - *perline = 1; - int s = SECURE_NONCHAR_SSCANF(fmt, " (I%d)", width); - GMM_ASSERT1(s == 1, "invalid HB I-format: " << fmt); - } - return *width; - } - - inline int ParseRfmt(const char *fmt, int* perline, int* width, - int* prec, int* flag) { - char p; - *perline = *width = *flag = *prec = 0; -#ifdef GMM_SECURE_CRT - if (sscanf_s(fmt, " (%d%c%d.%d)", perline, &p, sizeof(char), width, prec) - < 3 || !strchr("PEDF", p)) -#else - if (sscanf(fmt, " (%d%c%d.%d)", perline, &p, width, prec) < 3 - || !strchr("PEDF", p)) -#endif - { - *perline = 1; -#ifdef GMM_SECURE_CRT - int s = sscanf_s(fmt, " (%c%d.%d)", &p, sizeof(char), width, prec); -#else - int s = sscanf(fmt, " (%c%d.%d)", &p, width, prec); -#endif - GMM_ASSERT1(s>=2 && strchr("PEDF",p), "invalid HB REAL format: " << fmt); - } - *flag = p; - return *width; - } - - /** matrix input/output for Harwell-Boeing format */ - struct HarwellBoeing_IO { - int nrows() const { return Nrow; } - int ncols() const { return Ncol; } - int nnz() const { return Nnzero; } - int is_complex() const { return Type[0] == 'C'; } - int is_symmetric() const { return Type[1] == 'S'; } - int is_hermitian() const { return Type[1] == 'H'; } - HarwellBoeing_IO() { clear(); } - HarwellBoeing_IO(const char *filename) { clear(); open(filename); } - ~HarwellBoeing_IO() { close(); } - /** open filename and reads header */ - void open(const char *filename); - /** read the opened file */ - template void read(csc_matrix& A); - template void read(MAT &M) IS_DEPRECATED; - template - static void write(const char *filename, const csc_matrix& A); - template - static void write(const char *filename, const csc_matrix& A, - const std::vector &rhs); - template - static void write(const char *filename, - const csc_matrix_ref& A); - template - static void write(const char *filename, - const csc_matrix_ref& A, - const std::vector &rhs); - - /** static method for saving the matrix */ - template static void write(const char *filename, - const MAT& A) IS_DEPRECATED; - private: - FILE *f; - char Title[73], Key[9], Rhstype[4], Type[4]; - int Nrow, Ncol, Nnzero, Nrhs; - char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21]; - int Ptrcrd, Indcrd, Valcrd, Rhscrd; - int lcount; - - - void close() { if (f) fclose(f); clear(); } - void clear() { - Nrow = Ncol = Nnzero = Nrhs = 0; f = 0; lcount = 0; - memset(Type, 0, sizeof Type); - memset(Key, 0, sizeof Key); - memset(Title, 0, sizeof Title); - } - char *getline(char *buf) { - char *p = fgets(buf, BUFSIZ, f); ++lcount; - int s = SECURE_NONCHAR_SSCANF(buf,"%*s"); - GMM_ASSERT1(s >= 0 && p != 0, - "blank line in HB file at line " << lcount); - return buf; - } - - int substrtoi(const char *p, size_type len) { - char s[100]; len = std::min(len, sizeof s - 1); - SECURE_STRNCPY(s, 100, p, len); s[len] = 0; return atoi(s); - } - double substrtod(const char *p, size_type len, int Valflag) { - char s[100]; len = std::min(len, sizeof s - 1); - SECURE_STRNCPY(s, 100, p, len); s[len] = 0; - if ( Valflag != 'F' && !strchr(s,'E')) { - /* insert a char prefix for exp */ - int last = int(strlen(s)); - for (int j=last+1;j>=0;j--) { - s[j] = s[j-1]; - if ( s[j] == '+' || s[j] == '-' ) { - s[j-1] = char(Valflag); - break; - } - } - } - return atof(s); - } - template - int readHB_data(IND_TYPE colptr[], IND_TYPE rowind[], - double val[]) { - /***********************************************************************/ - /* This function opens and reads the specified file, interpreting its */ - /* contents as a sparse matrix stored in the Harwell/Boeing standard */ - /* format and creating compressed column storage scheme vectors to */ - /* hold the index and nonzero value information. */ - /* */ - /* ---------- */ - /* **CAVEAT** */ - /* ---------- */ - /* Parsing real formats from Fortran is tricky, and this file reader */ - /* does not claim to be foolproof. It has been tested for cases */ - /* when the real values are printed consistently and evenly spaced on */ - /* each line, with Fixed (F), and Exponential (E or D) formats. */ - /* */ - /* ** If the input file does not adhere to the H/B format, the ** */ - /* ** results will be unpredictable. ** */ - /* */ - /***********************************************************************/ - int i,ind,col,offset,count; - int Ptrperline, Ptrwidth, Indperline, Indwidth; - int Valperline, Valwidth, Valprec, Nentries; - int Valflag = 'D'; /* Indicates 'E','D', or 'F' float format */ - char line[BUFSIZ]; - gmm::standard_locale sl; - - - /* Parse the array input formats from Line 3 of HB file */ - ParseIfmt(Ptrfmt,&Ptrperline,&Ptrwidth); - ParseIfmt(Indfmt,&Indperline,&Indwidth); - if ( Type[0] != 'P' ) { /* Skip if pattern only */ - ParseRfmt(Valfmt,&Valperline,&Valwidth,&Valprec,&Valflag); - } - - /* Read column pointer array: */ - offset = 0; /* if base 0 storage is declared (via macro def), */ - /* then storage entries are offset by 1 */ - - for (count = 0, i=0;i Ncol) break; - colptr[count] = substrtoi(line+col,Ptrwidth)-offset; - count++; col += Ptrwidth; - } - } - - /* Read row index array: */ - for (count = 0, i=0;i(strchr(line,'D')) )) *p = 'E'; - } - for (col = 0, ind = 0;ind csc matrices */ - template void - HarwellBoeing_IO::read(csc_matrix& A) { - - // typedef typename csc_matrix::IND_TYPE IND_TYPE; - - GMM_ASSERT1(f, "no file opened!"); - GMM_ASSERT1(Type[0] != 'P', - "Bad HB matrix format (pattern matrices not supported)"); - GMM_ASSERT1(!is_complex_double__(T()) || Type[0] != 'R', - "Bad HB matrix format (file contains a REAL matrix)"); - GMM_ASSERT1(is_complex_double__(T()) || Type[0] != 'C', - "Bad HB matrix format (file contains a COMPLEX matrix)"); - A.nc = ncols(); A.nr = nrows(); - A.jc.resize(ncols()+1); - A.ir.resize(nnz()); - A.pr.resize(nnz()); - readHB_data(&A.jc[0], &A.ir[0], (double*)&A.pr[0]); - for (int i = 0; i <= ncols(); ++i) { A.jc[i] += shift; A.jc[i] -= 1; } - for (int i = 0; i < nnz(); ++i) { A.ir[i] += shift; A.ir[i] -= 1; } - } - - template void - HarwellBoeing_IO::read(MAT &M) { - csc_matrix::value_type> csc; - read(csc); - resize(M, mat_nrows(csc), mat_ncols(csc)); - copy(csc, M); - } - - template - inline int writeHB_mat_double(const char* filename, int M, int N, int nz, - const IND_TYPE colptr[], - const IND_TYPE rowind[], - const double val[], int Nrhs, - const double rhs[], const double guess[], - const double exact[], const char* Title, - const char* Key, const char* Type, - const char* Ptrfmt, const char* Indfmt, - const char* Valfmt, const char* Rhsfmt, - const char* Rhstype, int shift) { - /************************************************************************/ - /* The writeHB function opens the named file and writes the specified */ - /* matrix and optional right-hand-side(s) to that file in */ - /* Harwell-Boeing format. */ - /* */ - /* For a description of the Harwell Boeing standard, see: */ - /* Duff, et al., ACM TOMS Vol.15, No.1, March 1989 */ - /* */ - /************************************************************************/ - FILE *out_file; - int i, entry, offset, j, acount, linemod; - int totcrd, ptrcrd, indcrd, valcrd, rhscrd; - int nvalentries, nrhsentries; - int Ptrperline, Ptrwidth, Indperline, Indwidth; - int Rhsperline, Rhswidth, Rhsprec, Rhsflag; - int Valperline, Valwidth, Valprec; - int Valflag; /* Indicates 'E','D', or 'F' float format */ - char pformat[16],iformat[16],vformat[19],rformat[19]; - // char *pValflag, *pRhsflag; - gmm::standard_locale sl; - - if ( Type[0] == 'C' ) - { nvalentries = 2*nz; nrhsentries = 2*M; } - else - { nvalentries = nz; nrhsentries = M; } - - if ( filename != NULL ) { - SECURE_FOPEN(&out_file, filename, "w"); - GMM_ASSERT1(out_file != NULL, "Error: Cannot open file: " << filename); - } else out_file = stdout; - - if ( Ptrfmt == NULL ) Ptrfmt = "(8I10)"; - ParseIfmt(Ptrfmt, &Ptrperline, &Ptrwidth); - SECURE_SPRINTF1(pformat,sizeof(pformat),"%%%dd",Ptrwidth); - ptrcrd = (N+1)/Ptrperline; - if ( (N+1)%Ptrperline != 0) ptrcrd++; - - if ( Indfmt == NULL ) Indfmt = Ptrfmt; - ParseIfmt(Indfmt, &Indperline, &Indwidth); - SECURE_SPRINTF1(iformat,sizeof(iformat), "%%%dd",Indwidth); - indcrd = nz/Indperline; - if ( nz%Indperline != 0) indcrd++; - - if ( Type[0] != 'P' ) { /* Skip if pattern only */ - if ( Valfmt == NULL ) Valfmt = "(4E21.13)"; - ParseRfmt(Valfmt, &Valperline, &Valwidth, &Valprec, &Valflag); -// if (Valflag == 'D') { -// pValflag = (char *) strchr(Valfmt,'D'); -// *pValflag = 'E'; -// } - if (Valflag == 'F') - SECURE_SPRINTF2(vformat, sizeof(vformat), "%% %d.%df", Valwidth, - Valprec); - else - SECURE_SPRINTF2(vformat, sizeof(vformat), "%% %d.%dE", Valwidth, - Valprec); - valcrd = nvalentries/Valperline; - if ( nvalentries%Valperline != 0) valcrd++; - } else valcrd = 0; - - if ( Nrhs > 0 ) { - if ( Rhsfmt == NULL ) Rhsfmt = Valfmt; - ParseRfmt(Rhsfmt,&Rhsperline,&Rhswidth,&Rhsprec, &Rhsflag); - if (Rhsflag == 'F') - SECURE_SPRINTF2(rformat,sizeof(rformat), "%% %d.%df",Rhswidth,Rhsprec); - else - SECURE_SPRINTF2(rformat,sizeof(rformat), "%% %d.%dE",Rhswidth,Rhsprec); -// if (Valflag == 'D') { -// pRhsflag = (char *) strchr(Rhsfmt,'D'); -// *pRhsflag = 'E'; -// } - rhscrd = nrhsentries/Rhsperline; - if ( nrhsentries%Rhsperline != 0) rhscrd++; - if ( Rhstype[1] == 'G' ) rhscrd+=rhscrd; - if ( Rhstype[2] == 'X' ) rhscrd+=rhscrd; - rhscrd*=Nrhs; - } else rhscrd = 0; - - totcrd = 4+ptrcrd+indcrd+valcrd+rhscrd; - - - /* Print header information: */ - - fprintf(out_file,"%-72s%-8s\n%14d%14d%14d%14d%14d\n",Title, Key, totcrd, - ptrcrd, indcrd, valcrd, rhscrd); - fprintf(out_file,"%3s%11s%14d%14d%14d%14d\n",Type," ", M, N, nz, 0); - fprintf(out_file,"%-16s%-16s%-20s", Ptrfmt, Indfmt, Valfmt); - if ( Nrhs != 0 ) { - /* Print Rhsfmt on fourth line and */ - /* optional fifth header line for auxillary vector information:*/ - fprintf(out_file,"%-20s\n%-14s%d\n",Rhsfmt,Rhstype,Nrhs); - } - else - fprintf(out_file,"\n"); - - offset = 1 - shift; /* if base 0 storage is declared (via macro def), */ - /* then storage entries are offset by 1 */ - - /* Print column pointers: */ - for (i = 0; i < N+1; i++) { - entry = colptr[i]+offset; - fprintf(out_file,pformat,entry); - if ( (i+1)%Ptrperline == 0 ) fprintf(out_file,"\n"); - } - - if ( (N+1) % Ptrperline != 0 ) fprintf(out_file,"\n"); - - /* Print row indices: */ - for (i=0;i 0 ) { - for (j=0;j void - HarwellBoeing_IO::write(const char *filename, - const csc_matrix& A) { - write(filename, csc_matrix_ref - (&A.pr[0], &A.ir[0], &A.jc[0], A.nr, A.nc)); - } - - template void - HarwellBoeing_IO::write(const char *filename, - const csc_matrix& A, - const std::vector &rhs) { - write(filename, csc_matrix_ref - (&A.pr[0], &A.ir[0], &A.jc[0], A.nr, A.nc), rhs); - } - - template void - HarwellBoeing_IO::write(const char *filename, - const csc_matrix_ref& A) { - const char *t = 0; - if (is_complex_double__(T())) - if (mat_nrows(A) == mat_ncols(A)) t = "CUA"; else t = "CRA"; - else - if (mat_nrows(A) == mat_ncols(A)) t = "RUA"; else t = "RRA"; - writeHB_mat_double(filename, int(mat_nrows(A)), int(mat_ncols(A)), - A.jc[mat_ncols(A)], A.jc, A.ir, - (const double *)A.pr, - 0, 0, 0, 0, "GETFEM++ CSC MATRIX", "CSCMAT", - t, 0, 0, 0, 0, "F", shift); - } - - template void - HarwellBoeing_IO::write(const char *filename, - const csc_matrix_ref& A, - const std::vector &rhs) { - const char *t = 0; - if (is_complex_double__(T())) - if (mat_nrows(A) == mat_ncols(A)) t = "CUA"; else t = "CRA"; - else - if (mat_nrows(A) == mat_ncols(A)) t = "RUA"; else t = "RRA"; - int Nrhs = gmm::vect_size(rhs) / mat_nrows(A); - writeHB_mat_double(filename, int(mat_nrows(A)), int(mat_ncols(A)), - A.jc[mat_ncols(A)], A.jc, A.ir, - (const double *)A.pr, - Nrhs, (const double *)(&rhs[0]), 0, 0, - "GETFEM++ CSC MATRIX", "CSCMAT", - t, 0, 0, 0, 0, "F ", shift); - } - - - template void - HarwellBoeing_IO::write(const char *filename, const MAT& A) { - gmm::csc_matrix::value_type> - tmp(gmm::mat_nrows(A), gmm::mat_ncols(A)); - gmm::copy(A,tmp); - HarwellBoeing_IO::write(filename, tmp); - } - - /** save a "double" or "std::complex" csc matrix into a - HarwellBoeing file - */ - template inline void - Harwell_Boeing_save(const std::string &filename, - const csc_matrix& A) - { HarwellBoeing_IO::write(filename.c_str(), A); } - - /** save a reference on "double" or "std::complex" csc matrix - into a HarwellBoeing file - */ - template inline void - Harwell_Boeing_save(const std::string &filename, - const csc_matrix_ref& A) - { HarwellBoeing_IO::write(filename.c_str(), A); } - - /** save a "double" or "std::complex" generic matrix - into a HarwellBoeing file making a copy in a csc matrix - */ - template inline void - Harwell_Boeing_save(const std::string &filename, const MAT& A) { - gmm::csc_matrix::value_type> - tmp(gmm::mat_nrows(A), gmm::mat_ncols(A)); - gmm::copy(A, tmp); - HarwellBoeing_IO::write(filename.c_str(), tmp); - } - - template inline void - Harwell_Boeing_save(const std::string &filename, const MAT& A, - const VECT &RHS) { - typedef typename gmm::linalg_traits::value_type T; - gmm::csc_matrix tmp(gmm::mat_nrows(A), gmm::mat_ncols(A)); - gmm::copy(A, tmp); - std::vector tmprhs(gmm::vect_size(RHS)); - gmm::copy(RHS, tmprhs); - HarwellBoeing_IO::write(filename.c_str(), tmp, tmprhs); - } - - /** load a "double" or "std::complex" csc matrix from a - HarwellBoeing file - */ - template void - Harwell_Boeing_load(const std::string &filename, csc_matrix& A) { - HarwellBoeing_IO h(filename.c_str()); h.read(A); - } - - /** load a "double" or "std::complex" generic matrix from a - HarwellBoeing file - */ - template void - Harwell_Boeing_load(const std::string &filename, MAT& A) { - csc_matrix::value_type> csc; - Harwell_Boeing_load(filename, csc); - resize(A, mat_nrows(csc), mat_ncols(csc)); - copy(csc, A); - } - - /*************************************************************************/ - /* */ - /* Functions to read and write MatrixMarket format. */ - /* */ - /*************************************************************************/ - - /* - * Matrix Market I/O library for ANSI C - * - * See http://math.nist.gov/MatrixMarket for details. - * - * - */ - -#define MM_MAX_LINE_LENGTH 1025 -#define MatrixMarketBanner "%%MatrixMarket" -#define MM_MAX_TOKEN_LENGTH 64 - - typedef char MM_typecode[4]; - - /******************* MM_typecode query functions *************************/ - -#define mm_is_matrix(typecode) ((typecode)[0]=='M') - -#define mm_is_sparse(typecode) ((typecode)[1]=='C') -#define mm_is_coordinate(typecode) ((typecode)[1]=='C') -#define mm_is_dense(typecode) ((typecode)[1]=='A') -#define mm_is_array(typecode) ((typecode)[1]=='A') - -#define mm_is_complex(typecode) ((typecode)[2]=='C') -#define mm_is_real(typecode) ((typecode)[2]=='R') -#define mm_is_pattern(typecode) ((typecode)[2]=='P') -#define mm_is_integer(typecode) ((typecode)[2]=='I') - -#define mm_is_symmetric(typecode) ((typecode)[3]=='S') -#define mm_is_general(typecode) ((typecode)[3]=='G') -#define mm_is_skew(typecode) ((typecode)[3]=='K') -#define mm_is_hermitian(typecode) ((typecode)[3]=='H') - - /******************* MM_typecode modify fucntions ************************/ - -#define mm_set_matrix(typecode) ((*typecode)[0]='M') -#define mm_set_coordinate(typecode) ((*typecode)[1]='C') -#define mm_set_array(typecode) ((*typecode)[1]='A') -#define mm_set_dense(typecode) mm_set_array(typecode) -#define mm_set_sparse(typecode) mm_set_coordinate(typecode) - -#define mm_set_complex(typecode) ((*typecode)[2]='C') -#define mm_set_real(typecode) ((*typecode)[2]='R') -#define mm_set_pattern(typecode) ((*typecode)[2]='P') -#define mm_set_integer(typecode) ((*typecode)[2]='I') - - -#define mm_set_symmetric(typecode) ((*typecode)[3]='S') -#define mm_set_general(typecode) ((*typecode)[3]='G') -#define mm_set_skew(typecode) ((*typecode)[3]='K') -#define mm_set_hermitian(typecode) ((*typecode)[3]='H') - -#define mm_clear_typecode(typecode) ((*typecode)[0]=(*typecode)[1]= \ - (*typecode)[2]=' ',(*typecode)[3]='G') - -#define mm_initialize_typecode(typecode) mm_clear_typecode(typecode) - - - /******************* Matrix Market error codes ***************************/ - - -#define MM_COULD_NOT_READ_FILE 11 -#define MM_PREMATURE_EOF 12 -#define MM_NOT_MTX 13 -#define MM_NO_HEADER 14 -#define MM_UNSUPPORTED_TYPE 15 -#define MM_LINE_TOO_LONG 16 -#define MM_COULD_NOT_WRITE_FILE 17 - - - /******************** Matrix Market internal definitions ***************** - - MM_matrix_typecode: 4-character sequence - - object sparse/ data storage - dense type scheme - - string position: [0] [1] [2] [3] - - Matrix typecode: M(atrix) C(oord) R(eal) G(eneral) - A(array) C(omplex) H(ermitian) - P(attern) S(ymmetric) - I(nteger) K(kew) - - ***********************************************************************/ - -#define MM_MTX_STR "matrix" -#define MM_ARRAY_STR "array" -#define MM_DENSE_STR "array" -#define MM_COORDINATE_STR "coordinate" -#define MM_SPARSE_STR "coordinate" -#define MM_COMPLEX_STR "complex" -#define MM_REAL_STR "real" -#define MM_INT_STR "integer" -#define MM_GENERAL_STR "general" -#define MM_SYMM_STR "symmetric" -#define MM_HERM_STR "hermitian" -#define MM_SKEW_STR "skew-symmetric" -#define MM_PATTERN_STR "pattern" - - inline char *mm_typecode_to_str(MM_typecode matcode) { - char buffer[MM_MAX_LINE_LENGTH]; - const char *types[4] = {0,0,0,0}; - /* int error =0; */ - /* int i; */ - - /* check for MTX type */ - if (mm_is_matrix(matcode)) - types[0] = MM_MTX_STR; - /* - else - error=1; - */ - /* check for CRD or ARR matrix */ - if (mm_is_sparse(matcode)) - types[1] = MM_SPARSE_STR; - else - if (mm_is_dense(matcode)) - types[1] = MM_DENSE_STR; - else - return NULL; - - /* check for element data type */ - if (mm_is_real(matcode)) - types[2] = MM_REAL_STR; - else - if (mm_is_complex(matcode)) - types[2] = MM_COMPLEX_STR; - else - if (mm_is_pattern(matcode)) - types[2] = MM_PATTERN_STR; - else - if (mm_is_integer(matcode)) - types[2] = MM_INT_STR; - else - return NULL; - - - /* check for symmetry type */ - if (mm_is_general(matcode)) - types[3] = MM_GENERAL_STR; - else if (mm_is_symmetric(matcode)) - types[3] = MM_SYMM_STR; - else if (mm_is_hermitian(matcode)) - types[3] = MM_HERM_STR; - else if (mm_is_skew(matcode)) - types[3] = MM_SKEW_STR; - else - return NULL; - - SECURE_SPRINTF4(buffer, sizeof(buffer), "%s %s %s %s", types[0], types[1], - types[2], types[3]); - return SECURE_STRDUP(buffer); - - } - - inline int mm_read_banner(FILE *f, MM_typecode *matcode) { - char line[MM_MAX_LINE_LENGTH]; - char banner[MM_MAX_TOKEN_LENGTH]; - char mtx[MM_MAX_TOKEN_LENGTH]; - char crd[MM_MAX_TOKEN_LENGTH]; - char data_type[MM_MAX_TOKEN_LENGTH]; - char storage_scheme[MM_MAX_TOKEN_LENGTH]; - char *p; - gmm::standard_locale sl; - /* int ret_code; */ - - mm_clear_typecode(matcode); - - if (fgets(line, MM_MAX_LINE_LENGTH, f) == NULL) - return MM_PREMATURE_EOF; - -#ifdef GMM_SECURE_CRT - if (sscanf_s(line, "%s %s %s %s %s", banner, sizeof(banner), - mtx, sizeof(mtx), crd, sizeof(crd), data_type, - sizeof(data_type), storage_scheme, - sizeof(storage_scheme)) != 5) -#else - if (sscanf(line, "%s %s %s %s %s", banner, mtx, crd, - data_type, storage_scheme) != 5) -#endif - return MM_PREMATURE_EOF; - - for (p=mtx; *p!='\0'; *p=char(tolower(*p)),p++) {}; /* convert to lower case */ - for (p=crd; *p!='\0'; *p=char(tolower(*p)),p++) {}; - for (p=data_type; *p!='\0'; *p=char(tolower(*p)),p++) {}; - for (p=storage_scheme; *p!='\0'; *p=char(tolower(*p)),p++) {}; - - /* check for banner */ - if (strncmp(banner, MatrixMarketBanner, strlen(MatrixMarketBanner)) != 0) - return MM_NO_HEADER; - - /* first field should be "mtx" */ - if (strcmp(mtx, MM_MTX_STR) != 0) - return MM_UNSUPPORTED_TYPE; - mm_set_matrix(matcode); - - - /* second field describes whether this is a sparse matrix (in coordinate - storgae) or a dense array */ - - - if (strcmp(crd, MM_SPARSE_STR) == 0) - mm_set_sparse(matcode); - else - if (strcmp(crd, MM_DENSE_STR) == 0) - mm_set_dense(matcode); - else - return MM_UNSUPPORTED_TYPE; - - - /* third field */ - - if (strcmp(data_type, MM_REAL_STR) == 0) - mm_set_real(matcode); - else - if (strcmp(data_type, MM_COMPLEX_STR) == 0) - mm_set_complex(matcode); - else - if (strcmp(data_type, MM_PATTERN_STR) == 0) - mm_set_pattern(matcode); - else - if (strcmp(data_type, MM_INT_STR) == 0) - mm_set_integer(matcode); - else - return MM_UNSUPPORTED_TYPE; - - - /* fourth field */ - - if (strcmp(storage_scheme, MM_GENERAL_STR) == 0) - mm_set_general(matcode); - else - if (strcmp(storage_scheme, MM_SYMM_STR) == 0) - mm_set_symmetric(matcode); - else - if (strcmp(storage_scheme, MM_HERM_STR) == 0) - mm_set_hermitian(matcode); - else - if (strcmp(storage_scheme, MM_SKEW_STR) == 0) - mm_set_skew(matcode); - else - return MM_UNSUPPORTED_TYPE; - - return 0; - } - - inline int mm_read_mtx_crd_size(FILE *f, int *M, int *N, int *nz ) { - char line[MM_MAX_LINE_LENGTH]; - /* int ret_code;*/ - int num_items_read; - - /* set return null parameter values, in case we exit with errors */ - *M = *N = *nz = 0; - - /* now continue scanning until you reach the end-of-comments */ - do { - if (fgets(line,MM_MAX_LINE_LENGTH,f) == NULL) - return MM_PREMATURE_EOF; - } while (line[0] == '%'); - - /* line[] is either blank or has M,N, nz */ - if (SECURE_NONCHAR_SSCANF(line, "%d %d %d", M, N, nz) == 3) return 0; - else - do { - num_items_read = SECURE_NONCHAR_FSCANF(f, "%d %d %d", M, N, nz); - if (num_items_read == EOF) return MM_PREMATURE_EOF; - } - while (num_items_read != 3); - - return 0; - } - - - inline int mm_read_mtx_crd_data(FILE *f, int, int, int nz, int II[], - int J[], double val[], MM_typecode matcode) { - int i; - if (mm_is_complex(matcode)) { - for (i=0; i void read(Matrix &A); - /* write a matrix */ - template static void - write(const char *filename, const csc_matrix& A); - template static void - write(const char *filename, - const csc_matrix_ref& A); - template static void - write(const char *filename, const MAT& A); - }; - - /** load a matrix-market file */ - template inline void - MatrixMarket_load(const char *filename, Matrix& A) { - MatrixMarket_IO mm; mm.open(filename); - mm.read(A); - } - /** write a matrix-market file */ - template void - MatrixMarket_save(const char *filename, const csc_matrix& A) { - MatrixMarket_IO mm; mm.write(filename, A); - } - - template inline void - MatrixMarket_save(const char *filename, - const csc_matrix_ref& A) { - MatrixMarket_IO mm; mm.write(filename, A); - } - - - inline void MatrixMarket_IO::open(const char *filename) { - gmm::standard_locale sl; - if (f) { fclose(f); } - SECURE_FOPEN(&f, filename, "r"); - GMM_ASSERT1(f, "Sorry, cannot open file " << filename); - int s1 = mm_read_banner(f, &matcode); - GMM_ASSERT1(s1 == 0, "Sorry, cannnot find the matrix market banner in " - << filename); - int s2 = mm_is_coordinate(matcode), s3 = mm_is_matrix(matcode); - GMM_ASSERT1(s2 > 0 && s3 > 0, - "file is not coordinate storage or is not a matrix"); - int s4 = mm_is_pattern(matcode); - GMM_ASSERT1(s4 == 0, - "the file does only contain the pattern of a sparse matrix"); - int s5 = mm_is_skew(matcode); - GMM_ASSERT1(s5 == 0, "not currently supporting skew symmetric"); - isSymmetric = mm_is_symmetric(matcode) || mm_is_hermitian(matcode); - isHermitian = mm_is_hermitian(matcode); - isComplex = mm_is_complex(matcode); - mm_read_mtx_crd_size(f, &row, &col, &nz); - } - - template void MatrixMarket_IO::read(Matrix &A) { - gmm::standard_locale sl; - typedef typename linalg_traits::value_type T; - GMM_ASSERT1(f, "no file opened!"); - GMM_ASSERT1(!is_complex_double__(T()) || isComplex, - "Bad MM matrix format (complex matrix expected)"); - GMM_ASSERT1(is_complex_double__(T()) || !isComplex, - "Bad MM matrix format (real matrix expected)"); - A = Matrix(row, col); - gmm::clear(A); - - std::vector II(nz), J(nz); - std::vector PR(nz); - mm_read_mtx_crd_data(f, row, col, nz, &II[0], &J[0], - (double*)&PR[0], matcode); - - for (size_type i = 0; i < size_type(nz); ++i) { - A(II[i]-1, J[i]-1) = PR[i]; - - // FIXED MM Format - if (mm_is_hermitian(matcode) && (II[i] != J[i]) ) { - A(J[i]-1, II[i]-1) = gmm::conj(PR[i]); - } - - if (mm_is_symmetric(matcode) && (II[i] != J[i]) ) { - A(J[i]-1, II[i]-1) = PR[i]; - } - - if (mm_is_skew(matcode) && (II[i] != J[i]) ) { - A(J[i]-1, II[i]-1) = -PR[i]; - } - } - } - - template void - MatrixMarket_IO::write(const char *filename, const csc_matrix& A) { - write(filename, csc_matrix_ref - (&A.pr[0], &A.ir[0], &A.jc[0], A.nr, A.nc)); - } - - template void - MatrixMarket_IO::write(const char *filename, - const csc_matrix_ref& A) { - gmm::standard_locale sl; - static MM_typecode t1 = {'M', 'C', 'R', 'G'}; - static MM_typecode t2 = {'M', 'C', 'C', 'G'}; - MM_typecode t; - - if (is_complex_double__(T())) std::copy(&(t2[0]), &(t2[0])+4, &(t[0])); - else std::copy(&(t1[0]), &(t1[0])+4, &(t[0])); - size_type nz = A.jc[mat_ncols(A)]; - std::vector II(nz), J(nz); - for (size_type j=0; j < mat_ncols(A); ++j) { - for (size_type i = A.jc[j]; i < A.jc[j+1]; ++i) { - II[i] = A.ir[i] + 1 - shift; - J[i] = int(j + 1); - } - } - mm_write_mtx_crd(filename, int(mat_nrows(A)), int(mat_ncols(A)), - int(nz), &II[0], &J[0], (const double *)A.pr, t); - } - - - template void - MatrixMarket_IO::write(const char *filename, const MAT& A) { - gmm::csc_matrix::value_type> - tmp(gmm::mat_nrows(A), gmm::mat_ncols(A)); - gmm::copy(A,tmp); - MatrixMarket_IO::write(filename, tmp); - } - - template static void vecsave(std::string fname, const VEC& V, - bool binary=false) { - if (binary) { - std::ofstream f(fname.c_str(), std::ofstream::binary); - for (size_type i=0; i < gmm::vect_size(V); ++i) - f.write(reinterpret_cast(&V[i]), sizeof(V[i])); - } - else { - std::ofstream f(fname.c_str()); f.precision(16); f.imbue(std::locale("C")); - for (size_type i=0; i < gmm::vect_size(V); ++i) f << V[i] << "\n"; - } - } - - template static void vecload(std::string fname, const VEC& V_, - bool binary=false) { - VEC &V(const_cast(V_)); - if (binary) { - std::ifstream f(fname.c_str(), std::ifstream::binary); - for (size_type i=0; i < gmm::vect_size(V); ++i) - f.read(reinterpret_cast(&V[i]), sizeof(V[i])); - } - else { - std::ifstream f(fname.c_str()); f.imbue(std::locale("C")); - for (size_type i=0; i < gmm::vect_size(V); ++i) f >> V[i]; - } - } -} - - -#endif // GMM_INOUTPUT_H diff --git a/gmm/gmm_interface.h b/gmm/gmm_interface.h deleted file mode 100644 index a3c66cd1b..000000000 --- a/gmm/gmm_interface.h +++ /dev/null @@ -1,1068 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - - -/**@file gmm_interface.h - @author Yves Renard - @date October 13, 2002. - @brief gmm interface for STL vectors. -*/ - -#ifndef GMM_INTERFACE_H__ -#define GMM_INTERFACE_H__ - -#include "gmm_blas.h" -#include "gmm_sub_index.h" - -namespace gmm { - - /* ********************************************************************* */ - /* */ - /* What is needed for a Vector type : */ - /* Vector v(n) defines a vector with n components. */ - /* v[i] allows to access to the ith component of v. */ - /* linalg_traits should be filled with appropriate definitions */ - /* */ - /* for a dense vector : the minimum is two random iterators (begin and */ - /* end) and a pointer to a valid origin. */ - /* for a sparse vector : the minimum is two forward iterators, with */ - /* a method it.index() which gives the index of */ - /* a non zero element, an interface object */ - /* should describe the method to add new non */ - /* zero element, and a pointer to a valid */ - /* origin. */ - /* */ - /* What is needed for a Matrix type : */ - /* Matrix m(n, m) defines a matrix with n rows and m columns. */ - /* m(i, j) allows to access to the element at row i and column j. */ - /* linalg_traits should be filled with appropriate definitions */ - /* */ - /* What is needed for an iterator on dense vector */ - /* to be standard random access iterator */ - /* */ - /* What is needed for an iterator on a sparse vector */ - /* to be a standard bidirectional iterator */ - /* elt should be sorted with increasing indices. */ - /* it.index() gives the index of the non-zero element. */ - /* */ - /* Remark : If original iterators are not convenient, they could be */ - /* redefined and interfaced in linalg_traits without changing */ - /* the original Vector type. */ - /* */ - /* ********************************************************************* */ - - /* ********************************************************************* */ - /* Simple references on vectors */ - /* ********************************************************************* */ - - template struct simple_vector_ref { - typedef simple_vector_ref this_type; - typedef typename std::iterator_traits::value_type V; - typedef V * CPT; - typedef typename std::iterator_traits::reference ref_V; - typedef typename linalg_traits::iterator iterator; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::porigin_type porigin_type; - - iterator begin_, end_; - porigin_type origin; - size_type size_; - - simple_vector_ref(ref_V v) : begin_(vect_begin(const_cast(v))), - end_(vect_end(const_cast(v))), - origin(linalg_origin(const_cast(v))), - size_(vect_size(v)) {} - - simple_vector_ref(const simple_vector_ref &cr) - : begin_(cr.begin_),end_(cr.end_),origin(cr.origin),size_(cr.size_) {} - - simple_vector_ref(void) {} - - reference operator[](size_type i) const - { return linalg_traits::access(origin, begin_, end_, i); } - }; - - template inline - void set_to_begin(IT &it, ORG o, simple_vector_ref *,linalg_modifiable) { - typedef typename linalg_traits >::V_reference ref_t; - set_to_begin(it, o, PT(), ref_t()); - } - - template inline - void set_to_begin(IT &it, ORG o, const simple_vector_ref *, - linalg_modifiable) { - typedef typename linalg_traits >::V_reference ref_t; - set_to_begin(it, o, PT(), ref_t()); - } - - template inline - void set_to_end(IT &it, ORG o, simple_vector_ref *, linalg_modifiable) { - typedef typename linalg_traits >::V_reference ref_t; - set_to_end(it, o, PT(), ref_t()); - } - - template inline - void set_to_end(IT &it, ORG o, const simple_vector_ref *, - linalg_modifiable) { - typedef typename linalg_traits >::V_reference ref_t; - set_to_end(it, o, PT(), ref_t()); - } - - - template struct linalg_traits > { - typedef simple_vector_ref this_type; - typedef this_type *pthis_type; - typedef typename std::iterator_traits::value_type V; - typedef typename linalg_traits::origin_type origin_type; - typedef V *pV; - typedef typename linalg_traits::is_reference V_reference; - typedef typename which_reference::is_reference is_reference; - typedef abstract_vector linalg_type; - typedef typename linalg_traits::value_type value_type; - typedef typename select_ref::reference, PT>::ref_type reference; - typedef typename select_ref::ref_type porigin_type; - typedef typename select_ref::const_iterator, - typename linalg_traits::iterator, PT>::ref_type iterator; - typedef typename linalg_traits::const_iterator const_iterator; - typedef typename linalg_traits::storage_type storage_type; - typedef linalg_true index_sorted; - static size_type size(const this_type &v) { return v.size_; } - static inline iterator begin(this_type &v) { - iterator it = v.begin_; - set_to_begin(it, v.origin, pthis_type(), is_reference()); - return it; - } - static inline const_iterator begin(const this_type &v) { - const_iterator it = v.begin_; - set_to_begin(it, v.origin, pthis_type(), is_reference()); - return it; - } - static inline iterator end(this_type &v) { - iterator it = v.end_; - set_to_end(it, v.origin, pthis_type(), is_reference()); - return it; - } - static inline const_iterator end(const this_type &v) { - const_iterator it = v.end_; - set_to_end(it, v.origin, pthis_type(), is_reference()); - return it; - } - static origin_type* origin(this_type &v) { return v.origin; } - static const origin_type* origin(const this_type &v) { return v.origin; } - static void clear(origin_type* o, const iterator &it, const iterator &ite) - { linalg_traits::clear(o, it, ite); } - static void do_clear(this_type &v) { clear(v.origin, v.begin_, v.end_); } - static value_type access(const origin_type *o, const const_iterator &it, - const const_iterator &ite, size_type i) - { return linalg_traits::access(o, it, ite, i); } - static reference access(origin_type *o, const iterator &it, - const iterator &ite, size_type i) - { return linalg_traits::access(o, it, ite, i); } - }; - - template - std::ostream &operator << (std::ostream &o, const simple_vector_ref& v) - { gmm::write(o,v); return o; } - - template - simple_vector_ref *> - vref(const std::vector &vv) - { return simple_vector_ref *>(vv); } - - - /* ********************************************************************* */ - /* */ - /* Traits for S.T.L. object */ - /* */ - /* ********************************************************************* */ - - template - struct linalg_traits > { - typedef std::vector this_type; - typedef this_type origin_type; - typedef linalg_false is_reference; - typedef abstract_vector linalg_type; - typedef T value_type; - typedef T& reference; - typedef typename this_type::iterator iterator; - typedef typename this_type::const_iterator const_iterator; - typedef abstract_dense storage_type; - typedef linalg_true index_sorted; - static size_type size(const this_type &v) { return v.size(); } - static iterator begin(this_type &v) { return v.begin(); } - static const_iterator begin(const this_type &v) { return v.begin(); } - static iterator end(this_type &v) { return v.end(); } - static const_iterator end(const this_type &v) { return v.end(); } - static origin_type* origin(this_type &v) { return &v; } - static const origin_type* origin(const this_type &v) { return &v; } - static void clear(origin_type*, const iterator &it, const iterator &ite) - { std::fill(it, ite, value_type(0)); } - static void do_clear(this_type &v) { std::fill(v.begin(), v.end(), T(0)); } - static value_type access(const origin_type *, const const_iterator &it, - const const_iterator &, size_type i) - { return it[i]; } - static reference access(origin_type *, const iterator &it, - const iterator &, size_type i) - { return it[i]; } - static void resize(this_type &v, size_type n) { v.resize(n); } - }; - - - - template - inline size_type nnz(const std::vector& l) { return l.size(); } - - /* ********************************************************************* */ - /* */ - /* Traits for ref objects */ - /* */ - /* ********************************************************************* */ - - template - struct tab_ref_with_origin : public gmm::tab_ref { - typedef tab_ref_with_origin this_type; - // next line replaced by the 4 following lines in order to please aCC - //typedef typename linalg_traits::porigin_type porigin_type; - typedef typename linalg_traits::origin_type origin_type; - typedef typename std::iterator_traits::pointer PT; - typedef typename select_ref::ref_type porigin_type; - - - porigin_type origin; - - tab_ref_with_origin(void) {} - template tab_ref_with_origin(const IT &b, const IT &e, PT p) - : gmm::tab_ref(b,e), origin(porigin_type(p)) {} - tab_ref_with_origin(const IT &b, const IT &e, porigin_type p) - : gmm::tab_ref(b,e), origin(p) {} - - tab_ref_with_origin(const V &v, const sub_interval &si) - : gmm::tab_ref(vect_begin(const_cast(v))+si.min, - vect_begin(const_cast(v))+si.max), - origin(linalg_origin(const_cast(v))) {} - tab_ref_with_origin(V &v, const sub_interval &si) - : gmm::tab_ref(vect_begin(const_cast(v))+si.min, - vect_begin(const_cast(v))+si.max), - origin(linalg_origin(const_cast(v))) {} - }; - - template - struct linalg_traits > { - typedef typename std::iterator_traits::pointer PT; - typedef typename linalg_traits::origin_type origin_type; - typedef tab_ref_with_origin this_type; - typedef typename which_reference::is_reference is_reference; - typedef abstract_vector linalg_type; - typedef typename select_ref::ref_type porigin_type; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::reference reference; - typedef typename this_type::iterator iterator; - typedef typename this_type::iterator const_iterator; - typedef abstract_dense storage_type; - typedef linalg_true index_sorted; - static size_type size(const this_type &v) { return v.size(); } - static iterator begin(this_type &v) { return v.begin(); } - static const_iterator begin(const this_type &v) { return v.begin(); } - static iterator end(this_type &v) { return v.end(); } - static const_iterator end(const this_type &v) { return v.end(); } - static origin_type* origin(this_type &v) { return v.origin; } - static const origin_type* origin(const this_type &v) { return v.origin; } - static void clear(origin_type*, const iterator &it, const iterator &ite) - { std::fill(it, ite, value_type(0)); } - static inline void do_clear(this_type &v) - { std::fill(v.begin(), v.end(), value_type(0)); } - static value_type access(const origin_type *, const const_iterator &it, - const const_iterator &, size_type i) - { return it[i]; } - static reference access(origin_type *, const iterator &it, - const iterator &, size_type i) - { return it[i]; } - }; - - template std::ostream &operator << - (std::ostream &o, const tab_ref_with_origin& m) - { gmm::write(o,m); return o; } - - - template - struct tab_ref_reg_spaced_with_origin : public gmm::tab_ref_reg_spaced { - typedef tab_ref_reg_spaced_with_origin this_type; - typedef typename linalg_traits::porigin_type porigin_type; - - porigin_type origin; - - tab_ref_reg_spaced_with_origin(void) {} - tab_ref_reg_spaced_with_origin(const IT &b, size_type n, size_type s, - const porigin_type p) - : gmm::tab_ref_reg_spaced(b,n,s), origin(p) {} - tab_ref_reg_spaced_with_origin(const V &v, const sub_slice &si) - : gmm::tab_ref_reg_spaced(vect_begin(const_cast(v)) + si.min, - si.N, (si.max - si.min)/si.N), - origin(linalg_origin(const_cast(v))) {} - tab_ref_reg_spaced_with_origin(V &v, const sub_slice &si) - : gmm::tab_ref_reg_spaced(vect_begin(const_cast(v)) + si.min, - si.N, (si.max - si.min)/si.N), - origin(linalg_origin(const_cast(v))) {} - }; - - template - struct linalg_traits > { - typedef typename std::iterator_traits::pointer PT; - typedef tab_ref_reg_spaced_with_origin this_type; - typedef typename linalg_traits::origin_type origin_type; - typedef typename select_ref::ref_type porigin_type; - typedef typename which_reference::is_reference is_reference; - typedef abstract_vector linalg_type; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::reference reference; - typedef typename this_type::iterator iterator; - typedef typename this_type::iterator const_iterator; - typedef abstract_dense storage_type; - typedef linalg_true index_sorted; - static size_type size(const this_type &v) { return v.size(); } - static iterator begin(this_type &v) { return v.begin(); } - static const_iterator begin(const this_type &v) { return v.begin(); } - static iterator end(this_type &v) { return v.end(); } - static const_iterator end(const this_type &v) { return v.end(); } - static origin_type* origin(this_type &v) { return v.origin; } - static const origin_type* origin(const this_type &v) { return v.origin; } - static void clear(origin_type*, const iterator &it, const iterator &ite) - { std::fill(it, ite, value_type(0)); } - static void do_clear(this_type &v) - { std::fill(v.begin(), v.end(), value_type(0)); } - static value_type access(const origin_type *, const const_iterator &it, - const const_iterator &, size_type i) - { return it[i]; } - static reference access(origin_type *, const iterator &it, - const iterator &, size_type i) - { return it[i]; } - }; - - template std::ostream &operator << - (std::ostream &o, const tab_ref_reg_spaced_with_origin& m) - { gmm::write(o,m); return o; } - - - template - struct tab_ref_index_ref_with_origin - : public gmm::tab_ref_index_ref { - typedef tab_ref_index_ref_with_origin this_type; - typedef typename linalg_traits::porigin_type porigin_type; - - porigin_type origin; - - tab_ref_index_ref_with_origin(void) {} - tab_ref_index_ref_with_origin(const IT &b, const ITINDEX &bi, - const ITINDEX &ei, porigin_type p) - : gmm::tab_ref_index_ref(b, bi, ei), origin(p) {} - - tab_ref_index_ref_with_origin(const V &v, const sub_index &si) - : gmm::tab_ref_index_ref(vect_begin(const_cast(v)), - si.begin(), si.end()), - origin(linalg_origin(const_cast(v))) {} - tab_ref_index_ref_with_origin(V &v, const sub_index &si) - : gmm::tab_ref_index_ref(vect_begin(const_cast(v)), - si.begin(), si.end()), - origin(linalg_origin(const_cast(v))) {} - }; - - template - struct linalg_traits > { - typedef typename std::iterator_traits::pointer PT; - typedef tab_ref_index_ref_with_origin this_type; - typedef typename linalg_traits::origin_type origin_type; - typedef typename select_ref::ref_type porigin_type; - typedef typename which_reference::is_reference is_reference; - typedef abstract_vector linalg_type; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::reference reference; - typedef typename this_type::iterator iterator; - typedef typename this_type::iterator const_iterator; - typedef abstract_dense storage_type; - typedef linalg_true index_sorted; - static size_type size(const this_type &v) { return v.size(); } - static iterator begin(this_type &v) { return v.begin(); } - static const_iterator begin(const this_type &v) { return v.begin(); } - static iterator end(this_type &v) { return v.end(); } - static const_iterator end(const this_type &v) { return v.end(); } - static origin_type* origin(this_type &v) { return v.origin; } - static const origin_type* origin(const this_type &v) { return v.origin; } - static void clear(origin_type*, const iterator &it, const iterator &ite) - { std::fill(it, ite, value_type(0)); } - static void do_clear(this_type &v) - { std::fill(v.begin(), v.end(), value_type(0)); } - static value_type access(const origin_type *, const const_iterator &it, - const const_iterator &, size_type i) - { return it[i]; } - static reference access(origin_type *, const iterator &it, - const iterator &, size_type i) - { return it[i]; } - }; - - template - std::ostream &operator << - (std::ostream &o, const tab_ref_index_ref_with_origin& m) - { gmm::write(o,m); return o; } - - - template - struct dense_compressed_iterator { - typedef ITER value_type; - typedef ITER *pointer; - typedef ITER &reference; - typedef ptrdiff_t difference_type; - typedef std::random_access_iterator_tag iterator_category; - typedef size_t size_type; - typedef dense_compressed_iterator iterator; - typedef typename std::iterator_traits::value_type *MPT; - - ITER it; - size_type N, nrows, ncols, i; - PT origin; - - iterator operator ++(int) { iterator tmp = *this; i++; return tmp; } - iterator operator --(int) { iterator tmp = *this; i--; return tmp; } - iterator &operator ++() { ++i; return *this; } - iterator &operator --() { --i; return *this; } - iterator &operator +=(difference_type ii) { i += ii; return *this; } - iterator &operator -=(difference_type ii) { i -= ii; return *this; } - iterator operator +(difference_type ii) const - { iterator itt = *this; return (itt += ii); } - iterator operator -(difference_type ii) const - { iterator itt = *this; return (itt -= ii); } - difference_type operator -(const iterator &ii) const - { return (N ? (it - ii.it) / N : 0) + i - ii.i; } - - ITER operator *() const { return it+i*N; } - ITER operator [](int ii) const { return it + (i+ii) * N; } - - bool operator ==(const iterator &ii) const - { return (*this - ii) == difference_type(0); } - bool operator !=(const iterator &ii) const { return !(ii == *this); } - bool operator < (const iterator &ii) const - { return (*this - ii) < difference_type(0); } - - dense_compressed_iterator(void) {} - dense_compressed_iterator(const dense_compressed_iterator &ii) - : it(ii.it), N(ii.N), nrows(ii.nrows), ncols(ii.ncols), i(ii.i), - origin(ii.origin) {} - dense_compressed_iterator(const ITER &iter, size_type n, size_type r, - size_type c, size_type ii, PT o) - : it(iter), N(n), nrows(r), ncols(c), i(ii), origin(o) { } - - }; - - /* ******************************************************************** */ - /* Read only reference on a compressed sparse vector */ - /* ******************************************************************** */ - - template - struct cs_vector_ref_iterator { - PT1 pr; - PT2 ir; - - typedef typename std::iterator_traits::value_type value_type; - typedef PT1 pointer; - typedef typename std::iterator_traits::reference reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - typedef cs_vector_ref_iterator iterator; - - cs_vector_ref_iterator(void) {} - cs_vector_ref_iterator(PT1 p1, PT2 p2) : pr(p1), ir(p2) {} - - inline size_type index(void) const { return (*ir) - shift; } - iterator &operator ++() { ++pr; ++ir; return *this; } - iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; } - iterator &operator --() { --pr; --ir; return *this; } - iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; } - - reference operator *() const { return *pr; } - pointer operator ->() const { return pr; } - - bool operator ==(const iterator &i) const { return (i.pr==pr);} - bool operator !=(const iterator &i) const { return (i.pr!=pr);} - }; - - template struct cs_vector_ref { - PT1 pr; - PT2 ir; - size_type n, size_; - - typedef cs_vector_ref this_type; - typedef typename std::iterator_traits::value_type value_type; - typedef typename linalg_traits::const_iterator const_iterator; - - cs_vector_ref(PT1 pt1, PT2 pt2, size_type nnz, size_type ns) - : pr(pt1), ir(pt2), n(nnz), size_(ns) {} - cs_vector_ref(void) {} - - size_type size(void) const { return size_; } - - const_iterator begin(void) const { return const_iterator(pr, ir); } - const_iterator end(void) const { return const_iterator(pr+n, ir+n); } - - value_type operator[](size_type i) const - { return linalg_traits::access(pr, begin(), end(),i); } - }; - - template - struct linalg_traits > { - typedef cs_vector_ref this_type; - typedef linalg_const is_reference; - typedef abstract_vector linalg_type; - typedef typename std::iterator_traits::value_type value_type; - typedef value_type origin_type; - typedef typename std::iterator_traits::value_type reference; - typedef cs_vector_ref_iterator::pointer, - typename const_pointer::pointer, shift> const_iterator; - typedef abstract_null_type iterator; - typedef abstract_sparse storage_type; - typedef linalg_true index_sorted; - static size_type size(const this_type &v) { return v.size(); } - static iterator begin(this_type &v) { return v.begin(); } - static const_iterator begin(const this_type &v) { return v.begin(); } - static iterator end(this_type &v) { return v.end(); } - static const_iterator end(const this_type &v) { return v.end(); } - static const origin_type* origin(const this_type &v) { return v.pr; } - static value_type access(const origin_type *, const const_iterator &b, - const const_iterator &e, size_type i) { - if (b.ir == e.ir) return value_type(0); - PT2 p = std::lower_bound(b.ir, e.ir, i+shift); - return (*p == i+shift && p != e.ir) ? b.pr[p-b.ir] : value_type(0); - } - }; - - template - std::ostream &operator << - (std::ostream &o, const cs_vector_ref& m) - { gmm::write(o,m); return o; } - - template - inline size_type nnz(const cs_vector_ref& l) { return l.n; } - - /* ******************************************************************** */ - /* Read only reference on a compressed sparse column matrix */ - /* ******************************************************************** */ - - template - struct sparse_compressed_iterator { - typedef typename std::iterator_traits::value_type value_type; - typedef const value_type *pointer; - typedef const value_type &reference; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - typedef std::random_access_iterator_tag iterator_category; - typedef sparse_compressed_iterator iterator; - - PT1 pr; - PT2 ir; - PT3 jc; - size_type n; - const value_type *origin; - - iterator operator ++(int) { iterator tmp = *this; jc++; return tmp; } - iterator operator --(int) { iterator tmp = *this; jc--; return tmp; } - iterator &operator ++() { jc++; return *this; } - iterator &operator --() { jc--; return *this; } - iterator &operator +=(difference_type i) { jc += i; return *this; } - iterator &operator -=(difference_type i) { jc -= i; return *this; } - iterator operator +(difference_type i) const - { iterator itt = *this; return (itt += i); } - iterator operator -(difference_type i) const - { iterator itt = *this; return (itt -= i); } - difference_type operator -(const iterator &i) const { return jc - i.jc; } - - reference operator *() const { return pr + *jc - shift; } - reference operator [](int ii) { return pr + *(jc+ii) - shift; } - - bool operator ==(const iterator &i) const { return (jc == i.jc); } - bool operator !=(const iterator &i) const { return !(i == *this); } - bool operator < (const iterator &i) const { return (jc < i.jc); } - - sparse_compressed_iterator(void) {} - sparse_compressed_iterator(PT1 p1, PT2 p2, PT3 p3, size_type nn, - const value_type *o) - : pr(p1), ir(p2), jc(p3), n(nn), origin(o) { } - - }; - - template - struct csc_matrix_ref { - PT1 pr; // values. - PT2 ir; // row indexes. - PT3 jc; // column repartition on pr and ir. - size_type nc, nr; - - typedef typename std::iterator_traits::value_type value_type; - csc_matrix_ref(PT1 pt1, PT2 pt2, PT3 pt3, size_type nrr, size_type ncc) - : pr(pt1), ir(pt2), jc(pt3), nc(ncc), nr(nrr) {} - csc_matrix_ref(void) {} - - size_type nrows(void) const { return nr; } - size_type ncols(void) const { return nc; } - - value_type operator()(size_type i, size_type j) const - { return mat_col(*this, j)[i]; } - }; - - template - struct linalg_traits > { - typedef csc_matrix_ref this_type; - typedef linalg_const is_reference; - typedef abstract_matrix linalg_type; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::value_type reference; - typedef value_type origin_type; - typedef abstract_sparse storage_type; - typedef abstract_null_type sub_row_type; - typedef abstract_null_type const_sub_row_type; - typedef abstract_null_type row_iterator; - typedef abstract_null_type const_row_iterator; - typedef abstract_null_type sub_col_type; - typedef cs_vector_ref::pointer, - typename const_pointer::pointer, shift> const_sub_col_type; - typedef sparse_compressed_iterator::pointer, - typename const_pointer::pointer, - typename const_pointer::pointer, - shift> const_col_iterator; - typedef abstract_null_type col_iterator; - typedef col_major sub_orientation; - typedef linalg_true index_sorted; - static size_type nrows(const this_type &m) { return m.nrows(); } - static size_type ncols(const this_type &m) { return m.ncols(); } - static const_col_iterator col_begin(const this_type &m) - { return const_col_iterator(m.pr, m.ir, m.jc, m.nr, m.pr); } - static const_col_iterator col_end(const this_type &m) - { return const_col_iterator(m.pr, m.ir, m.jc + m.nc, m.nr, m.pr); } - static const_sub_col_type col(const const_col_iterator &it) { - return const_sub_col_type(it.pr + *(it.jc) - shift, - it.ir + *(it.jc) - shift, *(it.jc + 1) - *(it.jc), it.n); - } - static const origin_type* origin(const this_type &m) { return m.pr; } - static value_type access(const const_col_iterator &itcol, size_type j) - { return col(itcol)[j]; } - }; - - - template - std::ostream &operator << - (std::ostream &o, const csc_matrix_ref& m) - { gmm::write(o,m); return o; } - - /* ******************************************************************** */ - /* Read only reference on a compressed sparse row matrix */ - /* ******************************************************************** */ - - template - struct csr_matrix_ref { - PT1 pr; // values. - PT2 ir; // column indexes. - PT3 jc; // row repartition on pr and ir. - size_type nc, nr; - - typedef typename std::iterator_traits::value_type value_type; - csr_matrix_ref(PT1 pt1, PT2 pt2, PT3 pt3, size_type nrr, size_type ncc) - : pr(pt1), ir(pt2), jc(pt3), nc(ncc), nr(nrr) {} - csr_matrix_ref(void) {} - - size_type nrows(void) const { return nr; } - size_type ncols(void) const { return nc; } - - value_type operator()(size_type i, size_type j) const - { return mat_row(*this, i)[j]; } - }; - - template - struct linalg_traits > { - typedef csr_matrix_ref this_type; - typedef linalg_const is_reference; - typedef abstract_matrix linalg_type; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::value_type reference; - typedef value_type origin_type; - typedef abstract_sparse storage_type; - typedef abstract_null_type sub_col_type; - typedef abstract_null_type const_sub_col_type; - typedef abstract_null_type col_iterator; - typedef abstract_null_type const_col_iterator; - typedef abstract_null_type sub_row_type; - typedef cs_vector_ref::pointer, - typename const_pointer::pointer, shift> - const_sub_row_type; - typedef sparse_compressed_iterator::pointer, - typename const_pointer::pointer, - typename const_pointer::pointer, - shift> const_row_iterator; - typedef abstract_null_type row_iterator; - typedef row_major sub_orientation; - typedef linalg_true index_sorted; - static size_type nrows(const this_type &m) { return m.nrows(); } - static size_type ncols(const this_type &m) { return m.ncols(); } - static const_row_iterator row_begin(const this_type &m) - { return const_row_iterator(m.pr, m.ir, m.jc, m.nc, m.pr); } - static const_row_iterator row_end(const this_type &m) - { return const_row_iterator(m.pr, m.ir, m.jc + m.nr, m.nc, m.pr); } - static const_sub_row_type row(const const_row_iterator &it) { - return const_sub_row_type(it.pr + *(it.jc) - shift, - it.ir + *(it.jc) - shift, *(it.jc + 1) - *(it.jc), it.n); - } - static const origin_type* origin(const this_type &m) { return m.pr; } - static value_type access(const const_row_iterator &itrow, size_type j) - { return row(itrow)[j]; } - }; - - template - std::ostream &operator << - (std::ostream &o, const csr_matrix_ref& m) - { gmm::write(o,m); return o; } - - /* ********************************************************************* */ - /* */ - /* Simple interface for C arrays */ - /* */ - /* ********************************************************************* */ - - template struct array1D_reference { - - typedef typename std::iterator_traits::value_type value_type; - - PT begin, end; - - const value_type &operator[](size_type i) const { return *(begin+i); } - value_type &operator[](size_type i) { return *(begin+i); } - - array1D_reference(PT begin_, size_type s) : begin(begin_), end(begin_+s) {} - }; - - template - struct linalg_traits > { - typedef array1D_reference this_type; - typedef this_type origin_type; - typedef typename which_reference::is_reference is_reference; - typedef abstract_vector linalg_type; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::reference reference; - typedef PT iterator; - typedef PT const_iterator; - typedef abstract_dense storage_type; - typedef linalg_true index_sorted; - static size_type size(const this_type &v) { return v.end - v.begin; } - static iterator begin(this_type &v) { return v.begin; } - static const_iterator begin(const this_type &v) { return v.begin; } - static iterator end(this_type &v) { return v.end; } - static const_iterator end(const this_type &v) { return v.end; } - static origin_type* origin(this_type &v) { return &v; } - static const origin_type* origin(const this_type &v) { return &v; } - static void clear(origin_type*, const iterator &it, const iterator &ite) - { std::fill(it, ite, value_type(0)); } - static void do_clear(this_type &v) - { std::fill(v.begin, v.end, value_type(0)); } - static value_type access(const origin_type *, const const_iterator &it, - const const_iterator &, size_type i) - { return it[i]; } - static reference access(origin_type *, const iterator &it, - const iterator &, size_type i) - { return it[i]; } - static void resize(this_type &, size_type ) - { GMM_ASSERT1(false, "Not resizable vector"); } - }; - - template std::ostream &operator << - (std::ostream &o, const array1D_reference& v) - { gmm::write(o,v); return o; } - - template struct array2D_col_reference { - - typedef typename std::iterator_traits::value_type T; - typedef typename std::iterator_traits::reference reference; - typedef typename const_reference::reference const_reference; - typedef PT iterator; - typedef typename const_pointer::pointer const_iterator; - - PT begin_; - size_type nbl, nbc; - - inline const_reference operator ()(size_type l, size_type c) const { - GMM_ASSERT2(l < nbl && c < nbc, "out of range"); - return *(begin_ + c*nbl+l); - } - inline reference operator ()(size_type l, size_type c) { - GMM_ASSERT2(l < nbl && c < nbc, "out of range"); - return *(begin_ + c*nbl+l); - } - - void resize(size_type, size_type); - void reshape(size_type m, size_type n) { - GMM_ASSERT2(n*m == nbl*nbc, "dimensions mismatch"); - nbl = m; nbc = n; - } - - void fill(T a, T b = T(0)) { - std::fill(begin_, begin_+nbc*nbl, b); - iterator p = begin_, e = begin_+nbc*nbl; - while (p < e) { *p = a; p += nbl+1; } - } - inline size_type nrows(void) const { return nbl; } - inline size_type ncols(void) const { return nbc; } - - iterator begin(void) { return begin_; } - const_iterator begin(void) const { return begin_; } - iterator end(void) { return begin_+nbl*nbc; } - const_iterator end(void) const { return begin_+nbl*nbc; } - - array2D_col_reference(PT begin__, size_type nrows_, size_type ncols_) - : begin_(begin__), nbl(nrows_), nbc(ncols_) {} - }; - - template struct linalg_traits > { - typedef array2D_col_reference this_type; - typedef this_type origin_type; - typedef typename which_reference::is_reference is_reference; - typedef abstract_matrix linalg_type; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::reference reference; - typedef abstract_dense storage_type; - typedef tab_ref_reg_spaced_with_origin sub_row_type; - typedef tab_ref_reg_spaced_with_origin const_sub_row_type; - typedef dense_compressed_iterator row_iterator; - typedef dense_compressed_iterator const_row_iterator; - typedef tab_ref_with_origin sub_col_type; - typedef tab_ref_with_origin const_sub_col_type; - typedef dense_compressed_iterator col_iterator; - typedef dense_compressed_iterator const_col_iterator; - typedef col_and_row sub_orientation; - typedef linalg_true index_sorted; - static size_type nrows(const this_type &m) { return m.nrows(); } - static size_type ncols(const this_type &m) { return m.ncols(); } - static const_sub_row_type row(const const_row_iterator &it) - { return const_sub_row_type(*it, it.nrows, it.ncols, it.origin); } - static const_sub_col_type col(const const_col_iterator &it) - { return const_sub_col_type(*it, *it + it.nrows, it.origin); } - static sub_row_type row(const row_iterator &it) - { return sub_row_type(*it, it.nrows, it.ncols, it.origin); } - static sub_col_type col(const col_iterator &it) - { return sub_col_type(*it, *it + it.nrows, it.origin); } - static row_iterator row_begin(this_type &m) - { return row_iterator(m.begin(), 1, m.nrows(), m.ncols(), 0, &m); } - static row_iterator row_end(this_type &m) - { return row_iterator(m.begin(), 1, m.nrows(), m.ncols(), m.nrows(), &m); } - static const_row_iterator row_begin(const this_type &m) - { return const_row_iterator(m.begin(), 1, m.nrows(), m.ncols(), 0, &m); } - static const_row_iterator row_end(const this_type &m) { - return const_row_iterator(m.begin(), 1, m.nrows(), - m.ncols(), m.nrows(), &m); - } - static col_iterator col_begin(this_type &m) - { return col_iterator(m.begin(), m.nrows(), m.nrows(), m.ncols(), 0, &m); } - static col_iterator col_end(this_type &m) { - return col_iterator(m.begin(), m.nrows(), m.nrows(), m.ncols(), - m.ncols(), &m); - } - static const_col_iterator col_begin(const this_type &m) { - return const_col_iterator(m.begin(), m.nrows(), m.nrows(), - m.ncols(), 0, &m); - } - static const_col_iterator col_end(const this_type &m) { - return const_col_iterator(m.begin(), m.nrows(),m.nrows(),m.ncols(), - m.ncols(), &m); - } - static origin_type* origin(this_type &m) { return &m; } - static const origin_type* origin(const this_type &m) { return &m; } - static void do_clear(this_type &m) { m.fill(value_type(0)); } - static value_type access(const const_col_iterator &itcol, size_type j) - { return (*itcol)[j]; } - static reference access(const col_iterator &itcol, size_type j) - { return (*itcol)[j]; } - static void resize(this_type &v, size_type m, size_type n) - { v.resize(m,n); } - static void reshape(this_type &v, size_type m, size_type n) - { v.reshape(m, n); } - }; - - template std::ostream &operator << - (std::ostream &o, const array2D_col_reference& m) - { gmm::write(o,m); return o; } - - - - template struct array2D_row_reference { - - typedef typename std::iterator_traits::value_type T; - typedef typename std::iterator_traits::reference reference; - typedef typename const_reference::reference const_reference; - typedef PT iterator; - typedef typename const_pointer::pointer const_iterator; - - PT begin_; - size_type nbl, nbc; - - inline const_reference operator ()(size_type l, size_type c) const { - GMM_ASSERT2(l < nbl && c < nbc, "out of range"); - return *(begin_ + l*nbc+c); - } - inline reference operator ()(size_type l, size_type c) { - GMM_ASSERT2(l < nbl && c < nbc, "out of range"); - return *(begin_ + l*nbc+c); - } - - void resize(size_type, size_type); - void reshape(size_type m, size_type n) { - GMM_ASSERT2(n*m == nbl*nbc, "dimensions mismatch"); - nbl = m; nbc = n; - } - - void fill(T a, T b = T(0)) { - std::fill(begin_, begin_+nbc*nbl, b); - iterator p = begin_, e = begin_+nbc*nbl; - while (p < e) { *p = a; p += nbc+1; } - } - inline size_type nrows(void) const { return nbl; } - inline size_type ncols(void) const { return nbc; } - - iterator begin(void) { return begin_; } - const_iterator begin(void) const { return begin_; } - iterator end(void) { return begin_+nbl*nbc; } - const_iterator end(void) const { return begin_+nbl*nbc; } - - array2D_row_reference(PT begin__, size_type nrows_, size_type ncols_) - : begin_(begin__), nbl(nrows_), nbc(ncols_) {} - }; - - template struct linalg_traits > { - typedef array2D_row_reference this_type; - typedef this_type origin_type; - typedef typename which_reference::is_reference is_reference; - typedef abstract_matrix linalg_type; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::reference reference; - typedef abstract_dense storage_type; - typedef tab_ref_reg_spaced_with_origin sub_col_type; - typedef tab_ref_reg_spaced_with_origin const_sub_col_type; - typedef dense_compressed_iterator col_iterator; - typedef dense_compressed_iterator const_col_iterator; - typedef tab_ref_with_origin sub_row_type; - typedef tab_ref_with_origin const_sub_row_type; - typedef dense_compressed_iterator row_iterator; - typedef dense_compressed_iterator const_row_iterator; - typedef col_and_row sub_orientation; - typedef linalg_true index_sorted; - static size_type ncols(const this_type &m) { return m.ncols(); } - static size_type nrows(const this_type &m) { return m.nrows(); } - static const_sub_col_type col(const const_col_iterator &it) - { return const_sub_col_type(*it, it.ncols, it.nrows, it.origin); } - static const_sub_row_type row(const const_row_iterator &it) - { return const_sub_row_type(*it, *it + it.ncols, it.origin); } - static sub_col_type col(const col_iterator &it) - { return sub_col_type(*it, *it, it.ncols, it.nrows, it.origin); } - static sub_row_type row(const row_iterator &it) - { return sub_row_type(*it, *it + it.ncols, it.origin); } - static col_iterator col_begin(this_type &m) - { return col_iterator(m.begin(), 1, m.ncols(), m.nrows(), 0, &m); } - static col_iterator col_end(this_type &m) - { return col_iterator(m.begin(), 1, m.ncols(), m.nrows(), m.ncols(), &m); } - static const_col_iterator col_begin(const this_type &m) - { return const_col_iterator(m.begin(), 1, m.ncols(), m.nrows(), 0, &m); } - static const_col_iterator col_end(const this_type &m) { - return const_col_iterator(m.begin(), 1, m.ncols(), - m.nrows(), m.ncols(), &m); - } - static row_iterator row_begin(this_type &m) - { return row_iterator(m.begin(), m.ncols(), m.ncols(), m.nrows(), 0, &m); } - static row_iterator row_end(this_type &m) { - return row_iterator(m.begin(), m.ncols(), m.ncols(), m.nrows(), - m.nrows(), &m); - } - static const_row_iterator row_begin(const this_type &m) { - return const_row_iterator(m.begin(), m.ncols(), m.ncols(), m.nrows(), - 0, &m); - } - static const_row_iterator row_end(const this_type &m) { - return const_row_iterator(m.begin(), m.ncols(), m.ncols(), m.nrows(), - m.nrows(), &m); - } - static origin_type* origin(this_type &m) { return &m; } - static const origin_type* origin(const this_type &m) { return &m; } - static void do_clear(this_type &m) { m.fill(value_type(0)); } - static value_type access(const const_row_iterator &itrow, size_type j) - { return (*itrow)[j]; } - static reference access(const row_iterator &itrow, size_type j) - { return (*itrow)[j]; } - static void resize(this_type &v, size_type m, size_type n) - { v.resize(m,n); } - static void reshape(this_type &v, size_type m, size_type n) - { v.reshape(m, n); } - }; - - template std::ostream &operator << - (std::ostream &o, const array2D_row_reference& m) - { gmm::write(o,m); return o; } - - - - - - -} - - -#endif // GMM_INTERFACE_H__ diff --git a/gmm/gmm_interface_bgeot.h b/gmm/gmm_interface_bgeot.h deleted file mode 100644 index d1d0ae3ab..000000000 --- a/gmm/gmm_interface_bgeot.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_interface_bgeot.h - @author Yves Renard - @date October 13, 2002. - @brief interface for bgeot::small_vector -*/ -#ifndef GMM_INTERFACE_BGEOT_H__ -#define GMM_INTERFACE_BGEOT_H__ - - -namespace gmm { - - /* ********************************************************************* */ - /* */ - /* Traits for bgeot objects */ - /* */ - /* ********************************************************************* */ - - template struct linalg_traits > { - typedef bgeot::small_vector this_type; - typedef this_type origin_type; - typedef linalg_false is_reference; - typedef abstract_vector linalg_type; - typedef T value_type; - typedef T& reference; - typedef typename this_type::iterator iterator; - typedef typename this_type::const_iterator const_iterator; - typedef abstract_dense storage_type; - typedef linalg_true index_sorted; - static size_type size(const this_type &v) { return v.size(); } - static iterator begin(this_type &v) { return v.begin(); } - static const_iterator begin(const this_type &v) { return v.begin(); } - static iterator end(this_type &v) { return v.end(); } - static const_iterator end(const this_type &v) { return v.end(); } - static origin_type* origin(this_type &v) { return &v; } - static const origin_type* origin(const this_type &v) { return &v; } - static void clear(origin_type* o, const iterator &it, const iterator &ite) - { std::fill(it, ite, value_type(0)); } - static void do_clear(this_type &v) - { std::fill(v.begin(), v.end(), value_type(0)); } - static value_type access(const origin_type *, const const_iterator &it, - const const_iterator &, size_type i) - { return it[i]; } - static reference access(origin_type *, const iterator &it, - const iterator &, size_type i) - { return it[i]; } - static void resize(this_type &v, size_type n) { v.resize(n); } - }; - -} - - -#endif // GMM_INTERFACE_BGEOT_H__ diff --git a/gmm/gmm_iter.h b/gmm/gmm_iter.h deleted file mode 100644 index e82d270f4..000000000 --- a/gmm/gmm_iter.h +++ /dev/null @@ -1,162 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_iter.h - @author Yves Renard - @date February 10, 2003. - @brief Iteration object. -*/ - -#ifndef GMM_ITER_H__ -#define GMM_ITER_H__ - -#include "gmm_kernel.h" -#include - -namespace gmm { - - /** The Iteration object calculates whether the solution has reached the - desired accuracy, or whether the maximum number of iterations has - been reached. - - The method finished() checks the convergence. The first() - method is used to determine the first iteration of the loop. - */ - class iteration { - protected : - double rhsn; /* Right hand side norm. */ - size_type maxiter; /* Max. number of iterations. */ - int noise; /* if noise > 0 iterations are printed. */ - double resmax; /* maximum residu. */ - double resminreach, resadd; - double diverged_res; /* Threshold beyond which the iterative */ - /* is considered to diverge. */ - size_type nit; /* iteration number. */ - double res; /* last computed residu. */ - std::string name; /* eventually, name of the method. */ - bool written; - void (*callback)(const gmm::iteration&); - public : - - void init(void) { - nit = 0; res = 0.0; written = false; - resminreach = 1E200; resadd = 0.0; - callback = 0; - } - - iteration(double r = 1.0E-8, int noi = 0, size_type mit = size_type(-1), - double div_res = 1E200) - : rhsn(1.0), maxiter(mit), noise(noi), resmax(r), diverged_res(div_res) - { init(); } - - void operator ++(int) { nit++; written = false; resadd += res; } - void operator ++() { (*this)++; } - - bool first(void) { return nit == 0; } - - /* get/set the "noisyness" (verbosity) of the solvers */ - int get_noisy(void) const { return noise; } - void set_noisy(int n) { noise = n; } - void reduce_noisy(void) { if (noise > 0) noise--; } - - double get_resmax(void) const { return resmax; } - void set_resmax(double r) { resmax = r; } - - double get_res() const { return res; } - void enforce_converged(bool c = true) - { if (c) res = double(0); else res = rhsn * resmax + double(1); } - - /* change the user-definable callback, called after each iteration */ - void set_callback(void (*t)(const gmm::iteration&)) { - callback = t; - } - - double get_diverged_residual(void) const { return diverged_res; } - void set_diverged_residual(double r) { diverged_res = r; } - - size_type get_iteration(void) const { return nit; } - void set_iteration(size_type i) { nit = i; } - - size_type get_maxiter(void) const { return maxiter; } - void set_maxiter(size_type i) { maxiter = i; } - - double get_rhsnorm(void) const { return rhsn; } - void set_rhsnorm(double r) { rhsn = r; } - - bool converged(void) { - return !isnan(res) && res <= rhsn * resmax; - } - bool converged(double nr) { - res = gmm::abs(nr); - resminreach = std::min(resminreach, res); - return converged(); - } - template bool converged(const VECT &v) - { return converged(gmm::vect_norm2(v)); } - bool diverged(void) { - return isnan(res) || (nit>=maxiter) - || (res>=rhsn*diverged_res && nit > 4); - } - bool diverged(double nr) { - res = gmm::abs(nr); - resminreach = std::min(resminreach, res); - return diverged(); - } - - bool finished(double nr) { - if (callback) callback(*this); - if (noise > 0 && !written) { - double a = (rhsn == 0) ? 1.0 : rhsn; - converged(nr); - cout << name << " iter " << std::setw(3) << nit << " residual " - << std::setw(12) << gmm::abs(nr) / a; -// if (nit % 100 == 0 && nit > 0) { -// cout << " (residual min " << resminreach / a << " mean val " -// << resadd / (100.0 * a) << " )"; -// resadd = 0.0; -// } - cout << endl; - written = true; - } - return (converged(nr) || diverged(nr)); - } - template bool finished_vect(const VECT &v) - { return finished(double(gmm::vect_norm2(v))); } - - - void set_name(const std::string &n) { name = n; } - const std::string &get_name(void) const { return name; } - - }; - -} - -#endif /* GMM_ITER_H__ */ diff --git a/gmm/gmm_iter_solvers.h b/gmm/gmm_iter_solvers.h deleted file mode 100644 index cb34ef088..000000000 --- a/gmm/gmm_iter_solvers.h +++ /dev/null @@ -1,111 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_iter_solvers.h - @author Yves Renard - @date October 13, 2002. - @brief Include standard gmm iterative solvers (cg, gmres, ...) -*/ -#ifndef GMM_ITER_SOLVERS_H__ -#define GMM_ITER_SOLVERS_H__ - -#include "gmm_iter.h" - - -namespace gmm { - - /** mixed method to find a zero of a real function G, a priori - * between a and b. If the zero is not between a and b, iterations - * of secant are applied. When a convenient interval is found, - * iterations of dichotomie and regula falsi are applied. - */ - template - T find_root(const FUNC &G, T a = T(0), T b = T(1), - T tol = gmm::default_tol(T())) { - T c, Ga = G(a), Gb = G(b), Gc, d; - d = gmm::abs(b - a); -#if 0 - for (int i = 0; i < 4; i++) { /* secant iterations. */ - if (d < tol) return (b + a) / 2.0; - c = b - Gb * (b - a) / (Gb - Ga); Gc = G(c); - a = b; b = c; Ga = Gb; Gb = Gc; - d = gmm::abs(b - a); - } -#endif - while (Ga * Gb > 0.0) { /* secant iterations. */ - if (d < tol) return (b + a) / 2.0; - c = b - Gb * (b - a) / (Gb - Ga); Gc = G(c); - a = b; b = c; Ga = Gb; Gb = Gc; - d = gmm::abs(b - a); - } - - c = std::max(a, b); a = std::min(a, b); b = c; - while (d > tol) { - c = b - (b - a) * (Gb / (Gb - Ga)); /* regula falsi. */ - if (c > b) c = b; - if (c < a) c = a; - Gc = G(c); - if (Gc*Gb > 0) { b = c; Gb = Gc; } else { a = c; Ga = Gc; } - c = (b + a) / 2.0 ; Gc = G(c); /* Dichotomie. */ - if (Gc*Gb > 0) { b = c; Gb = Gc; } else { a = c; Ga = Gc; } - d = gmm::abs(b - a); c = (b + a) / 2.0; if ((c == a) || (c == b)) d = 0.0; - } - return (b + a) / 2.0; - } - -} - -#include "gmm_precond_diagonal.h" -#include "gmm_precond_ildlt.h" -#include "gmm_precond_ildltt.h" -#include "gmm_precond_mr_approx_inverse.h" -#include "gmm_precond_ilu.h" -#include "gmm_precond_ilut.h" -#include "gmm_precond_ilutp.h" - - - -#include "gmm_solver_cg.h" -#include "gmm_solver_bicgstab.h" -#include "gmm_solver_qmr.h" -#include "gmm_solver_constrained_cg.h" -#include "gmm_solver_Schwarz_additive.h" -#include "gmm_modified_gram_schmidt.h" -#include "gmm_tri_solve.h" -#include "gmm_solver_gmres.h" -#include "gmm_solver_bfgs.h" -#include "gmm_least_squares_cg.h" - -// #include "gmm_solver_idgmres.h" - - - -#endif // GMM_ITER_SOLVERS_H__ diff --git a/gmm/gmm_kernel.h b/gmm/gmm_kernel.h deleted file mode 100644 index ebd217610..000000000 --- a/gmm/gmm_kernel.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_kernel.h - @author Yves Renard - @date November 15, 2003. - @brief Include the base gmm files. - */ - -#ifndef GMM_KERNEL_H__ -#define GMM_KERNEL_H__ - -#include "gmm_def.h" -#include "gmm_blas.h" -#include "gmm_real_part.h" -#include "gmm_interface.h" -#include "gmm_sub_vector.h" -#include "gmm_sub_matrix.h" -#include "gmm_vector_to_matrix.h" -#include "gmm_vector.h" -#include "gmm_matrix.h" -#include "gmm_tri_solve.h" -#include "gmm_blas_interface.h" -#include "gmm_lapack_interface.h" - - -#endif // GMM_KERNEL_H__ diff --git a/gmm/gmm_lapack_interface.h b/gmm/gmm_lapack_interface.h deleted file mode 100644 index 24cd78c2d..000000000 --- a/gmm/gmm_lapack_interface.h +++ /dev/null @@ -1,475 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_lapack_interface.h - @author Yves Renard - @date October 7, 2003. - @brief gmm interface for LAPACK -*/ - -#ifndef GMM_LAPACK_INTERFACE_H -#define GMM_LAPACK_INTERFACE_H - -#include "gmm_blas_interface.h" -#include "gmm_dense_lu.h" -#include "gmm_dense_qr.h" - - -#if defined(GMM_USES_LAPACK) - -namespace gmm { - - /* ********************************************************************** */ - /* Operations interfaced for T = float, double, std::complex */ - /* or std::complex : */ - /* */ - /* lu_factor(dense_matrix, std::vector) */ - /* lu_solve(dense_matrix, std::vector, std::vector) */ - /* lu_solve(dense_matrix, std::vector, std::vector, */ - /* std::vector) */ - /* lu_solve_transposed(dense_matrix, std::vector, std::vector,*/ - /* std::vector) */ - /* lu_inverse(dense_matrix) */ - /* lu_inverse(dense_matrix, std::vector, dense_matrix) */ - /* */ - /* qr_factor(dense_matrix, dense_matrix, dense_matrix) */ - /* */ - /* implicit_qr_algorithm(dense_matrix, std::vector) */ - /* implicit_qr_algorithm(dense_matrix, std::vector, */ - /* dense_matrix) */ - /* implicit_qr_algorithm(dense_matrix, std::vector >) */ - /* implicit_qr_algorithm(dense_matrix, std::vector >, */ - /* dense_matrix) */ - /* */ - /* geev_interface_right */ - /* geev_interface_left */ - /* */ - /* schur(dense_matrix, dense_matrix, dense_matrix) */ - /* */ - /* svd(dense_matrix, dense_matrix, dense_matrix, std::vector) */ - /* svd(dense_matrix, dense_matrix, dense_matrix, */ - /* std::vector >) */ - /* */ - /* ********************************************************************** */ - - /* ********************************************************************** */ - /* LAPACK functions used. */ - /* ********************************************************************** */ - - extern "C" { - void sgetrf_(...); void dgetrf_(...); void cgetrf_(...); void zgetrf_(...); - void sgetrs_(...); void dgetrs_(...); void cgetrs_(...); void zgetrs_(...); - void sgetri_(...); void dgetri_(...); void cgetri_(...); void zgetri_(...); - void sgeqrf_(...); void dgeqrf_(...); void cgeqrf_(...); void zgeqrf_(...); - void sorgqr_(...); void dorgqr_(...); void cungqr_(...); void zungqr_(...); - void sormqr_(...); void dormqr_(...); void cunmqr_(...); void zunmqr_(...); - void sgees_ (...); void dgees_ (...); void cgees_ (...); void zgees_ (...); - void sgeev_ (...); void dgeev_ (...); void cgeev_ (...); void zgeev_ (...); - void sgeesx_(...); void dgeesx_(...); void cgeesx_(...); void zgeesx_(...); - void sgesvd_(...); void dgesvd_(...); void cgesvd_(...); void zgesvd_(...); - } - - /* ********************************************************************** */ - /* LU decomposition. */ - /* ********************************************************************** */ - -# define getrf_interface(lapack_name, base_type) inline \ - size_type lu_factor(dense_matrix &A, lapack_ipvt &ipvt){ \ - GMMLAPACK_TRACE("getrf_interface"); \ - long m = long(mat_nrows(A)), n = long(mat_ncols(A)), lda(m), info(-1L); \ - if (m && n) lapack_name(&m, &n, &A(0,0), &lda, ipvt.pfirst(), &info); \ - if ((info & 0xFFFFFFFF00000000L) && !(info & 0x00000000FFFFFFFFL)) \ - /* For compatibility with lapack version with 32 bit integer. */ \ - ipvt.set_to_int32(); \ - return size_type(int(info & 0x00000000FFFFFFFFL)); \ - } - - getrf_interface(sgetrf_, BLAS_S) - getrf_interface(dgetrf_, BLAS_D) - getrf_interface(cgetrf_, BLAS_C) - getrf_interface(zgetrf_, BLAS_Z) - - /* ********************************************************************* */ - /* LU solve. */ - /* ********************************************************************* */ - -# define getrs_interface(f_name, trans1, lapack_name, base_type) inline \ - void f_name(const dense_matrix &A, \ - const lapack_ipvt &ipvt, std::vector &x, \ - const std::vector &b) { \ - GMMLAPACK_TRACE("getrs_interface"); \ - long n = long(mat_nrows(A)), info(0), nrhs(1); \ - gmm::copy(b, x); trans1; \ - if (n) \ - lapack_name(&t,&n,&nrhs,&(A(0,0)),&n,ipvt.pfirst(),&x[0],&n,&info); \ - } - -# define getrs_trans_n const char t = 'N' -# define getrs_trans_t const char t = 'T' - - getrs_interface(lu_solve, getrs_trans_n, sgetrs_, BLAS_S) - getrs_interface(lu_solve, getrs_trans_n, dgetrs_, BLAS_D) - getrs_interface(lu_solve, getrs_trans_n, cgetrs_, BLAS_C) - getrs_interface(lu_solve, getrs_trans_n, zgetrs_, BLAS_Z) - getrs_interface(lu_solve_transposed, getrs_trans_t, sgetrs_, BLAS_S) - getrs_interface(lu_solve_transposed, getrs_trans_t, dgetrs_, BLAS_D) - getrs_interface(lu_solve_transposed, getrs_trans_t, cgetrs_, BLAS_C) - getrs_interface(lu_solve_transposed, getrs_trans_t, zgetrs_, BLAS_Z) - - /* ********************************************************************* */ - /* LU inverse. */ - /* ********************************************************************* */ - -# define getri_interface(lapack_name, base_type) inline \ - void lu_inverse(const dense_matrix &LU, \ - const lapack_ipvt &ipvt, const dense_matrix &A_) { \ - GMMLAPACK_TRACE("getri_interface"); \ - dense_matrix& \ - A = const_cast &>(A_); \ - long n = int(mat_nrows(A)), info(0), lwork(-1); base_type work1; \ - if (n) { \ - gmm::copy(LU, A); \ - lapack_name(&n, &A(0,0), &n, ipvt.pfirst(), &work1, &lwork, &info); \ - lwork = int(gmm::real(work1)); \ - std::vector work(lwork); \ - lapack_name(&n, &A(0,0), &n, ipvt.pfirst(), &work[0], &lwork,&info); \ - } \ - } - - getri_interface(sgetri_, BLAS_S) - getri_interface(dgetri_, BLAS_D) - getri_interface(cgetri_, BLAS_C) - getri_interface(zgetri_, BLAS_Z) - - /* ********************************************************************** */ - /* QR factorization. */ - /* ********************************************************************** */ - -# define geqrf_interface(lapack_name1, base_type) inline \ - void qr_factor(dense_matrix &A){ \ - GMMLAPACK_TRACE("geqrf_interface"); \ - long m = long(mat_nrows(A)), n=long(mat_ncols(A)), info(0), lwork(-1); \ - base_type work1; \ - if (m && n) { \ - std::vector tau(n); \ - lapack_name1(&m, &n, &A(0,0), &m, &tau[0], &work1 , &lwork, &info); \ - lwork = long(gmm::real(work1)); \ - std::vector work(lwork); \ - lapack_name1(&m, &n, &A(0,0), &m, &tau[0], &work[0], &lwork, &info); \ - GMM_ASSERT1(!info, "QR factorization failed"); \ - } \ - } - - geqrf_interface(sgeqrf_, BLAS_S) - geqrf_interface(dgeqrf_, BLAS_D) - // For complex values, housholder vectors are not the same as in - // gmm::lu_factor. Impossible to interface for the moment. - // geqrf_interface(cgeqrf_, BLAS_C) - // geqrf_interface(zgeqrf_, BLAS_Z) - -# define geqrf_interface2(lapack_name1, lapack_name2, base_type) inline \ - void qr_factor(const dense_matrix &A, \ - dense_matrix &Q, dense_matrix &R) { \ - GMMLAPACK_TRACE("geqrf_interface2"); \ - long m = long(mat_nrows(A)), n=long(mat_ncols(A)), info(0), lwork(-1); \ - base_type work1; \ - if (m && n) { \ - std::copy(A.begin(), A.end(), Q.begin()); \ - std::vector tau(n); \ - lapack_name1(&m, &n, &Q(0,0), &m, &tau[0], &work1 , &lwork, &info); \ - lwork = long(gmm::real(work1)); \ - std::vector work(lwork); \ - lapack_name1(&m, &n, &Q(0,0), &m, &tau[0], &work[0], &lwork, &info); \ - GMM_ASSERT1(!info, "QR factorization failed"); \ - base_type *p = &R(0,0), *q = &Q(0,0); \ - for (long j = 0; j < n; ++j, q += m-n) \ - for (long i = 0; i < n; ++i, ++p, ++q) \ - *p = (j < i) ? base_type(0) : *q; \ - lapack_name2(&m, &n, &n, &Q(0,0), &m,&tau[0],&work[0],&lwork,&info); \ - } \ - else gmm::clear(Q); \ - } - - geqrf_interface2(sgeqrf_, sorgqr_, BLAS_S) - geqrf_interface2(dgeqrf_, dorgqr_, BLAS_D) - geqrf_interface2(cgeqrf_, cungqr_, BLAS_C) - geqrf_interface2(zgeqrf_, zungqr_, BLAS_Z) - - /* ********************************************************************** */ - /* QR algorithm for eigenvalues search. */ - /* ********************************************************************** */ - -# define gees_interface(lapack_name, base_type) \ - template inline void implicit_qr_algorithm( \ - const dense_matrix &A, const VECT &eigval_, \ - dense_matrix &Q, \ - double tol=gmm::default_tol(base_type()), bool compvect = true) { \ - GMMLAPACK_TRACE("gees_interface"); \ - typedef bool (*L_fp)(...); L_fp p = 0; \ - long n=long(mat_nrows(A)), info(0), lwork(-1), sdim; base_type work1; \ - if (!n) return; \ - dense_matrix H(n,n); gmm::copy(A, H); \ - char jobvs = (compvect ? 'V' : 'N'), sort = 'N'; \ - std::vector rwork(n), eigv1(n), eigv2(n); \ - lapack_name(&jobvs, &sort, p, &n, &H(0,0), &n, &sdim, &eigv1[0], \ - &eigv2[0], &Q(0,0), &n, &work1, &lwork, &rwork[0], &info); \ - lwork = long(gmm::real(work1)); \ - std::vector work(lwork); \ - lapack_name(&jobvs, &sort, p, &n, &H(0,0), &n, &sdim, &eigv1[0], \ - &eigv2[0], &Q(0,0), &n, &work[0], &lwork, &rwork[0],&info);\ - GMM_ASSERT1(!info, "QR algorithm failed"); \ - extract_eig(H, const_cast(eigval_), tol); \ - } - -# define gees_interface2(lapack_name, base_type) \ - template inline void implicit_qr_algorithm( \ - const dense_matrix &A, const VECT &eigval_, \ - dense_matrix &Q, \ - double tol=gmm::default_tol(base_type()), bool compvect = true) { \ - GMMLAPACK_TRACE("gees_interface2"); \ - typedef bool (*L_fp)(...); L_fp p = 0; \ - long n=long(mat_nrows(A)), info(0), lwork(-1), sdim; base_type work1; \ - if (!n) return; \ - dense_matrix H(n,n); gmm::copy(A, H); \ - char jobvs = (compvect ? 'V' : 'N'), sort = 'N'; \ - std::vector rwork(n), eigvv(n*2); \ - lapack_name(&jobvs, &sort, p, &n, &H(0,0), &n, &sdim, &eigvv[0], \ - &Q(0,0), &n, &work1, &lwork, &rwork[0], &rwork[0], &info); \ - lwork = long(gmm::real(work1)); \ - std::vector work(lwork); \ - lapack_name(&jobvs, &sort, p, &n, &H(0,0), &n, &sdim, &eigvv[0], \ - &Q(0,0), &n, &work[0], &lwork, &rwork[0], &rwork[0],&info);\ - GMM_ASSERT1(!info, "QR algorithm failed"); \ - extract_eig(H, const_cast(eigval_), tol); \ - } - - gees_interface(sgees_, BLAS_S) - gees_interface(dgees_, BLAS_D) - gees_interface2(cgees_, BLAS_C) - gees_interface2(zgees_, BLAS_Z) - - -# define jobv_right char jobvl = 'N', jobvr = 'V'; -# define jobv_left char jobvl = 'V', jobvr = 'N'; - -# define geev_interface(lapack_name, base_type, side) \ - template inline void geev_interface_ ## side( \ - const dense_matrix &A, const VECT &eigval_, \ - dense_matrix &Q) { \ - GMMLAPACK_TRACE("geev_interface"); \ - long n = long(mat_nrows(A)), info(0), lwork(-1); base_type work1; \ - if (!n) return; \ - dense_matrix H(n,n); gmm::copy(A, H); \ - jobv_ ## side \ - std::vector eigvr(n), eigvi(n); \ - lapack_name(&jobvl, &jobvr, &n, &H(0,0), &n, &eigvr[0], &eigvi[0], \ - &Q(0,0), &n, &Q(0,0), &n, &work1, &lwork, &info); \ - lwork = long(gmm::real(work1)); \ - std::vector work(lwork); \ - lapack_name(&jobvl, &jobvr, &n, &H(0,0), &n, &eigvr[0], &eigvi[0], \ - &Q(0,0), &n, &Q(0,0), &n, &work[0], &lwork, &info); \ - GMM_ASSERT1(!info, "QR algorithm failed"); \ - gmm::copy(eigvr, gmm::real_part(const_cast(eigval_))); \ - gmm::copy(eigvi, gmm::imag_part(const_cast(eigval_))); \ - } - -# define geev_interface2(lapack_name, base_type, side) \ - template inline void geev_interface_ ## side( \ - const dense_matrix &A, const VECT &eigval_, \ - dense_matrix &Q) { \ - GMMLAPACK_TRACE("geev_interface"); \ - long n = long(mat_nrows(A)), info(0), lwork(-1); base_type work1; \ - if (!n) return; \ - dense_matrix H(n,n); gmm::copy(A, H); \ - jobv_ ## side \ - std::vector rwork(2*n); \ - std::vector eigv(n); \ - lapack_name(&jobvl, &jobvr, &n, &H(0,0), &n, &eigv[0], &Q(0,0), &n, \ - &Q(0,0), &n, &work1, &lwork, &rwork[0], &info); \ - lwork = long(gmm::real(work1)); \ - std::vector work(lwork); \ - lapack_name(&jobvl, &jobvr, &n, &H(0,0), &n, &eigv[0], &Q(0,0), &n, \ - &Q(0,0), &n, &work[0], &lwork, &rwork[0], &info); \ - GMM_ASSERT1(!info, "QR algorithm failed"); \ - gmm::copy(eigv, const_cast(eigval_)); \ - } - - geev_interface(sgeev_, BLAS_S, right) - geev_interface(dgeev_, BLAS_D, right) - geev_interface2(cgeev_, BLAS_C, right) - geev_interface2(zgeev_, BLAS_Z, right) - - geev_interface(sgeev_, BLAS_S, left) - geev_interface(dgeev_, BLAS_D, left) - geev_interface2(cgeev_, BLAS_C, left) - geev_interface2(zgeev_, BLAS_Z, left) - - - /* ********************************************************************** */ - /* SCHUR algorithm: */ - /* A = Q*S*(Q^T), with Q orthogonal and S upper quasi-triangula */ - /* ********************************************************************** */ - -# define geesx_interface(lapack_name, base_type) inline \ - void schur(dense_matrix &A, \ - dense_matrix &S, \ - dense_matrix &Q) { \ - GMMLAPACK_TRACE("geesx_interface"); \ - long m = long(mat_nrows(A)), n = long(mat_ncols(A)); \ - GMM_ASSERT1(m == n, "Schur decomposition requires square matrix"); \ - char jobvs = 'V', sort = 'N', sense = 'N'; \ - bool select = false; \ - long lwork = 8*n, sdim = 0, liwork = 1; \ - std::vector work(lwork), wr(n), wi(n); \ - std::vector iwork(liwork); \ - std::vector bwork(1); \ - resize(S, n, n); copy(A, S); \ - resize(Q, n, n); \ - base_type rconde(0), rcondv(0); \ - long info(0); \ - lapack_name(&jobvs, &sort, &select, &sense, &n, &S(0,0), &n, \ - &sdim, &wr[0], &wi[0], &Q(0,0), &n, &rconde, &rcondv, \ - &work[0], &lwork, &iwork[0], &liwork, &bwork[0], &info);\ - GMM_ASSERT1(!info, "SCHUR algorithm failed"); \ - } - -# define geesx_interface2(lapack_name, base_type) inline \ - void schur(dense_matrix &A, \ - dense_matrix &S, \ - dense_matrix &Q) { \ - GMMLAPACK_TRACE("geesx_interface"); \ - long m = long(mat_nrows(A)), n = long(mat_ncols(A)); \ - GMM_ASSERT1(m == n, "Schur decomposition requires square matrix"); \ - char jobvs = 'V', sort = 'N', sense = 'N'; \ - bool select = false; \ - long lwork = 8*n, sdim = 0; \ - std::vector rwork(lwork); \ - std::vector work(lwork), w(n); \ - std::vector bwork(1); \ - resize(S, n, n); copy(A, S); \ - resize(Q, n, n); \ - base_type rconde(0), rcondv(0); \ - long info(0); \ - lapack_name(&jobvs, &sort, &select, &sense, &n, &S(0,0), &n, \ - &sdim, &w[0], &Q(0,0), &n, &rconde, &rcondv, \ - &work[0], &lwork, &rwork[0], &bwork[0], &info); \ - GMM_ASSERT1(!info, "SCHUR algorithm failed"); \ - } - - geesx_interface(sgeesx_, BLAS_S) - geesx_interface(dgeesx_, BLAS_D) - geesx_interface2(cgeesx_, BLAS_C) - geesx_interface2(zgeesx_, BLAS_Z) - - template - void schur(const MAT &A_, MAT &S, MAT &Q) { - MAT A(A_); - schur(A, S, Q); - } - - - /* ********************************************************************** */ - /* Interface to SVD. Does not correspond to a Gmm++ functionnality. */ - /* Author : Sebastian Nowozin */ - /* ********************************************************************** */ - -# define gesvd_interface(lapack_name, base_type) inline \ - void svd(dense_matrix &X, \ - dense_matrix &U, \ - dense_matrix &Vtransposed, \ - std::vector &sigma) { \ - GMMLAPACK_TRACE("gesvd_interface"); \ - long m = long(mat_nrows(X)), n = long(mat_ncols(X)); \ - long mn_min = m < n ? m : n; \ - sigma.resize(mn_min); \ - std::vector work(15 * mn_min); \ - long lwork = long(work.size()); \ - resize(U, m, m); \ - resize(Vtransposed, n, n); \ - char job = 'A'; \ - long info(0); \ - lapack_name(&job, &job, &m, &n, &X(0,0), &m, &sigma[0], &U(0,0), \ - &m, &Vtransposed(0,0), &n, &work[0], &lwork, &info); \ - } - -# define cgesvd_interface(lapack_name, base_type, base_type2) inline \ - void svd(dense_matrix &X, \ - dense_matrix &U, \ - dense_matrix &Vtransposed, \ - std::vector &sigma) { \ - GMMLAPACK_TRACE("gesvd_interface"); \ - long m = long(mat_nrows(X)), n = long(mat_ncols(X)); \ - long mn_min = m < n ? m : n; \ - sigma.resize(mn_min); \ - std::vector work(15 * mn_min); \ - std::vector rwork(5 * mn_min); \ - long lwork = long(work.size()); \ - resize(U, m, m); \ - resize(Vtransposed, n, n); \ - char job = 'A'; \ - long info(0); \ - lapack_name(&job, &job, &m, &n, &X(0,0), &m, &sigma[0], &U(0,0), \ - &m, &Vtransposed(0,0), &n, &work[0], &lwork, \ - &rwork[0], &info); \ - } - - gesvd_interface(sgesvd_, BLAS_S) - gesvd_interface(dgesvd_, BLAS_D) - cgesvd_interface(cgesvd_, BLAS_C, BLAS_S) - cgesvd_interface(zgesvd_, BLAS_Z, BLAS_D) - - template - void svd(const MAT &X_, MAT &U, MAT &Vtransposed, VEC &sigma) { - MAT X(X_); - svd(X, U, Vtransposed, sigma); - } - - - - -} - -#else - -namespace gmm -{ -template -void schur(const MAT &A_, MAT &S, MAT &Q) -{ - GMM_ASSERT1(false, "Use of function schur(A,S,Q) requires GetFEM++ " - "to be built with Lapack"); -} - -}// namespace gmm - -#endif // GMM_USES_LAPACK - -#endif // GMM_LAPACK_INTERFACE_H diff --git a/gmm/gmm_least_squares_cg.h b/gmm/gmm_least_squares_cg.h deleted file mode 100644 index 71e446658..000000000 --- a/gmm/gmm_least_squares_cg.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard, Benjamin Schleimer - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_leastsquares_cg.h - @author Benjamin Schleimer - @date January 23, 2007. - @brief Conjugate gradient least squares algorithm. - Algorithm taken from http://www.stat.washington.edu/wxs/Stat538-w05/Notes/conjugate-gradients.pdf page 6 -*/ -#ifndef GMM_LEAST_SQUARES_CG_H__ -#define GMM_LEAST_SQUARES_CG_H__ - -#include "gmm_kernel.h" -#include "gmm_iter.h" -#include "gmm_conjugated.h" - -namespace gmm { - - template - void least_squares_cg(const Matrix& C, Vector1& x, const Vector2& y, - iteration &iter) { - - typedef typename temporary_dense_vector::vector_type temp_vector; - typedef typename linalg_traits::value_type T; - - T rho, rho_1(0), a; - temp_vector p(vect_size(x)), q(vect_size(y)), g(vect_size(x)); - temp_vector r(vect_size(y)); - iter.set_rhsnorm(gmm::sqrt(gmm::abs(vect_hp(y, y)))); - - if (iter.get_rhsnorm() == 0.0) - clear(x); - else { - mult(C, scaled(x, T(-1)), y, r); - mult(conjugated(C), r, g); - rho = vect_hp(g, g); - copy(g, p); - - while (!iter.finished_vect(g)) { - - if (!iter.first()) { - rho = vect_hp(g, g); - add(g, scaled(p, rho / rho_1), p); - } - - mult(C, p, q); - - a = rho / vect_hp(q, q); - add(scaled(p, a), x); - add(scaled(q, -a), r); - // NOTE: how do we minimize the impact to the transpose? - mult(conjugated(C), r, g); - rho_1 = rho; - - ++iter; - } - } - } - - template inline - void least_squares_cg(const Matrix& C, const Vector1& x, const Vector2& y, - iteration &iter) - { least_squares_cg(C, linalg_const_cast(x), y, iter); } -} - - -#endif // GMM_SOLVER_CG_H__ diff --git a/gmm/gmm_matrix.h b/gmm/gmm_matrix.h deleted file mode 100644 index 23fb9d267..000000000 --- a/gmm/gmm_matrix.h +++ /dev/null @@ -1,1199 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/** @file gmm_matrix.h - @author Yves Renard - @date October 13, 2002. - @brief Declaration of some matrix types (gmm::dense_matrix, - gmm::row_matrix, gmm::col_matrix, gmm::csc_matrix, etc.) -*/ - -#ifndef GMM_MATRIX_H__ -#define GMM_MATRIX_H__ - -#include "gmm_vector.h" -#include "gmm_sub_vector.h" -#include "gmm_sub_matrix.h" -#include "gmm_transposed.h" - -namespace gmm -{ - - /* ******************************************************************** */ - /* */ - /* Identity matrix */ - /* */ - /* ******************************************************************** */ - - struct identity_matrix { - template void build_with(const MAT &) {} - }; - - template inline - void add(const identity_matrix&, M &v1) { - size_type n = std::min(gmm::mat_nrows(v1), gmm::mat_ncols(v1)); - for (size_type i = 0; i < n; ++i) - v1(i,i) += typename linalg_traits::value_type(1); - } - template inline - void add(const identity_matrix &II, const M &v1) - { add(II, linalg_const_cast(v1)); } - - template inline - void mult(const identity_matrix&, const V1 &v1, V2 &v2) - { copy(v1, v2); } - template inline - void mult(const identity_matrix&, const V1 &v1, const V2 &v2) - { copy(v1, v2); } - template inline - void mult(const identity_matrix&, const V1 &v1, const V2 &v2, V3 &v3) - { add(v1, v2, v3); } - template inline - void mult(const identity_matrix&, const V1 &v1, const V2 &v2, const V3 &v3) - { add(v1, v2, v3); } - template inline - void left_mult(const identity_matrix&, const V1 &v1, V2 &v2) - { copy(v1, v2); } - template inline - void left_mult(const identity_matrix&, const V1 &v1, const V2 &v2) - { copy(v1, v2); } - template inline - void right_mult(const identity_matrix&, const V1 &v1, V2 &v2) - { copy(v1, v2); } - template inline - void right_mult(const identity_matrix&, const V1 &v1, const V2 &v2) - { copy(v1, v2); } - template inline - void transposed_left_mult(const identity_matrix&, const V1 &v1, V2 &v2) - { copy(v1, v2); } - template inline - void transposed_left_mult(const identity_matrix&, const V1 &v1,const V2 &v2) - { copy(v1, v2); } - template inline - void transposed_right_mult(const identity_matrix&, const V1 &v1, V2 &v2) - { copy(v1, v2); } - template inline - void transposed_right_mult(const identity_matrix&,const V1 &v1,const V2 &v2) - { copy(v1, v2); } - template void copy_ident(const identity_matrix&, M &m) { - size_type i = 0, n = std::min(mat_nrows(m), mat_ncols(m)); - clear(m); - for (; i < n; ++i) m(i,i) = typename linalg_traits::value_type(1); - } - template inline void copy(const identity_matrix&, M &m) - { copy_ident(identity_matrix(), m); } - template inline void copy(const identity_matrix &, const M &m) - { copy_ident(identity_matrix(), linalg_const_cast(m)); } - template inline - typename linalg_traits::value_type - vect_sp(const identity_matrix &, const V1 &v1, const V2 &v2) - { return vect_sp(v1, v2); } - template inline - typename linalg_traits::value_type - vect_hp(const identity_matrix &, const V1 &v1, const V2 &v2) - { return vect_hp(v1, v2); } - template inline bool is_identity(const M&) { return false; } - inline bool is_identity(const identity_matrix&) { return true; } - - /* ******************************************************************** */ - /* */ - /* Row matrix */ - /* */ - /* ******************************************************************** */ - - template class row_matrix { - protected : - std::vector li; /* array of rows. */ - size_type nc; - - public : - - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::value_type value_type; - - row_matrix(size_type r, size_type c) : li(r, V(c)), nc(c) {} - row_matrix(void) : nc(0) {} - reference operator ()(size_type l, size_type c) - { return li[l][c]; } - value_type operator ()(size_type l, size_type c) const - { return li[l][c]; } - - void clear_mat(); - void resize(size_type m, size_type n); - - typename std::vector::iterator begin(void) - { return li.begin(); } - typename std::vector::iterator end(void) - { return li.end(); } - typename std::vector::const_iterator begin(void) const - { return li.begin(); } - typename std::vector::const_iterator end(void) const - { return li.end(); } - - - V& row(size_type i) { return li[i]; } - const V& row(size_type i) const { return li[i]; } - V& operator[](size_type i) { return li[i]; } - const V& operator[](size_type i) const { return li[i]; } - - inline size_type nrows(void) const { return li.size(); } - inline size_type ncols(void) const { return nc; } - - void swap(row_matrix &m) { std::swap(li, m.li); std::swap(nc, m.nc); } - void swap_row(size_type i, size_type j) { std::swap(li[i], li[j]); } - }; - - template void row_matrix::resize(size_type m, size_type n) { - size_type nr = std::min(nrows(), m); - li.resize(m); - for (size_type i=nr; i < m; ++i) gmm::resize(li[i], n); - if (n != nc) { - for (size_type i=0; i < nr; ++i) gmm::resize(li[i], n); - nc = n; - } - } - - - template void row_matrix::clear_mat() - { for (size_type i=0; i < nrows(); ++i) clear(li[i]); } - - template struct linalg_traits > { - typedef row_matrix this_type; - typedef this_type origin_type; - typedef linalg_false is_reference; - typedef abstract_matrix linalg_type; - typedef typename linalg_traits::value_type value_type; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::storage_type storage_type; - typedef V & sub_row_type; - typedef const V & const_sub_row_type; - typedef typename std::vector::iterator row_iterator; - typedef typename std::vector::const_iterator const_row_iterator; - typedef abstract_null_type sub_col_type; - typedef abstract_null_type const_sub_col_type; - typedef abstract_null_type col_iterator; - typedef abstract_null_type const_col_iterator; - typedef row_major sub_orientation; - typedef linalg_true index_sorted; - static size_type nrows(const this_type &m) { return m.nrows(); } - static size_type ncols(const this_type &m) { return m.ncols(); } - static row_iterator row_begin(this_type &m) { return m.begin(); } - static row_iterator row_end(this_type &m) { return m.end(); } - static const_row_iterator row_begin(const this_type &m) - { return m.begin(); } - static const_row_iterator row_end(const this_type &m) - { return m.end(); } - static const_sub_row_type row(const const_row_iterator &it) - { return const_sub_row_type(*it); } - static sub_row_type row(const row_iterator &it) - { return sub_row_type(*it); } - static origin_type* origin(this_type &m) { return &m; } - static const origin_type* origin(const this_type &m) { return &m; } - static void do_clear(this_type &m) { m.clear_mat(); } - static value_type access(const const_row_iterator &itrow, size_type j) - { return (*itrow)[j]; } - static reference access(const row_iterator &itrow, size_type j) - { return (*itrow)[j]; } - static void resize(this_type &v, size_type m, size_type n) - { v.resize(m, n); } - static void reshape(this_type &, size_type, size_type) - { GMM_ASSERT1(false, "Sorry, to be done"); } - }; - - template std::ostream &operator << - (std::ostream &o, const row_matrix& m) { gmm::write(o,m); return o; } - - /* ******************************************************************** */ - /* */ - /* Column matrix */ - /* */ - /* ******************************************************************** */ - - template class col_matrix { - protected : - std::vector li; /* array of columns. */ - size_type nr; - - public : - - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::value_type value_type; - - col_matrix(size_type r, size_type c) : li(c, V(r)), nr(r) { } - col_matrix(void) : nr(0) {} - reference operator ()(size_type l, size_type c) - { return li[c][l]; } - value_type operator ()(size_type l, size_type c) const - { return li[c][l]; } - - void clear_mat(); - void resize(size_type, size_type); - - V& col(size_type i) { return li[i]; } - const V& col(size_type i) const { return li[i]; } - V& operator[](size_type i) { return li[i]; } - const V& operator[](size_type i) const { return li[i]; } - - typename std::vector::iterator begin(void) - { return li.begin(); } - typename std::vector::iterator end(void) - { return li.end(); } - typename std::vector::const_iterator begin(void) const - { return li.begin(); } - typename std::vector::const_iterator end(void) const - { return li.end(); } - - inline size_type ncols(void) const { return li.size(); } - inline size_type nrows(void) const { return nr; } - - void swap(col_matrix &m) { std::swap(li, m.li); std::swap(nr, m.nr); } - void swap_col(size_type i, size_type j) { std::swap(li[i], li[j]); } - }; - - template void col_matrix::resize(size_type m, size_type n) { - size_type nc = std::min(ncols(), n); - li.resize(n); - for (size_type i=nc; i < n; ++i) gmm::resize(li[i], m); - if (m != nr) { - for (size_type i=0; i < nc; ++i) gmm::resize(li[i], m); - nr = m; - } - } - - template void col_matrix::clear_mat() - { for (size_type i=0; i < ncols(); ++i) clear(li[i]); } - - template struct linalg_traits > { - typedef col_matrix this_type; - typedef this_type origin_type; - typedef linalg_false is_reference; - typedef abstract_matrix linalg_type; - typedef typename linalg_traits::value_type value_type; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::storage_type storage_type; - typedef V &sub_col_type; - typedef const V &const_sub_col_type; - typedef typename std::vector::iterator col_iterator; - typedef typename std::vector::const_iterator const_col_iterator; - typedef abstract_null_type sub_row_type; - typedef abstract_null_type const_sub_row_type; - typedef abstract_null_type row_iterator; - typedef abstract_null_type const_row_iterator; - typedef col_major sub_orientation; - typedef linalg_true index_sorted; - static size_type nrows(const this_type &m) { return m.nrows(); } - static size_type ncols(const this_type &m) { return m.ncols(); } - static col_iterator col_begin(this_type &m) { return m.begin(); } - static col_iterator col_end(this_type &m) { return m.end(); } - static const_col_iterator col_begin(const this_type &m) - { return m.begin(); } - static const_col_iterator col_end(const this_type &m) - { return m.end(); } - static const_sub_col_type col(const const_col_iterator &it) - { return *it; } - static sub_col_type col(const col_iterator &it) - { return *it; } - static origin_type* origin(this_type &m) { return &m; } - static const origin_type* origin(const this_type &m) { return &m; } - static void do_clear(this_type &m) { m.clear_mat(); } - static value_type access(const const_col_iterator &itcol, size_type j) - { return (*itcol)[j]; } - static reference access(const col_iterator &itcol, size_type j) - { return (*itcol)[j]; } - static void resize(this_type &v, size_type m, size_type n) - { v.resize(m,n); } - static void reshape(this_type &, size_type, size_type) - { GMM_ASSERT1(false, "Sorry, to be done"); } - }; - - template std::ostream &operator << - (std::ostream &o, const col_matrix& m) { gmm::write(o,m); return o; } - - /* ******************************************************************** */ - /* */ - /* Dense matrix */ - /* */ - /* ******************************************************************** */ - - template class dense_matrix : public std::vector { - public: - typedef typename std::vector::size_type size_type; - typedef typename std::vector::iterator iterator; - typedef typename std::vector::const_iterator const_iterator; - typedef typename std::vector::reference reference; - typedef typename std::vector::const_reference const_reference; - - protected: - size_type nbc, nbl; - - public: - - inline const_reference operator ()(size_type l, size_type c) const { - GMM_ASSERT2(l < nbl && c < nbc, "out of range"); - return *(this->begin() + c*nbl+l); - } - inline reference operator ()(size_type l, size_type c) { - GMM_ASSERT2(l < nbl && c < nbc, "out of range"); - return *(this->begin() + c*nbl+l); - } - - std::vector &as_vector(void) { return *this; } - const std::vector &as_vector(void) const { return *this; } - - void resize(size_type, size_type); - void base_resize(size_type, size_type); - void reshape(size_type, size_type); - - void fill(T a, T b = T(0)); - inline size_type nrows(void) const { return nbl; } - inline size_type ncols(void) const { return nbc; } - void swap(dense_matrix &m) - { std::vector::swap(m); std::swap(nbc, m.nbc); std::swap(nbl, m.nbl); } - - dense_matrix(size_type l, size_type c) - : std::vector(c*l), nbc(c), nbl(l) {} - dense_matrix(void) { nbl = nbc = 0; } - }; - - template void dense_matrix::reshape(size_type m,size_type n) { - GMM_ASSERT2(n*m == nbl*nbc, "dimensions mismatch"); - nbl = m; nbc = n; - } - - template void dense_matrix::base_resize(size_type m, - size_type n) - { std::vector::resize(n*m); nbl = m; nbc = n; } - - template void dense_matrix::resize(size_type m, size_type n) { - if (n*m > nbc*nbl) std::vector::resize(n*m); - if (m < nbl) { - for (size_type i = 1; i < std::min(nbc, n); ++i) - std::copy(this->begin()+i*nbl, this->begin()+(i*nbl+m), - this->begin()+i*m); - for (size_type i = std::min(nbc, n); i < n; ++i) - std::fill(this->begin()+(i*m), this->begin()+(i+1)*m, T(0)); - } - else if (m > nbl) { /* do nothing when the nb of rows does not change */ - for (size_type i = std::min(nbc, n); i > 1; --i) - std::copy(this->begin()+(i-1)*nbl, this->begin()+i*nbl, - this->begin()+(i-1)*m); - for (size_type i = 0; i < std::min(nbc, n); ++i) - std::fill(this->begin()+(i*m+nbl), this->begin()+(i+1)*m, T(0)); - } - if (n*m < nbc*nbl) std::vector::resize(n*m); - nbl = m; nbc = n; - } - - template void dense_matrix::fill(T a, T b) { - std::fill(this->begin(), this->end(), b); - size_type n = std::min(nbl, nbc); - if (a != b) for (size_type i = 0; i < n; ++i) (*this)(i,i) = a; - } - - template struct linalg_traits > { - typedef dense_matrix this_type; - typedef this_type origin_type; - typedef linalg_false is_reference; - typedef abstract_matrix linalg_type; - typedef T value_type; - typedef T& reference; - typedef abstract_dense storage_type; - typedef tab_ref_reg_spaced_with_origin sub_row_type; - typedef tab_ref_reg_spaced_with_origin const_sub_row_type; - typedef dense_compressed_iterator row_iterator; - typedef dense_compressed_iterator const_row_iterator; - typedef tab_ref_with_origin sub_col_type; - typedef tab_ref_with_origin const_sub_col_type; - typedef dense_compressed_iterator col_iterator; - typedef dense_compressed_iterator const_col_iterator; - typedef col_and_row sub_orientation; - typedef linalg_true index_sorted; - static size_type nrows(const this_type &m) { return m.nrows(); } - static size_type ncols(const this_type &m) { return m.ncols(); } - static const_sub_row_type row(const const_row_iterator &it) - { return const_sub_row_type(*it, it.nrows, it.ncols, it.origin); } - static const_sub_col_type col(const const_col_iterator &it) - { return const_sub_col_type(*it, *it + it.nrows, it.origin); } - static sub_row_type row(const row_iterator &it) - { return sub_row_type(*it, it.nrows, it.ncols, it.origin); } - static sub_col_type col(const col_iterator &it) - { return sub_col_type(*it, *it + it.nrows, it.origin); } - static row_iterator row_begin(this_type &m) - { return row_iterator(m.begin(), m.size() ? 1 : 0, m.nrows(), m.ncols(), 0, &m); } - static row_iterator row_end(this_type &m) - { return row_iterator(m.begin(), m.size() ? 1 : 0, m.nrows(), m.ncols(), m.nrows(), &m); } - static const_row_iterator row_begin(const this_type &m) - { return const_row_iterator(m.begin(), m.size() ? 1 : 0, m.nrows(), m.ncols(), 0, &m); } - static const_row_iterator row_end(const this_type &m) - { return const_row_iterator(m.begin(), m.size() ? 1 : 0, m.nrows(), m.ncols(), m.nrows(), &m); } - static col_iterator col_begin(this_type &m) - { return col_iterator(m.begin(), m.nrows(), m.nrows(), m.ncols(), 0, &m); } - static col_iterator col_end(this_type &m) - { return col_iterator(m.begin(), m.nrows(), m.nrows(), m.ncols(), m.ncols(), &m); } - static const_col_iterator col_begin(const this_type &m) - { return const_col_iterator(m.begin(), m.nrows(), m.nrows(), m.ncols(), 0, &m); } - static const_col_iterator col_end(const this_type &m) - { return const_col_iterator(m.begin(),m.nrows(),m.nrows(),m.ncols(),m.ncols(), &m); } - static origin_type* origin(this_type &m) { return &m; } - static const origin_type* origin(const this_type &m) { return &m; } - static void do_clear(this_type &m) { m.fill(value_type(0)); } - static value_type access(const const_col_iterator &itcol, size_type j) - { return (*itcol)[j]; } - static reference access(const col_iterator &itcol, size_type j) - { return (*itcol)[j]; } - static void resize(this_type &v, size_type m, size_type n) - { v.resize(m,n); } - static void reshape(this_type &v, size_type m, size_type n) - { v.reshape(m, n); } - }; - - template std::ostream &operator << - (std::ostream &o, const dense_matrix& m) { gmm::write(o,m); return o; } - - - /* ******************************************************************** */ - /* */ - /* Read only compressed sparse column matrix */ - /* */ - /* ******************************************************************** */ - - template - struct csc_matrix { - typedef unsigned int IND_TYPE; - - std::vector pr; - std::vector ir; - std::vector jc; - size_type nc, nr; - - typedef T value_type; - typedef T& access_type; - - template void init_with_good_format(const Matrix &B); - template void init_with(const Matrix &A); - void init_with(const col_matrix > &B) - { init_with_good_format(B); } - void init_with(const col_matrix > &B) - { init_with_good_format(B); } - template - void init_with(const csc_matrix_ref& B) - { init_with_good_format(B); } - template - void init_with(const csc_matrix& B) - { init_with_good_format(B); } - - void init_with_identity(size_type n); - - csc_matrix(void) : nc(0), nr(0) {} - csc_matrix(size_type nnr, size_type nnc); - - size_type nrows(void) const { return nr; } - size_type ncols(void) const { return nc; } - void swap(csc_matrix &m) { - std::swap(pr, m.pr); - std::swap(ir, m.ir); std::swap(jc, m.jc); - std::swap(nc, m.nc); std::swap(nr, m.nr); - } - value_type operator()(size_type i, size_type j) const - { return mat_col(*this, j)[i]; } - }; - - template template - void csc_matrix::init_with_good_format(const Matrix &B) { - typedef typename linalg_traits::const_sub_col_type col_type; - nc = mat_ncols(B); nr = mat_nrows(B); - jc.resize(nc+1); - jc[0] = shift; - for (size_type j = 0; j < nc; ++j) { - jc[j+1] = IND_TYPE(jc[j] + nnz(mat_const_col(B, j))); - } - pr.resize(jc[nc]); - ir.resize(jc[nc]); - for (size_type j = 0; j < nc; ++j) { - col_type col = mat_const_col(B, j); - typename linalg_traits::t>::const_iterator - it = vect_const_begin(col), ite = vect_const_end(col); - for (size_type k = 0; it != ite; ++it, ++k) { - pr[jc[j]-shift+k] = *it; - ir[jc[j]-shift+k] = IND_TYPE(it.index() + shift); - } - } - } - - template template - void csc_matrix::init_with(const Matrix &A) { - col_matrix > B(mat_nrows(A), mat_ncols(A)); - copy(A, B); - init_with_good_format(B); - } - - template - void csc_matrix::init_with_identity(size_type n) { - nc = nr = n; - pr.resize(nc); ir.resize(nc); jc.resize(nc+1); - for (size_type j = 0; j < nc; ++j) - { ir[j] = jc[j] = shift + j; pr[j] = T(1); } - jc[nc] = shift + nc; - } - - template - csc_matrix::csc_matrix(size_type nnr, size_type nnc) - : nc(nnc), nr(nnr) { - pr.resize(1); ir.resize(1); jc.resize(nc+1); - for (size_type j = 0; j <= nc; ++j) jc[j] = shift; - } - - template - struct linalg_traits > { - typedef csc_matrix this_type; - typedef typename this_type::IND_TYPE IND_TYPE; - typedef linalg_const is_reference; - typedef abstract_matrix linalg_type; - typedef T value_type; - typedef T origin_type; - typedef T reference; - typedef abstract_sparse storage_type; - typedef abstract_null_type sub_row_type; - typedef abstract_null_type const_sub_row_type; - typedef abstract_null_type row_iterator; - typedef abstract_null_type const_row_iterator; - typedef abstract_null_type sub_col_type; - typedef cs_vector_ref - const_sub_col_type; - typedef sparse_compressed_iterator - const_col_iterator; - typedef abstract_null_type col_iterator; - typedef col_major sub_orientation; - typedef linalg_true index_sorted; - static size_type nrows(const this_type &m) { return m.nrows(); } - static size_type ncols(const this_type &m) { return m.ncols(); } - static const_col_iterator col_begin(const this_type &m) - { return const_col_iterator(&m.pr[0],&m.ir[0],&m.jc[0], m.nr, &m.pr[0]); } - static const_col_iterator col_end(const this_type &m) { - return const_col_iterator(&m.pr[0],&m.ir[0],&m.jc[0]+m.nc, - m.nr,&m.pr[0]); - } - static const_sub_col_type col(const const_col_iterator &it) { - return const_sub_col_type(it.pr + *(it.jc) - shift, - it.ir + *(it.jc) - shift, - *(it.jc + 1) - *(it.jc), it.n); - } - static const origin_type* origin(const this_type &m) { return &m.pr[0]; } - static void do_clear(this_type &m) { m.do_clear(); } - static value_type access(const const_col_iterator &itcol, size_type j) - { return col(itcol)[j]; } - }; - - template - std::ostream &operator << - (std::ostream &o, const csc_matrix& m) - { gmm::write(o,m); return o; } - - template - inline void copy(const identity_matrix &, csc_matrix& M) - { M.init_with_identity(mat_nrows(M)); } - - template - inline void copy(const Matrix &A, csc_matrix& M) - { M.init_with(A); } - - /* ******************************************************************** */ - /* */ - /* Read only compressed sparse row matrix */ - /* */ - /* ******************************************************************** */ - - template - struct csr_matrix { - - typedef unsigned int IND_TYPE; - - std::vector pr; // values. - std::vector ir; // col indices. - std::vector jc; // row repartition on pr and ir. - size_type nc, nr; - - typedef T value_type; - typedef T& access_type; - - - template void init_with_good_format(const Matrix &B); - void init_with(const row_matrix > &B) - { init_with_good_format(B); } - void init_with(const row_matrix > &B) - { init_with_good_format(B); } - template - void init_with(const csr_matrix_ref& B) - { init_with_good_format(B); } - template - void init_with(const csr_matrix& B) - { init_with_good_format(B); } - - template void init_with(const Matrix &A); - void init_with_identity(size_type n); - - csr_matrix(void) : nc(0), nr(0) {} - csr_matrix(size_type nnr, size_type nnc); - - size_type nrows(void) const { return nr; } - size_type ncols(void) const { return nc; } - void swap(csr_matrix &m) { - std::swap(pr, m.pr); - std::swap(ir,m.ir); std::swap(jc, m.jc); - std::swap(nc, m.nc); std::swap(nr,m.nr); - } - - value_type operator()(size_type i, size_type j) const - { return mat_row(*this, i)[j]; } - }; - - template template - void csr_matrix::init_with_good_format(const Matrix &B) { - typedef typename linalg_traits::const_sub_row_type row_type; - nc = mat_ncols(B); nr = mat_nrows(B); - jc.resize(nr+1); - jc[0] = shift; - for (size_type j = 0; j < nr; ++j) { - jc[j+1] = IND_TYPE(jc[j] + nnz(mat_const_row(B, j))); - } - pr.resize(jc[nr]); - ir.resize(jc[nr]); - for (size_type j = 0; j < nr; ++j) { - row_type row = mat_const_row(B, j); - typename linalg_traits::t>::const_iterator - it = vect_const_begin(row), ite = vect_const_end(row); - for (size_type k = 0; it != ite; ++it, ++k) { - pr[jc[j]-shift+k] = *it; - ir[jc[j]-shift+k] = IND_TYPE(it.index()+shift); - } - } - } - - template template - void csr_matrix::init_with(const Matrix &A) { - row_matrix > B(mat_nrows(A), mat_ncols(A)); - copy(A, B); - init_with_good_format(B); - } - - template - void csr_matrix::init_with_identity(size_type n) { - nc = nr = n; - pr.resize(nr); ir.resize(nr); jc.resize(nr+1); - for (size_type j = 0; j < nr; ++j) - { ir[j] = jc[j] = shift + j; pr[j] = T(1); } - jc[nr] = shift + nr; - } - - template - csr_matrix::csr_matrix(size_type nnr, size_type nnc) - : nc(nnc), nr(nnr) { - pr.resize(1); ir.resize(1); jc.resize(nr+1); - for (size_type j = 0; j < nr; ++j) jc[j] = shift; - jc[nr] = shift; - } - - - template - struct linalg_traits > { - typedef csr_matrix this_type; - typedef typename this_type::IND_TYPE IND_TYPE; - typedef linalg_const is_reference; - typedef abstract_matrix linalg_type; - typedef T value_type; - typedef T origin_type; - typedef T reference; - typedef abstract_sparse storage_type; - typedef abstract_null_type sub_col_type; - typedef abstract_null_type const_sub_col_type; - typedef abstract_null_type col_iterator; - typedef abstract_null_type const_col_iterator; - typedef abstract_null_type sub_row_type; - typedef cs_vector_ref - const_sub_row_type; - typedef sparse_compressed_iterator - const_row_iterator; - typedef abstract_null_type row_iterator; - typedef row_major sub_orientation; - typedef linalg_true index_sorted; - static size_type nrows(const this_type &m) { return m.nrows(); } - static size_type ncols(const this_type &m) { return m.ncols(); } - static const_row_iterator row_begin(const this_type &m) - { return const_row_iterator(&m.pr[0], &m.ir[0], &m.jc[0], m.nc, &m.pr[0]); } - static const_row_iterator row_end(const this_type &m) - { return const_row_iterator(&m.pr[0], &m.ir[0], &m.jc[0] + m.nr, m.nc, &m.pr[0]); } - static const_sub_row_type row(const const_row_iterator &it) { - return const_sub_row_type(it.pr + *(it.jc) - shift, - it.ir + *(it.jc) - shift, - *(it.jc + 1) - *(it.jc), it.n); - } - static const origin_type* origin(const this_type &m) { return &m.pr[0]; } - static void do_clear(this_type &m) { m.do_clear(); } - static value_type access(const const_row_iterator &itrow, size_type j) - { return row(itrow)[j]; } - }; - - template - std::ostream &operator << - (std::ostream &o, const csr_matrix& m) - { gmm::write(o,m); return o; } - - template - inline void copy(const identity_matrix &, csr_matrix& M) - { M.init_with_identity(mat_nrows(M)); } - - template - inline void copy(const Matrix &A, csr_matrix& M) - { M.init_with(A); } - - /* ******************************************************************** */ - /* */ - /* Block matrix */ - /* */ - /* ******************************************************************** */ - - template class block_matrix { - protected : - std::vector blocks; - size_type nrowblocks_; - size_type ncolblocks_; - std::vector introw, intcol; - - public : - typedef typename linalg_traits::value_type value_type; - typedef typename linalg_traits::reference reference; - - size_type nrows(void) const { return introw[nrowblocks_-1].max; } - size_type ncols(void) const { return intcol[ncolblocks_-1].max; } - size_type nrowblocks(void) const { return nrowblocks_; } - size_type ncolblocks(void) const { return ncolblocks_; } - const sub_interval &subrowinterval(size_type i) const { return introw[i]; } - const sub_interval &subcolinterval(size_type i) const { return intcol[i]; } - const MAT &block(size_type i, size_type j) const - { return blocks[j*ncolblocks_+i]; } - MAT &block(size_type i, size_type j) - { return blocks[j*ncolblocks_+i]; } - void do_clear(void); - // to be done : read and write access to a component - value_type operator() (size_type i, size_type j) const { - size_type k, l; - for (k = 0; k < nrowblocks_; ++k) - if (i >= introw[k].min && i < introw[k].max) break; - for (l = 0; l < nrowblocks_; ++l) - if (j >= introw[l].min && j < introw[l].max) break; - return (block(k, l))(i - introw[k].min, j - introw[l].min); - } - reference operator() (size_type i, size_type j) { - size_type k, l; - for (k = 0; k < nrowblocks_; ++k) - if (i >= introw[k].min && i < introw[k].max) break; - for (l = 0; l < nrowblocks_; ++l) - if (j >= introw[l].min && j < introw[l].max) break; - return (block(k, l))(i - introw[k].min, j - introw[l].min); - } - - template void resize(const CONT &c1, const CONT &c2); - template block_matrix(const CONT &c1, const CONT &c2) - { resize(c1, c2); } - block_matrix(void) {} - - }; - - template struct linalg_traits > { - typedef block_matrix this_type; - typedef linalg_false is_reference; - typedef abstract_matrix linalg_type; - typedef this_type origin_type; - typedef typename linalg_traits::value_type value_type; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::storage_type storage_type; - typedef abstract_null_type sub_row_type; // to be done ... - typedef abstract_null_type const_sub_row_type; // to be done ... - typedef abstract_null_type row_iterator; // to be done ... - typedef abstract_null_type const_row_iterator; // to be done ... - typedef abstract_null_type sub_col_type; // to be done ... - typedef abstract_null_type const_sub_col_type; // to be done ... - typedef abstract_null_type col_iterator; // to be done ... - typedef abstract_null_type const_col_iterator; // to be done ... - typedef abstract_null_type sub_orientation; // to be done ... - typedef linalg_true index_sorted; - static size_type nrows(const this_type &m) { return m.nrows(); } - static size_type ncols(const this_type &m) { return m.ncols(); } - static origin_type* origin(this_type &m) { return &m; } - static const origin_type* origin(const this_type &m) { return &m; } - static void do_clear(this_type &m) { m.do_clear(); } - // access to be done ... - static void resize(this_type &, size_type , size_type) - { GMM_ASSERT1(false, "Sorry, to be done"); } - static void reshape(this_type &, size_type , size_type) - { GMM_ASSERT1(false, "Sorry, to be done"); } - }; - - template void block_matrix::do_clear(void) { - for (size_type j = 0, l = 0; j < ncolblocks_; ++j) - for (size_type i = 0, k = 0; i < nrowblocks_; ++i) - clear(block(i,j)); - } - - template template - void block_matrix::resize(const CONT &c1, const CONT &c2) { - nrowblocks_ = c1.size(); ncolblocks_ = c2.size(); - blocks.resize(nrowblocks_ * ncolblocks_); - intcol.resize(ncolblocks_); - introw.resize(nrowblocks_); - for (size_type j = 0, l = 0; j < ncolblocks_; ++j) { - intcol[j] = sub_interval(l, c2[j]); l += c2[j]; - for (size_type i = 0, k = 0; i < nrowblocks_; ++i) { - if (j == 0) { introw[i] = sub_interval(k, c1[i]); k += c1[i]; } - block(i, j) = MAT(c1[i], c2[j]); - } - } - } - - template - void copy(const block_matrix &m1, M2 &m2) { - for (size_type j = 0; j < m1.ncolblocks(); ++j) - for (size_type i = 0; i < m1.nrowblocks(); ++i) - copy(m1.block(i,j), sub_matrix(m2, m1.subrowinterval(i), - m1.subcolinterval(j))); - } - - template - void copy(const block_matrix &m1, const M2 &m2) - { copy(m1, linalg_const_cast(m2)); } - - - template - void mult(const block_matrix &m, const V1 &v1, V2 &v2) { - clear(v2); - typename sub_vector_type::vector_type sv; - for (size_type i = 0; i < m.nrowblocks() ; ++i) - for (size_type j = 0; j < m.ncolblocks() ; ++j) { - sv = sub_vector(v2, m.subrowinterval(i)); - mult(m.block(i,j), - sub_vector(v1, m.subcolinterval(j)), sv, sv); - } - } - - template - void mult(const block_matrix &m, const V1 &v1, const V2 &v2, V3 &v3) { - typename sub_vector_type::vector_type sv; - for (size_type i = 0; i < m.nrowblocks() ; ++i) - for (size_type j = 0; j < m.ncolblocks() ; ++j) { - sv = sub_vector(v3, m.subrowinterval(i)); - if (j == 0) - mult(m.block(i,j), - sub_vector(v1, m.subcolinterval(j)), - sub_vector(v2, m.subrowinterval(i)), sv); - else - mult(m.block(i,j), - sub_vector(v1, m.subcolinterval(j)), sv, sv); - } - - } - - template - void mult(const block_matrix &m, const V1 &v1, const V2 &v2) - { mult(m, v1, linalg_const_cast(v2)); } - - template - void mult(const block_matrix &m, const V1 &v1, const V2 &v2, - const V3 &v3) - { mult_const(m, v1, v2, linalg_const_cast(v3)); } - -} - /* ******************************************************************** */ - /* */ - /* Distributed matrices */ - /* */ - /* ******************************************************************** */ - -#ifdef GMM_USES_MPI -# include - -namespace gmm { - - - - template inline MPI_Datatype mpi_type(T) - { GMM_ASSERT1(false, "Sorry unsupported type"); return MPI_FLOAT; } - inline MPI_Datatype mpi_type(double) { return MPI_DOUBLE; } - inline MPI_Datatype mpi_type(float) { return MPI_FLOAT; } - inline MPI_Datatype mpi_type(long double) { return MPI_LONG_DOUBLE; } -#ifndef LAM_MPI - inline MPI_Datatype mpi_type(std::complex) { return MPI_COMPLEX; } - inline MPI_Datatype mpi_type(std::complex) { return MPI_DOUBLE_COMPLEX; } -#endif - inline MPI_Datatype mpi_type(int) { return MPI_INT; } - inline MPI_Datatype mpi_type(unsigned int) { return MPI_UNSIGNED; } - inline MPI_Datatype mpi_type(long) { return MPI_LONG; } - inline MPI_Datatype mpi_type(unsigned long) { return MPI_UNSIGNED_LONG; } - - template struct mpi_distributed_matrix { - MAT M; - - mpi_distributed_matrix(size_type n, size_type m) : M(n, m) {} - mpi_distributed_matrix() {} - - const MAT &local_matrix(void) const { return M; } - MAT &local_matrix(void) { return M; } - }; - - template inline MAT &eff_matrix(MAT &m) { return m; } - template inline - const MAT &eff_matrix(const MAT &m) { return m; } - template inline - MAT &eff_matrix(mpi_distributed_matrix &m) { return m.M; } - template inline - const MAT &eff_matrix(const mpi_distributed_matrix &m) { return m.M; } - - - template - inline void copy(const mpi_distributed_matrix &m1, - mpi_distributed_matrix &m2) - { copy(eff_matrix(m1), eff_matrix(m2)); } - template - inline void copy(const mpi_distributed_matrix &m1, - const mpi_distributed_matrix &m2) - { copy(m1.M, m2.M); } - - template - inline void copy(const mpi_distributed_matrix &m1, MAT2 &m2) - { copy(m1.M, m2); } - template - inline void copy(const mpi_distributed_matrix &m1, const MAT2 &m2) - { copy(m1.M, m2); } - - - template inline - typename strongest_value_type3::value_type - vect_sp(const mpi_distributed_matrix &ps, const V1 &v1, - const V2 &v2) { - typedef typename strongest_value_type3::value_type T; - T res = vect_sp(ps.M, v1, v2), rest; - MPI_Allreduce(&res, &rest, 1, mpi_type(T()), MPI_SUM,MPI_COMM_WORLD); - return rest; - } - - template - inline void mult_add(const mpi_distributed_matrix &m, const V1 &v1, - V2 &v2) { - typedef typename linalg_traits::value_type T; - std::vector v3(vect_size(v2)), v4(vect_size(v2)); - static double tmult_tot = 0.0; - static double tmult_tot2 = 0.0; - double t_ref = MPI_Wtime(); - gmm::mult(m.M, v1, v3); - if (is_sparse(v2)) GMM_WARNING2("Using a plain temporary, here."); - double t_ref2 = MPI_Wtime(); - MPI_Allreduce(&(v3[0]), &(v4[0]),gmm::vect_size(v2), mpi_type(T()), - MPI_SUM,MPI_COMM_WORLD); - tmult_tot2 = MPI_Wtime()-t_ref2; - cout << "reduce mult mpi = " << tmult_tot2 << endl; - gmm::add(v4, v2); - tmult_tot = MPI_Wtime()-t_ref; - cout << "tmult mpi = " << tmult_tot << endl; - } - - template - void mult_add(const mpi_distributed_matrix &m, const V1 &v1, - const V2 &v2_) - { mult_add(m, v1, const_cast(v2_)); } - - template - inline void mult(const mpi_distributed_matrix &m, const V1 &v1, - const V2 &v2_) - { V2 &v2 = const_cast(v2_); clear(v2); mult_add(m, v1, v2); } - - template - inline void mult(const mpi_distributed_matrix &m, const V1 &v1, - V2 &v2) - { clear(v2); mult_add(m, v1, v2); } - - template - inline void mult(const mpi_distributed_matrix &m, const V1 &v1, - const V2 &v2, const V3 &v3_) - { V3 &v3 = const_cast(v3_); gmm::copy(v2, v3); mult_add(m, v1, v3); } - - template - inline void mult(const mpi_distributed_matrix &m, const V1 &v1, - const V2 &v2, V3 &v3) - { gmm::copy(v2, v3); mult_add(m, v1, v3); } - - - template inline - size_type mat_nrows(const mpi_distributed_matrix &M) - { return mat_nrows(M.M); } - template inline - size_type mat_ncols(const mpi_distributed_matrix &M) - { return mat_nrows(M.M); } - template inline - void resize(mpi_distributed_matrix &M, size_type m, size_type n) - { resize(M.M, m, n); } - template inline void clear(mpi_distributed_matrix &M) - { clear(M.M); } - - - // For compute reduced system - template inline - void mult(const MAT1 &M1, const mpi_distributed_matrix &M2, - mpi_distributed_matrix &M3) - { mult(M1, M2.M, M3.M); } - template inline - void mult(const mpi_distributed_matrix &M2, - const MAT1 &M1, mpi_distributed_matrix &M3) - { mult(M2.M, M1, M3.M); } - template inline - void mult(const MAT1 &M1, const mpi_distributed_matrix &M2, - MAT3 &M3) - { mult(M1, M2.M, M3); } - template inline - void mult(const MAT1 &M1, const mpi_distributed_matrix &M2, - const MAT3 &M3) - { mult(M1, M2.M, M3); } - - template - struct sub_matrix_type *, SUBI1, SUBI2> - { typedef abstract_null_type matrix_type; }; - - template - struct sub_matrix_type *, SUBI1, SUBI2> - { typedef abstract_null_type matrix_type; }; - - template inline - typename select_return - ::matrix_type, typename sub_matrix_type::matrix_type, - M *>::return_type - sub_matrix(mpi_distributed_matrix &m, const SUBI1 &si1, const SUBI2 &si2) - { return sub_matrix(m.M, si1, si2); } - - template inline - typename select_return - ::matrix_type, typename sub_matrix_type::matrix_type, - const MAT *>::return_type - sub_matrix(const mpi_distributed_matrix &m, const SUBI1 &si1, - const SUBI2 &si2) - { return sub_matrix(m.M, si1, si2); } - - template inline - typename select_return - ::matrix_type, typename sub_matrix_type::matrix_type, - M *>::return_type - sub_matrix(mpi_distributed_matrix &m, const SUBI1 &si1) - { return sub_matrix(m.M, si1, si1); } - - template inline - typename select_return - ::matrix_type, typename sub_matrix_type::matrix_type, - const M *>::return_type - sub_matrix(const mpi_distributed_matrix &m, const SUBI1 &si1) - { return sub_matrix(m.M, si1, si1); } - - - template struct transposed_return *> - { typedef abstract_null_type return_type; }; - template struct transposed_return *> - { typedef abstract_null_type return_type; }; - - template inline typename transposed_return::return_type - transposed(const mpi_distributed_matrix &l) - { return transposed(l.M); } - - template inline typename transposed_return::return_type - transposed(mpi_distributed_matrix &l) - { return transposed(l.M); } - - - template - struct linalg_traits > { - typedef mpi_distributed_matrix this_type; - typedef MAT origin_type; - typedef linalg_false is_reference; - typedef abstract_matrix linalg_type; - typedef typename linalg_traits::value_type value_type; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::storage_type storage_type; - typedef abstract_null_type sub_row_type; - typedef abstract_null_type const_sub_row_type; - typedef abstract_null_type row_iterator; - typedef abstract_null_type const_row_iterator; - typedef abstract_null_type sub_col_type; - typedef abstract_null_type const_sub_col_type; - typedef abstract_null_type col_iterator; - typedef abstract_null_type const_col_iterator; - typedef abstract_null_type sub_orientation; - typedef abstract_null_type index_sorted; - static size_type nrows(const this_type &m) { return nrows(m.M); } - static size_type ncols(const this_type &m) { return ncols(m.M); } - static void do_clear(this_type &m) { clear(m.M); } - }; - -} - - -#endif // GMM_USES_MPI - -namespace std { - template - void swap(gmm::row_matrix &m1, gmm::row_matrix &m2) - { m1.swap(m2); } - template - void swap(gmm::col_matrix &m1, gmm::col_matrix &m2) - { m1.swap(m2); } - template - void swap(gmm::dense_matrix &m1, gmm::dense_matrix &m2) - { m1.swap(m2); } - template void - swap(gmm::csc_matrix &m1, gmm::csc_matrix &m2) - { m1.swap(m2); } - template void - swap(gmm::csr_matrix &m1, gmm::csr_matrix &m2) - { m1.swap(m2); } -} - - - - -#endif /* GMM_MATRIX_H__ */ diff --git a/gmm/gmm_modified_gram_schmidt.h b/gmm/gmm_modified_gram_schmidt.h deleted file mode 100644 index 34d54ae3f..000000000 --- a/gmm/gmm_modified_gram_schmidt.h +++ /dev/null @@ -1,127 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -//=========================================================================== -// -// Copyright (c) 1998-2001, University of Notre Dame. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of Notre Dame nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE TRUSTEES OF INDIANA UNIVERSITY AND -// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES -// OF INDIANA UNIVERSITY AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//=========================================================================== - -/**@file gmm_modified_gram_schmidt.h - @author Andrew Lumsdaine , Lie-Quan Lee - @date October 13, 2002. - @brief Modified Gram-Schmidt orthogonalization -*/ - -#ifndef GMM_MODIFIED_GRAM_SCHMIDT_H -#define GMM_MODIFIED_GRAM_SCHMIDT_H - -#include "gmm_kernel.h" - -namespace gmm { - - template - class modified_gram_schmidt { - protected: - typedef dense_matrix MAT; - MAT M; - - public: - - modified_gram_schmidt(int restart, size_t s) : M(s, restart+1) {} - - typename linalg_traits::const_sub_col_type - operator[](size_t i) const { return mat_const_col(M, i); } - - typename linalg_traits::sub_col_type - operator[](size_t i) { return mat_col(M, i); } - - inline size_type nrows(void) const { return M.nrows(); } - inline size_type ncols(void) const { return M.ncols(); } - MAT &mat(void) { return M; } - const MAT &mat(void) const { return M; } - - }; - - template inline - void orthogonalize(modified_gram_schmidt& V, const VecHi& Hi_, size_t i) { - VecHi& Hi = const_cast(Hi_); - - for (size_t k = 0; k <= i; k++) { - Hi[k] = gmm::vect_hp(V[i+1], V[k]); - gmm::add(gmm::scaled(V[k], -Hi[k]), V[i+1]); - } - } - - template - void orthogonalize_with_refinment(modified_gram_schmidt& V, - const VecHi& Hi_, size_t i) { - VecHi& Hi = const_cast(Hi_); - orthogonalize(V, Hi_, i); - - sub_interval SUBI(0, V.nrows()), SUBJ(0, i+1); - std::vector corr(i+1); - gmm::mult(conjugated(sub_matrix(V.mat(), SUBI, SUBJ)), - V[i+1], corr); - gmm::mult(sub_matrix(V.mat(), SUBI, SUBJ), - scaled(corr, T(-1)), V[i+1],V[i+1]); - gmm::add(corr, sub_vector(Hi, SUBJ)); - } - - template - void combine(modified_gram_schmidt& V, const VecS& s, VecX& x, size_t i) - { for (size_t j = 0; j < i; ++j) gmm::add(gmm::scaled(V[j], s[j]), x); } -} - -#endif diff --git a/gmm/gmm_opt.h b/gmm/gmm_opt.h deleted file mode 100644 index 87b19296a..000000000 --- a/gmm/gmm_opt.h +++ /dev/null @@ -1,131 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_opt.h - @author Yves Renard - @date July 9, 2003. - @brief Optimization for some small cases (inversion of 2x2 matrices etc.) -*/ -#ifndef GMM_OPT_H__ -#define GMM_OPT_H__ - -#include - -namespace gmm { - - /* ********************************************************************* */ - /* Optimized determinant and inverse for small matrices (2x2 and 3x3) */ - /* with dense_matrix. */ - /* ********************************************************************* */ - - template T lu_det(const dense_matrix &A) { - size_type n(mat_nrows(A)); - if (n) { - const T *p = &(A(0,0)); - switch (n) { - case 1 : return (*p); - case 2 : return (*p) * (*(p+3)) - (*(p+1)) * (*(p+2)); -// Not stable for nearly singular matrices -// case 3 : return (*p) * ((*(p+4)) * (*(p+8)) - (*(p+5)) * (*(p+7))) -// - (*(p+1)) * ((*(p+3)) * (*(p+8)) - (*(p+5)) * (*(p+6))) -// + (*(p+2)) * ((*(p+3)) * (*(p+7)) - (*(p+4)) * (*(p+6))); - default : - { - dense_matrix B(mat_nrows(A), mat_ncols(A)); - lapack_ipvt ipvt(mat_nrows(A)); - gmm::copy(A, B); - lu_factor(B, ipvt); - return lu_det(B, ipvt); - } - } - } - return T(1); - } - - - template T lu_inverse(const dense_matrix &A_, - bool doassert = true) { - dense_matrix& A = const_cast &>(A_); - size_type N = mat_nrows(A); - T det(1); - if (N) { - T *p = &(A(0,0)); - switch (N) { - case 1 : { - det = *p; - if (doassert) GMM_ASSERT1(det!=T(0), "non invertible matrix"); - if (det == T(0)) break; - *p = T(1) / det; - } break; - case 2 : { - det = (*p) * (*(p+3)) - (*(p+1)) * (*(p+2)); - if (doassert) GMM_ASSERT1(det!=T(0), "non invertible matrix"); - if (det == T(0)) break; - std::swap(*p, *(p+3)); - *p++ /= det; *p++ /= -det; *p++ /= -det; *p++ /= det; - } break; - case 3 : { // not stable for nearly singular matrices - T a, b, c, d, e, f, g, h, i; - a = (*(p+4)) * (*(p+8)) - (*(p+5)) * (*(p+7)); - b = - (*(p+1)) * (*(p+8)) + (*(p+2)) * (*(p+7)); - c = (*(p+1)) * (*(p+5)) - (*(p+2)) * (*(p+4)); - d = - (*(p+3)) * (*(p+8)) + (*(p+5)) * (*(p+6)); - e = (*(p+0)) * (*(p+8)) - (*(p+2)) * (*(p+6)); - f = - (*(p+0)) * (*(p+5)) + (*(p+2)) * (*(p+3)); - g = (*(p+3)) * (*(p+7)) - (*(p+4)) * (*(p+6)); - h = - (*(p+0)) * (*(p+7)) + (*(p+1)) * (*(p+6)); - i = (*(p+0)) * (*(p+4)) - (*(p+1)) * (*(p+3)); - det = (*p) * a + (*(p+1)) * d + (*(p+2)) * g; - if (std::abs(det) > 1e-5) { - *p++ = a / det; *p++ = b / det; *p++ = c / det; - *p++ = d / det; *p++ = e / det; *p++ = f / det; - *p++ = g / det; *p++ = h / det; *p++ = i / det; - break; - } - } - default : { - dense_matrix B(mat_nrows(A), mat_ncols(A)); - lapack_ipvt ipvt(mat_nrows(A)); - gmm::copy(A, B); - size_type info = lu_factor(B, ipvt); - GMM_ASSERT1(!info, "non invertible matrix"); - lu_inverse(B, ipvt, A); - return lu_det(B, ipvt); - } - } - } - return det; - } - - -} - -#endif // GMM_OPT_H__ diff --git a/gmm/gmm_precond.h b/gmm/gmm_precond.h deleted file mode 100644 index fca4f35d4..000000000 --- a/gmm/gmm_precond.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2004-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ -#ifndef GMM_PRECOND_H -#define GMM_PRECOND_H - -#include "gmm_kernel.h" - -/** @file gmm_precond.h - @author Yves Renard - @date March 29, 2004. - @brief gmm preconditioners. - */ - -/* Preconditioner concept : */ -/* */ -/* A the matrix, P the preconditioner PA well conditioned. */ -/* PRECOND precontioner type. */ -/* mult(P, v, w) : w <- P v */ -/* transposed_mult(P, v, w) : w <- transposed(P) v */ -/* left_mult(P, v, w) : see qmr solver */ -/* right_mult(P, v, w) : see qmr solver */ -/* transposed_left_mult(P, v, w) : see qmr solver */ -/* transposed_right_mult(P, v, w) : see qmr solver */ -/* */ -/* PRECOND P() : empty preconditioner. */ -/* PRECOND P(A, ...) : preconditioner for the matrix A, with optional */ -/* parameters */ -/* PRECOND(...) : empty precondtioner with parameters set. */ -/* P.build_with(A) : build a precondtioner for A. */ -/* */ -/* *********************************************************************** */ - - - - -#endif - diff --git a/gmm/gmm_precond_diagonal.h b/gmm/gmm_precond_diagonal.h deleted file mode 100644 index 19d46095b..000000000 --- a/gmm/gmm_precond_diagonal.h +++ /dev/null @@ -1,132 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_precond_diagonal.h - @author Yves Renard - @date June 5, 2003. - @brief Diagonal matrix preconditoner. -*/ - -#ifndef GMM_PRECOND_DIAGONAL_H -#define GMM_PRECOND_DIAGONAL_H - -#include "gmm_precond.h" - -namespace gmm { - - /** Diagonal preconditioner. */ - template struct diagonal_precond { - typedef typename linalg_traits::value_type value_type; - typedef typename number_traits::magnitude_type magnitude_type; - - std::vector diag; - - void build_with(const Matrix &M) { - diag.resize(mat_nrows(M)); - for (size_type i = 0; i < mat_nrows(M); ++i) { - magnitude_type x = gmm::abs(M(i, i)); - if (x == magnitude_type(0)) { - x = magnitude_type(1); - GMM_WARNING2("The matrix has a zero on its diagonal"); - } - diag[i] = magnitude_type(1) / x; - } - } - size_type memsize() const { return sizeof(*this) + diag.size() * sizeof(value_type); } - diagonal_precond(const Matrix &M) { build_with(M); } - diagonal_precond(void) {} - }; - - template inline - void mult_diag_p(const diagonal_precond& P, V2 &v2, abstract_sparse){ - typename linalg_traits::iterator it = vect_begin(v2), - ite = vect_end(v2); - for (; it != ite; ++it) *it *= P.diag[it.index()]; - } - - template inline - void mult_diag_p(const diagonal_precond& P,V2 &v2, abstract_skyline) - { mult_diag_p(P, v2, abstract_sparse()); } - - template inline - void mult_diag_p(const diagonal_precond& P, V2 &v2, abstract_dense){ - for (size_type i = 0; i < P.diag.size(); ++i) v2[i] *= P.diag[i]; - } - - template inline - void mult(const diagonal_precond& P, const V1 &v1, V2 &v2) { - GMM_ASSERT2(P.diag.size() == vect_size(v2),"dimensions mismatch"); - copy(v1, v2); - mult_diag_p(P, v2, typename linalg_traits::storage_type()); - } - - template inline - void transposed_mult(const diagonal_precond& P,const V1 &v1,V2 &v2) { - mult(P, v1, v2); - } - - // # define DIAG_LEFT_MULT_SQRT - - template inline - void left_mult(const diagonal_precond& P, const V1 &v1, V2 &v2) { - GMM_ASSERT2(P.diag.size() == vect_size(v2), "dimensions mismatch"); - copy(v1, v2); -# ifdef DIAG_LEFT_MULT_SQRT - for (size_type i= 0; i < P.diag.size(); ++i) v2[i] *= gmm::sqrt(P.diag[i]); -# else - for (size_type i= 0; i < P.diag.size(); ++i) v2[i] *= P.diag[i]; -# endif - } - - template inline - void transposed_left_mult(const diagonal_precond& P, - const V1 &v1, V2 &v2) - { left_mult(P, v1, v2); } - - template inline - void right_mult(const diagonal_precond& P, const V1 &v1, V2 &v2) { - // typedef typename linalg_traits::value_type T; - GMM_ASSERT2(P.diag.size() == vect_size(v2), "dimensions mismatch"); - copy(v1, v2); -# ifdef DIAG_LEFT_MULT_SQRT - for (size_type i= 0; i < P.diag.size(); ++i) v2[i] *= gmm::sqrt(P.diag[i]); -# endif - } - - template inline - void transposed_right_mult(const diagonal_precond& P, - const V1 &v1, V2 &v2) - { right_mult(P, v1, v2); } - -} - -#endif - diff --git a/gmm/gmm_precond_ildlt.h b/gmm/gmm_precond_ildlt.h deleted file mode 100644 index 22484df73..000000000 --- a/gmm/gmm_precond_ildlt.h +++ /dev/null @@ -1,241 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -// This file is a modified version of cholesky.h from ITL. -// See http://osl.iu.edu/research/itl/ -// Following the corresponding Copyright notice. -//=========================================================================== -// -// Copyright (c) 1998-2001, University of Notre Dame. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of Notre Dame nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE TRUSTEES OF INDIANA UNIVERSITY AND -// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES -// OF INDIANA UNIVERSITY AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//=========================================================================== - -#ifndef GMM_PRECOND_ILDLT_H -#define GMM_PRECOND_ILDLT_H - -/**@file gmm_precond_ildlt.h - @author Andrew Lumsdaine - @author Lie-Quan Lee - @author Yves Renard - @date June 5, 2003. - @brief Incomplete Level 0 ILDLT Preconditioner. -*/ - -#include "gmm_precond.h" - -namespace gmm { - - /** Incomplete Level 0 LDLT Preconditioner. - - For use with symmetric real or hermitian complex sparse matrices. - - Notes: The idea under a concrete Preconditioner such as Incomplete - Cholesky is to create a Preconditioner object to use in iterative - methods. - - - Y. Renard : Transformed in LDLT for stability reason. - - U=LT is stored in csr format. D is stored on the diagonal of U. - */ - template - class ildlt_precond { - - public : - typedef typename linalg_traits::value_type value_type; - typedef typename number_traits::magnitude_type magnitude_type; - typedef csr_matrix_ref tm_type; - - tm_type U; - - protected : - std::vector Tri_val; - std::vector Tri_ind, Tri_ptr; - - template void do_ildlt(const M& A, row_major); - void do_ildlt(const Matrix& A, col_major); - - public: - - size_type nrows(void) const { return mat_nrows(U); } - size_type ncols(void) const { return mat_ncols(U); } - value_type &D(size_type i) { return Tri_val[Tri_ptr[i]]; } - const value_type &D(size_type i) const { return Tri_val[Tri_ptr[i]]; } - ildlt_precond(void) {} - void build_with(const Matrix& A) { - Tri_ptr.resize(mat_nrows(A)+1); - do_ildlt(A, typename principal_orientation_type::sub_orientation>::potype()); - } - ildlt_precond(const Matrix& A) { build_with(A); } - size_type memsize() const { - return sizeof(*this) + - Tri_val.size() * sizeof(value_type) + - (Tri_ind.size()+Tri_ptr.size()) * sizeof(size_type); - } - }; - - template template - void ildlt_precond::do_ildlt(const M& A, row_major) { - typedef typename linalg_traits::storage_type store_type; - typedef value_type T; - typedef typename number_traits::magnitude_type R; - - size_type Tri_loc = 0, n = mat_nrows(A), d, g, h, i, j, k; - if (n == 0) return; - T z, zz; - Tri_ptr[0] = 0; - R prec = default_tol(R()); - R max_pivot = gmm::abs(A(0,0)) * prec; - - for (int count = 0; count < 2; ++count) { - if (count) { Tri_val.resize(Tri_loc); Tri_ind.resize(Tri_loc); } - for (Tri_loc = 0, i = 0; i < n; ++i) { - typedef typename linalg_traits::const_sub_row_type row_type; - row_type row = mat_const_row(A, i); - typename linalg_traits::t>::const_iterator - it = vect_const_begin(row), ite = vect_const_end(row); - - if (count) { Tri_val[Tri_loc] = T(0); Tri_ind[Tri_loc] = i; } - ++Tri_loc; // diagonal element - - for (k = 0; it != ite; ++it, ++k) { - j = index_of_it(it, k, store_type()); - if (i == j) { - if (count) Tri_val[Tri_loc-1] = *it; - } - else if (j > i) { - if (count) { Tri_val[Tri_loc] = *it; Tri_ind[Tri_loc]=j; } - ++Tri_loc; - } - } - Tri_ptr[i+1] = Tri_loc; - } - } - - if (A(0,0) == T(0)) { - Tri_val[Tri_ptr[0]] = T(1); - GMM_WARNING2("pivot 0 is too small"); - } - - for (k = 0; k < n; k++) { - d = Tri_ptr[k]; - z = T(gmm::real(Tri_val[d])); Tri_val[d] = z; - if (gmm::abs(z) <= max_pivot) { - Tri_val[d] = z = T(1); - GMM_WARNING2("pivot " << k << " is too small [" << gmm::abs(z) << "]"); - } - max_pivot = std::max(max_pivot, std::min(gmm::abs(z) * prec, R(1))); - - for (i = d + 1; i < Tri_ptr[k+1]; ++i) Tri_val[i] /= z; - for (i = d + 1; i < Tri_ptr[k+1]; ++i) { - zz = gmm::conj(Tri_val[i] * z); - h = Tri_ind[i]; - g = i; - - for (j = Tri_ptr[h] ; j < Tri_ptr[h+1]; ++j) - for ( ; g < Tri_ptr[k+1] && Tri_ind[g] <= Tri_ind[j]; ++g) - if (Tri_ind[g] == Tri_ind[j]) - Tri_val[j] -= zz * Tri_val[g]; - } - } - U = tm_type(&(Tri_val[0]), &(Tri_ind[0]), &(Tri_ptr[0]), - n, mat_ncols(A)); - } - - template - void ildlt_precond::do_ildlt(const Matrix& A, col_major) - { do_ildlt(gmm::conjugated(A), row_major()); } - - template inline - void mult(const ildlt_precond& P, const V1 &v1, V2 &v2) { - gmm::copy(v1, v2); - gmm::lower_tri_solve(gmm::conjugated(P.U), v2, true); - for (size_type i = 0; i < mat_nrows(P.U); ++i) v2[i] /= P.D(i); - gmm::upper_tri_solve(P.U, v2, true); - } - - template inline - void transposed_mult(const ildlt_precond& P,const V1 &v1,V2 &v2) - { mult(P, v1, v2); } - - template inline - void left_mult(const ildlt_precond& P, const V1 &v1, V2 &v2) { - copy(v1, v2); - gmm::lower_tri_solve(gmm::conjugated(P.U), v2, true); - for (size_type i = 0; i < mat_nrows(P.U); ++i) v2[i] /= P.D(i); - } - - template inline - void right_mult(const ildlt_precond& P, const V1 &v1, V2 &v2) - { copy(v1, v2); gmm::upper_tri_solve(P.U, v2, true); } - - template inline - void transposed_left_mult(const ildlt_precond& P, const V1 &v1, - V2 &v2) { - copy(v1, v2); - gmm::upper_tri_solve(P.U, v2, true); - for (size_type i = 0; i < mat_nrows(P.U); ++i) v2[i] /= P.D(i); - } - - template inline - void transposed_right_mult(const ildlt_precond& P, const V1 &v1, - V2 &v2) - { copy(v1, v2); gmm::lower_tri_solve(gmm::conjugated(P.U), v2, true); } - - -} - -#endif - diff --git a/gmm/gmm_precond_ildltt.h b/gmm/gmm_precond_ildltt.h deleted file mode 100644 index 380106a40..000000000 --- a/gmm/gmm_precond_ildltt.h +++ /dev/null @@ -1,174 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_precond_ildltt.h - @author Yves Renard - @date June 30, 2003. - @brief incomplete LDL^t (cholesky) preconditioner with fill-in and threshold. -*/ - -#ifndef GMM_PRECOND_ILDLTT_H -#define GMM_PRECOND_ILDLTT_H - -// Store U = LT and D in indiag. On each line, the fill-in is the number -// of non-zero elements on the line of the original matrix plus K, except if -// the matrix is dense. In this case the fill-in is K on each line. - -#include "gmm_precond_ilut.h" - -namespace gmm { - /** incomplete LDL^t (cholesky) preconditioner with fill-in and - threshold. */ - template - class ildltt_precond { - public : - typedef typename linalg_traits::value_type value_type; - typedef typename number_traits::magnitude_type magnitude_type; - - typedef rsvector svector; - - row_matrix U; - std::vector indiag; - - protected: - size_type K; - double eps; - - template void do_ildltt(const M&, row_major); - void do_ildltt(const Matrix&, col_major); - - public: - void build_with(const Matrix& A, int k_ = -1, double eps_ = double(-1)) { - if (k_ >= 0) K = k_; - if (eps_ >= double(0)) eps = eps_; - gmm::resize(U, mat_nrows(A), mat_ncols(A)); - indiag.resize(std::min(mat_nrows(A), mat_ncols(A))); - do_ildltt(A, typename principal_orientation_type::sub_orientation>::potype()); - } - ildltt_precond(const Matrix& A, int k_, double eps_) - : U(mat_nrows(A),mat_ncols(A)), K(k_), eps(eps_) { build_with(A); } - ildltt_precond(void) { K=10; eps = 1E-7; } - ildltt_precond(size_type k_, double eps_) : K(k_), eps(eps_) {} - size_type memsize() const { - return sizeof(*this) + nnz(U)*sizeof(value_type) + indiag.size() * sizeof(magnitude_type); - } - }; - - template template - void ildltt_precond::do_ildltt(const M& A,row_major) { - typedef value_type T; - typedef typename number_traits::magnitude_type R; - - size_type n = mat_nrows(A); - if (n == 0) return; - svector w(n); - T tmp; - R prec = default_tol(R()), max_pivot = gmm::abs(A(0,0)) * prec; - - gmm::clear(U); - for (size_type i = 0; i < n; ++i) { - gmm::copy(mat_const_row(A, i), w); - double norm_row = gmm::vect_norm2(w); - - for (size_type krow = 0, k; krow < w.nb_stored(); ++krow) { - typename svector::iterator wk = w.begin() + krow; - if ((k = wk->c) >= i) break; - if (gmm::is_complex(wk->e)) { - tmp = gmm::conj(U(k, i))/indiag[k]; // not completely satisfactory .. - gmm::add(scaled(mat_row(U, k), -tmp), w); - } - else { - tmp = wk->e; - if (gmm::abs(tmp) < eps * norm_row) { w.sup(k); --krow; } - else { wk->e += tmp; gmm::add(scaled(mat_row(U, k), -tmp), w); } - } - } - tmp = w[i]; - - if (gmm::abs(gmm::real(tmp)) <= max_pivot) - { GMM_WARNING2("pivot " << i << " is too small"); tmp = T(1); } - - max_pivot = std::max(max_pivot, std::min(gmm::abs(tmp) * prec, R(1))); - indiag[i] = R(1) / gmm::real(tmp); - gmm::clean(w, eps * norm_row); - gmm::scale(w, T(indiag[i])); - std::sort(w.begin(), w.end(), elt_rsvector_value_less_()); - typename svector::const_iterator wit = w.begin(), wite = w.end(); - for (size_type nnu = 0; wit != wite; ++wit) // copy to be optimized ... - if (wit->c > i) { if (nnu < K) { U(i, wit->c) = wit->e; ++nnu; } } - } - } - - template - void ildltt_precond::do_ildltt(const Matrix& A, col_major) - { do_ildltt(gmm::conjugated(A), row_major()); } - - template inline - void mult(const ildltt_precond& P, const V1 &v1, V2 &v2) { - gmm::copy(v1, v2); - gmm::lower_tri_solve(gmm::conjugated(P.U), v2, true); - for (size_type i = 0; i < P.indiag.size(); ++i) v2[i] *= P.indiag[i]; - gmm::upper_tri_solve(P.U, v2, true); - } - - template inline - void transposed_mult(const ildltt_precond& P,const V1 &v1, V2 &v2) - { mult(P, v1, v2); } - - template inline - void left_mult(const ildltt_precond& P, const V1 &v1, V2 &v2) { - copy(v1, v2); - gmm::lower_tri_solve(gmm::conjugated(P.U), v2, true); - for (size_type i = 0; i < P.indiag.size(); ++i) v2[i] *= P.indiag[i]; - } - - template inline - void right_mult(const ildltt_precond& P, const V1 &v1, V2 &v2) - { copy(v1, v2); gmm::upper_tri_solve(P.U, v2, true); } - - template inline - void transposed_left_mult(const ildltt_precond& P, const V1 &v1, - V2 &v2) { - copy(v1, v2); - gmm::upper_tri_solve(P.U, v2, true); - for (size_type i = 0; i < P.indiag.size(); ++i) v2[i] *= P.indiag[i]; - } - - template inline - void transposed_right_mult(const ildltt_precond& P, const V1 &v1, - V2 &v2) - { copy(v1, v2); gmm::lower_tri_solve(gmm::conjugated(P.U), v2, true); } - -} - -#endif - diff --git a/gmm/gmm_precond_ilu.h b/gmm/gmm_precond_ilu.h deleted file mode 100644 index 9256b86a2..000000000 --- a/gmm/gmm_precond_ilu.h +++ /dev/null @@ -1,280 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -// This file is a modified version of ilu.h from ITL. -// See http://osl.iu.edu/research/itl/ -// Following the corresponding Copyright notice. -//=========================================================================== -// -// Copyright (c) 1998-2001, University of Notre Dame. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of Notre Dame nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE TRUSTEES OF INDIANA UNIVERSITY AND -// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES -// OF INDIANA UNIVERSITY AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//=========================================================================== - -/**@file gmm_precond_ilu.h - @author Andrew Lumsdaine - @author Lie-Quan Lee - @author Yves Renard - @date June 5, 2003. - @brief Incomplete LU without fill-in Preconditioner. -*/ - -#ifndef GMM_PRECOND_ILU_H -#define GMM_PRECOND_ILU_H - -// -// Notes: The idea under a concrete Preconditioner such -// as Incomplete LU is to create a Preconditioner -// object to use in iterative methods. -// - -#include "gmm_precond.h" - -namespace gmm { - /** Incomplete LU without fill-in Preconditioner. */ - template - class ilu_precond { - - public : - typedef typename linalg_traits::value_type value_type; - typedef csr_matrix_ref tm_type; - - tm_type U, L; - bool invert; - protected : - std::vector L_val, U_val; - std::vector L_ind, U_ind, L_ptr, U_ptr; - - template void do_ilu(const M& A, row_major); - void do_ilu(const Matrix& A, col_major); - - public: - - size_type nrows(void) const { return mat_nrows(L); } - size_type ncols(void) const { return mat_ncols(U); } - - void build_with(const Matrix& A) { - invert = false; - L_ptr.resize(mat_nrows(A)+1); - U_ptr.resize(mat_nrows(A)+1); - do_ilu(A, typename principal_orientation_type::sub_orientation>::potype()); - } - ilu_precond(const Matrix& A) { build_with(A); } - ilu_precond(void) {} - size_type memsize() const { - return sizeof(*this) + - (L_val.size()+U_val.size()) * sizeof(value_type) + - (L_ind.size()+L_ptr.size()) * sizeof(size_type) + - (U_ind.size()+U_ptr.size()) * sizeof(size_type); - } - }; - - template template - void ilu_precond::do_ilu(const M& A, row_major) { - typedef typename linalg_traits::storage_type store_type; - typedef value_type T; - typedef typename number_traits::magnitude_type R; - - size_type L_loc = 0, U_loc = 0, n = mat_nrows(A), i, j, k; - if (n == 0) return; - L_ptr[0] = 0; U_ptr[0] = 0; - R prec = default_tol(R()); - R max_pivot = gmm::abs(A(0,0)) * prec; - - - for (int count = 0; count < 2; ++count) { - if (count) { - L_val.resize(L_loc); L_ind.resize(L_loc); - U_val.resize(U_loc); U_ind.resize(U_loc); - } - L_loc = U_loc = 0; - for (i = 0; i < n; ++i) { - typedef typename linalg_traits::const_sub_row_type row_type; - row_type row = mat_const_row(A, i); - typename linalg_traits::t>::const_iterator - it = vect_const_begin(row), ite = vect_const_end(row); - - if (count) { U_val[U_loc] = T(0); U_ind[U_loc] = i; } - ++U_loc; // diagonal element - - for (k = 0; it != ite && k < 1000; ++it, ++k) { - // if a plain row is present, retains only the 1000 firsts - // nonzero elements. ---> a sort should be done. - j = index_of_it(it, k, store_type()); - if (j < i) { - if (count) { L_val[L_loc] = *it; L_ind[L_loc] = j; } - L_loc++; - } - else if (i == j) { - if (count) U_val[U_loc-1] = *it; - } - else { - if (count) { U_val[U_loc] = *it; U_ind[U_loc] = j; } - U_loc++; - } - } - L_ptr[i+1] = L_loc; U_ptr[i+1] = U_loc; - } - } - - if (A(0,0) == T(0)) { - U_val[U_ptr[0]] = T(1); - GMM_WARNING2("pivot 0 is too small"); - } - - size_type qn, pn, rn; - for (i = 1; i < n; i++) { - - pn = U_ptr[i]; - if (gmm::abs(U_val[pn]) <= max_pivot) { - U_val[pn] = T(1); - GMM_WARNING2("pivot " << i << " is too small"); - } - max_pivot = std::max(max_pivot, - std::min(gmm::abs(U_val[pn]) * prec, R(1))); - - for (j = L_ptr[i]; j < L_ptr[i+1]; j++) { - pn = U_ptr[L_ind[j]]; - - T multiplier = (L_val[j] /= U_val[pn]); - - qn = j + 1; - rn = U_ptr[i]; - - for (pn++; pn < U_ptr[L_ind[j]+1] && U_ind[pn] < i; pn++) { - while (qn < L_ptr[i+1] && L_ind[qn] < U_ind[pn]) - qn++; - if (qn < L_ptr[i+1] && U_ind[pn] == L_ind[qn]) - L_val[qn] -= multiplier * U_val[pn]; - } - for (; pn < U_ptr[L_ind[j]+1]; pn++) { - while (rn < U_ptr[i+1] && U_ind[rn] < U_ind[pn]) - rn++; - if (rn < U_ptr[i+1] && U_ind[pn] == U_ind[rn]) - U_val[rn] -= multiplier * U_val[pn]; - } - } - } - - L = tm_type(&(L_val[0]), &(L_ind[0]), &(L_ptr[0]), n, mat_ncols(A)); - U = tm_type(&(U_val[0]), &(U_ind[0]), &(U_ptr[0]), n, mat_ncols(A)); - } - - template - void ilu_precond::do_ilu(const Matrix& A, col_major) { - do_ilu(gmm::transposed(A), row_major()); - invert = true; - } - - template inline - void mult(const ilu_precond& P, const V1 &v1, V2 &v2) { - gmm::copy(v1, v2); - if (P.invert) { - gmm::lower_tri_solve(gmm::transposed(P.U), v2, false); - gmm::upper_tri_solve(gmm::transposed(P.L), v2, true); - } - else { - gmm::lower_tri_solve(P.L, v2, true); - gmm::upper_tri_solve(P.U, v2, false); - } - } - - template inline - void transposed_mult(const ilu_precond& P,const V1 &v1,V2 &v2) { - gmm::copy(v1, v2); - if (P.invert) { - gmm::lower_tri_solve(P.L, v2, true); - gmm::upper_tri_solve(P.U, v2, false); - } - else { - gmm::lower_tri_solve(gmm::transposed(P.U), v2, false); - gmm::upper_tri_solve(gmm::transposed(P.L), v2, true); - } - } - - template inline - void left_mult(const ilu_precond& P, const V1 &v1, V2 &v2) { - copy(v1, v2); - if (P.invert) gmm::lower_tri_solve(gmm::transposed(P.U), v2, false); - else gmm::lower_tri_solve(P.L, v2, true); - } - - template inline - void right_mult(const ilu_precond& P, const V1 &v1, V2 &v2) { - copy(v1, v2); - if (P.invert) gmm::upper_tri_solve(gmm::transposed(P.L), v2, true); - else gmm::upper_tri_solve(P.U, v2, false); - } - - template inline - void transposed_left_mult(const ilu_precond& P, const V1 &v1, - V2 &v2) { - copy(v1, v2); - if (P.invert) gmm::upper_tri_solve(P.U, v2, false); - else gmm::upper_tri_solve(gmm::transposed(P.L), v2, true); - } - - template inline - void transposed_right_mult(const ilu_precond& P, const V1 &v1, - V2 &v2) { - copy(v1, v2); - if (P.invert) gmm::lower_tri_solve(P.L, v2, true); - else gmm::lower_tri_solve(gmm::transposed(P.U), v2, false); - } - - -} - -#endif - diff --git a/gmm/gmm_precond_ilut.h b/gmm/gmm_precond_ilut.h deleted file mode 100644 index 0860324f0..000000000 --- a/gmm/gmm_precond_ilut.h +++ /dev/null @@ -1,263 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -// This file is a modified version of ilut.h from ITL. -// See http://osl.iu.edu/research/itl/ -// Following the corresponding Copyright notice. -//=========================================================================== -// -// Copyright (c) 1998-2001, University of Notre Dame. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of Notre Dame nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE TRUSTEES OF INDIANA UNIVERSITY AND -// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES -// OF INDIANA UNIVERSITY AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//=========================================================================== - -#ifndef GMM_PRECOND_ILUT_H -#define GMM_PRECOND_ILUT_H - -/**@file gmm_precond_ilut.h - @author Andrew Lumsdaine , Lie-Quan Lee - @date June 5, 2003. - @brief ILUT: Incomplete LU with threshold and K fill-in Preconditioner. -*/ - -/* - Performane comparing for SSOR, ILU and ILUT based on sherman 5 matrix - in Harwell-Boeing collection on Sun Ultra 30 UPA/PCI (UltraSPARC-II 296MHz) - Preconditioner & Factorization time & Number of Iteration \\ \hline - SSOR & 0.010577 & 41 \\ - ILU & 0.019336 & 32 \\ - ILUT with 0 fill-in and threshold of 1.0e-6 & 0.343612 & 23 \\ - ILUT with 5 fill-in and threshold of 1.0e-6 & 0.343612 & 18 \\ \hline -*/ - -#include "gmm_precond.h" - -namespace gmm { - - template struct elt_rsvector_value_less_ { - inline bool operator()(const elt_rsvector_& a, - const elt_rsvector_& b) const - { return (gmm::abs(a.e) > gmm::abs(b.e)); } - }; - - /** Incomplete LU with threshold and K fill-in Preconditioner. - - The algorithm of ILUT(A, 0, 1.0e-6) is slower than ILU(A). If No - fill-in is arrowed, you can use ILU instead of ILUT. - - Notes: The idea under a concrete Preconditioner such as ilut is to - create a Preconditioner object to use in iterative methods. - */ - template - class ilut_precond { - public : - typedef typename linalg_traits::value_type value_type; - typedef wsvector _wsvector; - typedef rsvector _rsvector; - typedef row_matrix<_rsvector> LU_Matrix; - - bool invert; - LU_Matrix L, U; - - protected: - size_type K; - double eps; - - template void do_ilut(const M&, row_major); - void do_ilut(const Matrix&, col_major); - - public: - void build_with(const Matrix& A, int k_ = -1, double eps_ = double(-1)) { - if (k_ >= 0) K = k_; - if (eps_ >= double(0)) eps = eps_; - invert = false; - gmm::resize(L, mat_nrows(A), mat_ncols(A)); - gmm::resize(U, mat_nrows(A), mat_ncols(A)); - do_ilut(A, typename principal_orientation_type::sub_orientation>::potype()); - } - ilut_precond(const Matrix& A, int k_, double eps_) - : L(mat_nrows(A), mat_ncols(A)), U(mat_nrows(A), mat_ncols(A)), - K(k_), eps(eps_) { build_with(A); } - ilut_precond(size_type k_, double eps_) : K(k_), eps(eps_) {} - ilut_precond(void) { K = 10; eps = 1E-7; } - size_type memsize() const { - return sizeof(*this) + (nnz(U)+nnz(L))*sizeof(value_type); - } - }; - - template template - void ilut_precond::do_ilut(const M& A, row_major) { - typedef value_type T; - typedef typename number_traits::magnitude_type R; - - size_type n = mat_nrows(A); - if (n == 0) return; - std::vector indiag(n); - _wsvector w(mat_ncols(A)); - _rsvector ww(mat_ncols(A)), wL(mat_ncols(A)), wU(mat_ncols(A)); - T tmp; - gmm::clear(U); gmm::clear(L); - R prec = default_tol(R()); - R max_pivot = gmm::abs(A(0,0)) * prec; - - for (size_type i = 0; i < n; ++i) { - gmm::copy(mat_const_row(A, i), w); - double norm_row = gmm::vect_norm2(w); - - typename _wsvector::iterator wkold = w.end(); - for (typename _wsvector::iterator wk = w.begin(); - wk != w.end() && wk->first < i; ) { - size_type k = wk->first; - tmp = (wk->second) * indiag[k]; - if (gmm::abs(tmp) < eps * norm_row) w.erase(k); - else { wk->second += tmp; gmm::add(scaled(mat_row(U, k), -tmp), w); } - if (wkold == w.end()) wk = w.begin(); else { wk = wkold; ++wk; } - if (wk != w.end() && wk->first == k) - { if (wkold == w.end()) wkold = w.begin(); else ++wkold; ++wk; } - } - tmp = w[i]; - - if (gmm::abs(tmp) <= max_pivot) { - GMM_WARNING2("pivot " << i << " too small. try with ilutp ?"); - w[i] = tmp = T(1); - } - - max_pivot = std::max(max_pivot, std::min(gmm::abs(tmp) * prec, R(1))); - indiag[i] = T(1) / tmp; - gmm::clean(w, eps * norm_row); - gmm::copy(w, ww); - std::sort(ww.begin(), ww.end(), elt_rsvector_value_less_()); - typename _rsvector::const_iterator wit = ww.begin(), wite = ww.end(); - - size_type nnl = 0, nnu = 0; - wL.base_resize(K); wU.base_resize(K+1); - typename _rsvector::iterator witL = wL.begin(), witU = wU.begin(); - for (; wit != wite; ++wit) - if (wit->c < i) { if (nnl < K) { *witL++ = *wit; ++nnl; } } - else { if (nnu < K || wit->c == i) { *witU++ = *wit; ++nnu; } } - wL.base_resize(nnl); wU.base_resize(nnu); - std::sort(wL.begin(), wL.end()); - std::sort(wU.begin(), wU.end()); - gmm::copy(wL, L.row(i)); - gmm::copy(wU, U.row(i)); - } - - } - - template - void ilut_precond::do_ilut(const Matrix& A, col_major) { - do_ilut(gmm::transposed(A), row_major()); - invert = true; - } - - template inline - void mult(const ilut_precond& P, const V1 &v1, V2 &v2) { - gmm::copy(v1, v2); - if (P.invert) { - gmm::lower_tri_solve(gmm::transposed(P.U), v2, false); - gmm::upper_tri_solve(gmm::transposed(P.L), v2, true); - } - else { - gmm::lower_tri_solve(P.L, v2, true); - gmm::upper_tri_solve(P.U, v2, false); - } - } - - template inline - void transposed_mult(const ilut_precond& P,const V1 &v1,V2 &v2) { - gmm::copy(v1, v2); - if (P.invert) { - gmm::lower_tri_solve(P.L, v2, true); - gmm::upper_tri_solve(P.U, v2, false); - } - else { - gmm::lower_tri_solve(gmm::transposed(P.U), v2, false); - gmm::upper_tri_solve(gmm::transposed(P.L), v2, true); - } - } - - template inline - void left_mult(const ilut_precond& P, const V1 &v1, V2 &v2) { - copy(v1, v2); - if (P.invert) gmm::lower_tri_solve(gmm::transposed(P.U), v2, false); - else gmm::lower_tri_solve(P.L, v2, true); - } - - template inline - void right_mult(const ilut_precond& P, const V1 &v1, V2 &v2) { - copy(v1, v2); - if (P.invert) gmm::upper_tri_solve(gmm::transposed(P.L), v2, true); - else gmm::upper_tri_solve(P.U, v2, false); - } - - template inline - void transposed_left_mult(const ilut_precond& P, const V1 &v1, - V2 &v2) { - copy(v1, v2); - if (P.invert) gmm::upper_tri_solve(P.U, v2, false); - else gmm::upper_tri_solve(gmm::transposed(P.L), v2, true); - } - - template inline - void transposed_right_mult(const ilut_precond& P, const V1 &v1, - V2 &v2) { - copy(v1, v2); - if (P.invert) gmm::lower_tri_solve(P.L, v2, true); - else gmm::lower_tri_solve(gmm::transposed(P.U), v2, false); - } - -} - -#endif - diff --git a/gmm/gmm_precond_ilutp.h b/gmm/gmm_precond_ilutp.h deleted file mode 100644 index d867d6053..000000000 --- a/gmm/gmm_precond_ilutp.h +++ /dev/null @@ -1,284 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2004-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_precond_ilutp.h - @author Yves Renard - @date October 14, 2004. - @brief ILUTP: Incomplete LU with threshold and K fill-in Preconditioner and - column pivoting. - - -*/ -#ifndef GMM_PRECOND_ILUTP_H -#define GMM_PRECOND_ILUTP_H - -#include "gmm_precond_ilut.h" - -namespace gmm { - - /** - ILUTP: Incomplete LU with threshold and K fill-in Preconditioner and - column pivoting. - - See Yousef Saad, Iterative Methods for - sparse linear systems, PWS Publishing Company, section 10.4.4 - - TODO : store the permutation by cycles to avoid the temporary vector - */ - template - class ilutp_precond { - public : - typedef typename linalg_traits::value_type value_type; - typedef wsvector _wsvector; - typedef rsvector _rsvector; - typedef row_matrix<_rsvector> LU_Matrix; - typedef col_matrix<_wsvector> CLU_Matrix; - - bool invert; - LU_Matrix L, U; - gmm::unsorted_sub_index indperm; - gmm::unsorted_sub_index indperminv; - mutable std::vector temporary; - - protected: - size_type K; - double eps; - - template void do_ilutp(const M&, row_major); - void do_ilutp(const Matrix&, col_major); - - public: - void build_with(const Matrix& A, int k_ = -1, double eps_ = double(-1)) { - if (k_ >= 0) K = k_; - if (eps_ >= double(0)) eps = eps_; - invert = false; - gmm::resize(L, mat_nrows(A), mat_ncols(A)); - gmm::resize(U, mat_nrows(A), mat_ncols(A)); - do_ilutp(A, typename principal_orientation_type::sub_orientation>::potype()); - } - ilutp_precond(const Matrix& A, size_type k_, double eps_) - : L(mat_nrows(A), mat_ncols(A)), U(mat_nrows(A), mat_ncols(A)), - K(k_), eps(eps_) { build_with(A); } - ilutp_precond(int k_, double eps_) : K(k_), eps(eps_) {} - ilutp_precond(void) { K = 10; eps = 1E-7; } - size_type memsize() const { - return sizeof(*this) + (nnz(U)+nnz(L))*sizeof(value_type); - } - }; - - - template template - void ilutp_precond::do_ilutp(const M& A, row_major) { - typedef value_type T; - typedef typename number_traits::magnitude_type R; - - size_type n = mat_nrows(A); - CLU_Matrix CU(n,n); - if (n == 0) return; - std::vector indiag(n); - temporary.resize(n); - std::vector ipvt(n), ipvtinv(n); - for (size_type i = 0; i < n; ++i) ipvt[i] = ipvtinv[i] = i; - indperm = unsorted_sub_index(ipvt); - indperminv = unsorted_sub_index(ipvtinv); - _wsvector w(mat_ncols(A)); - _rsvector ww(mat_ncols(A)); - - T tmp = T(0); - gmm::clear(L); gmm::clear(U); - R prec = default_tol(R()); - R max_pivot = gmm::abs(A(0,0)) * prec; - - for (size_type i = 0; i < n; ++i) { - - copy(sub_vector(mat_const_row(A, i), indperm), w); - double norm_row = gmm::vect_norm2(mat_const_row(A, i)); - - typename _wsvector::iterator wkold = w.end(); - for (typename _wsvector::iterator wk = w.begin(); - wk != w.end() && wk->first < i; ) { - size_type k = wk->first; - tmp = (wk->second) * indiag[k]; - if (gmm::abs(tmp) < eps * norm_row) w.erase(k); - else { wk->second += tmp; gmm::add(scaled(mat_row(U, k), -tmp), w); } - if (wkold == w.end()) wk = w.begin(); else { wk = wkold; ++wk; } - if (wk != w.end() && wk->first == k) - { if (wkold == w.end()) wkold = w.begin(); else ++wkold; ++wk; } - } - - gmm::clean(w, eps * norm_row); - gmm::copy(w, ww); - - std::sort(ww.begin(), ww.end(), elt_rsvector_value_less_()); - typename _rsvector::const_iterator wit = ww.begin(), wite = ww.end(); - size_type ip = size_type(-1); - - for (; wit != wite; ++wit) - if (wit->c >= i) { ip = wit->c; tmp = wit->e; break; } - if (ip == size_type(-1) || gmm::abs(tmp) <= max_pivot) - { GMM_WARNING2("pivot " << i << " too small"); ip=i; ww[i]=tmp=T(1); } - max_pivot = std::max(max_pivot, std::min(gmm::abs(tmp) * prec, R(1))); - indiag[i] = T(1) / tmp; - wit = ww.begin(); - - size_type nnl = 0, nnu = 0; - L[i].base_resize(K); U[i].base_resize(K+1); - typename _rsvector::iterator witL = L[i].begin(), witU = U[i].begin(); - for (; wit != wite; ++wit) { - if (wit->c < i) { if (nnl < K) { *witL++ = *wit; ++nnl; } } - else if (nnu < K || wit->c == i) - { CU(i, wit->c) = wit->e; *witU++ = *wit; ++nnu; } - } - L[i].base_resize(nnl); U[i].base_resize(nnu); - std::sort(L[i].begin(), L[i].end()); - std::sort(U[i].begin(), U[i].end()); - - if (ip != i) { - typename _wsvector::const_iterator iti = CU.col(i).begin(); - typename _wsvector::const_iterator itie = CU.col(i).end(); - typename _wsvector::const_iterator itp = CU.col(ip).begin(); - typename _wsvector::const_iterator itpe = CU.col(ip).end(); - - while (iti != itie && itp != itpe) { - if (iti->first < itp->first) - { U.row(iti->first).swap_indices(i, ip); ++iti; } - else if (iti->first > itp->first) - { U.row(itp->first).swap_indices(i,ip);++itp; } - else - { U.row(iti->first).swap_indices(i, ip); ++iti; ++itp; } - } - - for( ; iti != itie; ++iti) U.row(iti->first).swap_indices(i, ip); - for( ; itp != itpe; ++itp) U.row(itp->first).swap_indices(i, ip); - - CU.swap_col(i, ip); - - indperm.swap(i, ip); - indperminv.swap(ipvt[i], ipvt[ip]); - std::swap(ipvtinv[ipvt[i]], ipvtinv[ipvt[ip]]); - std::swap(ipvt[i], ipvt[ip]); - } - } - } - - template - void ilutp_precond::do_ilutp(const Matrix& A, col_major) { - do_ilutp(gmm::transposed(A), row_major()); - invert = true; - } - - template inline - void mult(const ilutp_precond& P, const V1 &v1, V2 &v2) { - if (P.invert) { - gmm::copy(gmm::sub_vector(v1, P.indperm), v2); - gmm::lower_tri_solve(gmm::transposed(P.U), v2, false); - gmm::upper_tri_solve(gmm::transposed(P.L), v2, true); - } - else { - gmm::copy(v1, P.temporary); - gmm::lower_tri_solve(P.L, P.temporary, true); - gmm::upper_tri_solve(P.U, P.temporary, false); - gmm::copy(gmm::sub_vector(P.temporary, P.indperminv), v2); - } - } - - template inline - void transposed_mult(const ilutp_precond& P,const V1 &v1,V2 &v2) { - if (P.invert) { - gmm::copy(v1, P.temporary); - gmm::lower_tri_solve(P.L, P.temporary, true); - gmm::upper_tri_solve(P.U, P.temporary, false); - gmm::copy(gmm::sub_vector(P.temporary, P.indperminv), v2); - } - else { - gmm::copy(gmm::sub_vector(v1, P.indperm), v2); - gmm::lower_tri_solve(gmm::transposed(P.U), v2, false); - gmm::upper_tri_solve(gmm::transposed(P.L), v2, true); - } - } - - template inline - void left_mult(const ilutp_precond& P, const V1 &v1, V2 &v2) { - if (P.invert) { - gmm::copy(gmm::sub_vector(v1, P.indperm), v2); - gmm::lower_tri_solve(gmm::transposed(P.U), v2, false); - } - else { - copy(v1, v2); - gmm::lower_tri_solve(P.L, v2, true); - } - } - - template inline - void right_mult(const ilutp_precond& P, const V1 &v1, V2 &v2) { - if (P.invert) { - copy(v1, v2); - gmm::upper_tri_solve(gmm::transposed(P.L), v2, true); - } - else { - copy(v1, P.temporary); - gmm::upper_tri_solve(P.U, P.temporary, false); - gmm::copy(gmm::sub_vector(P.temporary, P.indperminv), v2); - } - } - - template inline - void transposed_left_mult(const ilutp_precond& P, const V1 &v1, - V2 &v2) { - if (P.invert) { - copy(v1, P.temporary); - gmm::upper_tri_solve(P.U, P.temporary, false); - gmm::copy(gmm::sub_vector(P.temporary, P.indperminv), v2); - } - else { - copy(v1, v2); - gmm::upper_tri_solve(gmm::transposed(P.L), v2, true); - } - } - - template inline - void transposed_right_mult(const ilutp_precond& P, const V1 &v1, - V2 &v2) { - if (P.invert) { - copy(v1, v2); - gmm::lower_tri_solve(P.L, v2, true); - } - else { - gmm::copy(gmm::sub_vector(v1, P.indperm), v2); - gmm::lower_tri_solve(gmm::transposed(P.U), v2, false); - } - } - -} - -#endif - diff --git a/gmm/gmm_precond_mr_approx_inverse.h b/gmm/gmm_precond_mr_approx_inverse.h deleted file mode 100644 index 7504f48fb..000000000 --- a/gmm/gmm_precond_mr_approx_inverse.h +++ /dev/null @@ -1,149 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - - -// This file is a modified version of approximate_inverse.h from ITL. -// See http://osl.iu.edu/research/itl/ -// Following the corresponding Copyright notice. -//=========================================================================== -// -// Copyright (c) 1998-2001, University of Notre Dame. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of Notre Dame nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE TRUSTEES OF INDIANA UNIVERSITY AND -// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES -// OF INDIANA UNIVERSITY AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//=========================================================================== - -/**@file gmm_precond_mr_approx_inverse.h - @author Andrew Lumsdaine - @author Lie-Quan Lee - @author Yves Renard - @date June 5, 2003. - @brief Approximate inverse via MR iteration. -*/ - -#ifndef GMM_PRECOND_MR_APPROX_INVERSE_H -#define GMM_PRECOND_MR_APPROX_INVERSE_H - - -#include "gmm_precond.h" - -namespace gmm { - - /** Approximate inverse via MR iteration (see P301 of Saad book). - */ - template - struct mr_approx_inverse_precond { - - typedef typename linalg_traits::value_type value_type; - typedef typename number_traits::magnitude_type magnitude_type; - typedef typename principal_orientation_type::sub_orientation>::potype sub_orientation; - typedef wsvector VVector; - typedef col_matrix MMatrix; - - MMatrix M; - size_type nb_it; - magnitude_type threshold; - - void build_with(const Matrix& A); - mr_approx_inverse_precond(const Matrix& A, size_type nb_it_, - magnitude_type threshold_) - : M(mat_nrows(A), mat_ncols(A)) - { threshold = threshold_; nb_it = nb_it_; build_with(A); } - mr_approx_inverse_precond(void) - { threshold = magnitude_type(1E-7); nb_it = 5; } - mr_approx_inverse_precond(size_type nb_it_, magnitude_type threshold_) - { threshold = threshold_; nb_it = nb_it_; } - const MMatrix &approx_inverse(void) const { return M; } - }; - - template inline - void mult(const mr_approx_inverse_precond& P, const V1 &v1, V2 &v2) - { mult(P.M, v1, v2); } - - template inline - void transposed_mult(const mr_approx_inverse_precond& P, - const V1 &v1,V2 &v2) - { mult(gmm::conjugated(P.M), v1, v2); } - - template - void mr_approx_inverse_precond::build_with(const Matrix& A) { - gmm::resize(M, mat_nrows(A), mat_ncols(A)); - typedef value_type T; - typedef magnitude_type R; - VVector m(mat_ncols(A)),r(mat_ncols(A)),ei(mat_ncols(A)),Ar(mat_ncols(A)); - T alpha = mat_trace(A)/ mat_euclidean_norm_sqr(A); - if (alpha == T(0)) alpha = T(1); - - for (size_type i = 0; i < mat_nrows(A); ++i) { - gmm::clear(m); gmm::clear(ei); - m[i] = alpha; - ei[i] = T(1); - - for (size_type j = 0; j < nb_it; ++j) { - gmm::mult(A, gmm::scaled(m, T(-1)), r); - gmm::add(ei, r); - gmm::mult(A, r, Ar); - T nAr = vect_sp(Ar,Ar); - if (gmm::abs(nAr) > R(0)) { - gmm::add(gmm::scaled(r, gmm::safe_divide(vect_sp(r, Ar), vect_sp(Ar, Ar))), m); - gmm::clean(m, threshold * gmm::vect_norm2(m)); - } else gmm::clear(m); - } - if (gmm::vect_norm2(m) == R(0)) m[i] = alpha; - gmm::copy(m, M.col(i)); - } - } -} - -#endif - diff --git a/gmm/gmm_range_basis.h b/gmm/gmm_range_basis.h deleted file mode 100644 index 05a71a0c8..000000000 --- a/gmm/gmm_range_basis.h +++ /dev/null @@ -1,499 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2009-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_range_basis.h - @author Yves Renard - @date March 10, 2009. - @brief Extract a basis of the range of a (large sparse) matrix from the - columns of this matrix. -*/ -#ifndef GMM_RANGE_BASIS_H -#define GMM_RANGE_BASIS_H -#include "gmm_dense_qr.h" -#include "gmm_dense_lu.h" - -#include "gmm_kernel.h" -#include "gmm_iter.h" -#include -#include - - -namespace gmm { - - - template - void tridiag_qr_algorithm - (std::vector::magnitude_type> diag, - std::vector sdiag, const VECT &eigval_, const MAT1 &eigvect_, - bool compvect, tol_type_for_qr tol = default_tol_for_qr) { - VECT &eigval = const_cast(eigval_); - MAT1 &eigvect = const_cast(eigvect_); - typedef typename number_traits::magnitude_type R; - - if (compvect) gmm::copy(identity_matrix(), eigvect); - - size_type n = diag.size(), q = 0, p, ite = 0; - if (n == 0) return; - if (n == 1) { eigval[0] = gmm::real(diag[0]); return; } - - symmetric_qr_stop_criterion(diag, sdiag, p, q, tol); - - while (q < n) { - sub_interval SUBI(p, n-p-q), SUBJ(0, mat_ncols(eigvect)), SUBK(p, n-p-q); - if (!compvect) SUBK = sub_interval(0,0); - - symmetric_Wilkinson_qr_step(sub_vector(diag, SUBI), - sub_vector(sdiag, SUBI), - sub_matrix(eigvect, SUBJ, SUBK), compvect); - - symmetric_qr_stop_criterion(diag, sdiag, p, q, tol*R(3)); - ++ite; - GMM_ASSERT1(ite < n*100, "QR algorithm failed."); - } - - gmm::copy(diag, eigval); - } - - // Range basis with a restarted Lanczos method - template - void range_basis_eff_Lanczos(const Mat &BB, std::set &columns, - double EPS=1E-12) { - typedef std::set TAB; - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - size_type nc_r = columns.size(), k; - col_matrix< rsvector > B(mat_nrows(BB), mat_ncols(BB)); - - k = 0; - for (TAB::iterator it = columns.begin(); it!=columns.end(); ++it, ++k){ - gmm::copy(scaled(mat_col(BB, *it), T(1)/vect_norm2(mat_col(BB, *it))), - mat_col(B, *it)); - } - std::vector w(mat_nrows(B)); - size_type restart = 120; - std::vector sdiag(restart); - std::vector eigval(restart), diag(restart); - dense_matrix eigvect(restart, restart); - - R rho = R(-1), rho2; - while (nc_r) { - - std::vector v(nc_r), v0(nc_r), wl(nc_r); - dense_matrix lv(nc_r, restart); - - if (rho < R(0)) { // Estimate of the spectral radius of B^* B - gmm::fill_random(v); - for (size_type i = 0; i < 100; ++i) { - gmm::scale(v, T(1)/vect_norm2(v)); - gmm::copy(v, v0); - k = 0; gmm::clear(w); - for (TAB::iterator it=columns.begin(); it!=columns.end(); ++it, ++k) - add(scaled(mat_col(B, *it), v[k]), w); - k = 0; - for (TAB::iterator it=columns.begin(); it!=columns.end(); ++it, ++k) - v[k] = vect_hp(w, mat_col(B, *it)); - rho = gmm::abs(vect_hp(v, v0) / vect_hp(v0, v0)); - } - rho *= R(2); - } - - // Computing vectors of the null space of de B^* B with restarted Lanczos - rho2 = 0; - gmm::fill_random(v); - size_type iter = 0; - for(;;++iter) { - R rho_old = rho2; - R beta = R(0), alpha; - gmm::scale(v, T(1)/vect_norm2(v)); - size_type eff_restart = restart; - if (sdiag.size() != restart) { - sdiag.resize(restart); eigval.resize(restart); diag.resize(restart); gmm::resize(eigvect, restart, restart); - gmm::resize(lv, nc_r, restart); - } - - for (size_type i = 0; i < restart; ++i) { // Lanczos iterations - gmm::copy(v, mat_col(lv, i)); - gmm::clear(w); - k = 0; - for (TAB::iterator it=columns.begin(); it!=columns.end(); ++it, ++k) - add(scaled(mat_col(B, *it), v[k]), w); - - k = 0; - for (TAB::iterator it=columns.begin(); it!=columns.end(); ++it, ++k) - wl[k] = v[k]*rho - vect_hp(w, mat_col(B, *it)) - beta*v0[k]; - alpha = gmm::real(vect_hp(wl, v)); - diag[i] = alpha; - gmm::add(gmm::scaled(v, -alpha), wl); - sdiag[i] = beta = vect_norm2(wl); - gmm::copy(v, v0); - if (beta < EPS) { eff_restart = i+1; break; } - gmm::copy(gmm::scaled(wl, T(1) / beta), v); - } - if (eff_restart != restart) { - sdiag.resize(eff_restart); eigval.resize(eff_restart); diag.resize(eff_restart); - gmm::resize(eigvect, eff_restart, eff_restart); gmm::resize(lv, nc_r, eff_restart); - } - tridiag_qr_algorithm(diag, sdiag, eigval, eigvect, true); - - size_type num = size_type(-1); - rho2 = R(0); - for (size_type j = 0; j < eff_restart; ++j) - { R nvp=gmm::abs(eigval[j]); if (nvp > rho2) { rho2=nvp; num=j; }} - - GMM_ASSERT1(num != size_type(-1), "Internal error"); - - gmm::mult(lv, mat_col(eigvect, num), v); - - if (gmm::abs(rho2-rho_old) < rho_old*R(EPS)) break; - // if (gmm::abs(rho-rho2) < rho*R(gmm::sqrt(EPS))) break; - if (gmm::abs(rho-rho2) < rho*R(EPS)*R(100)) break; - } - - if (gmm::abs(rho-rho2) < rho*R(EPS*10.)) { - size_type j_max = size_type(-1), j = 0; - R val_max = R(0); - for (TAB::iterator it=columns.begin(); it!=columns.end(); ++it, ++j) - if (gmm::abs(v[j]) > val_max) - { val_max = gmm::abs(v[j]); j_max = *it; } - columns.erase(j_max); nc_r = columns.size(); - } - else break; - } - } - - // Range basis with LU decomposition. Not stable from a numerical viewpoint. - // Complex version not verified - template - void range_basis_eff_lu(const Mat &B, std::set &columns, - std::vector &c_ortho, double EPS) { - - typedef std::set TAB; - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - size_type nc_r = 0, nc_o = 0, nc = mat_ncols(B), nr = mat_nrows(B), i, j; - - for (TAB::iterator it=columns.begin(); it!=columns.end(); ++it) - if (!(c_ortho[*it])) ++nc_r; else nc_o++; - - if (nc_r > 0) { - - gmm::row_matrix< gmm::rsvector > Hr(nc, nc_r), Ho(nc, nc_o); - gmm::row_matrix< gmm::rsvector > BBr(nr, nc_r), BBo(nr, nc_o); - - i = j = 0; - for (TAB::iterator it=columns.begin(); it!=columns.end(); ++it) - if (!(c_ortho[*it])) - { Hr(*it, i) = T(1)/ vect_norminf(mat_col(B, *it)); ++i; } - else - { Ho(*it, j) = T(1)/ vect_norm2(mat_col(B, *it)); ++j; } - - gmm::mult(B, Hr, BBr); - gmm::mult(B, Ho, BBo); - gmm::dense_matrix M(nc_r, nc_r), BBB(nc_r, nc_o), MM(nc_r, nc_r); - gmm::mult(gmm::conjugated(BBr), BBr, M); - gmm::mult(gmm::conjugated(BBr), BBo, BBB); - gmm::mult(BBB, gmm::conjugated(BBB), MM); - gmm::add(gmm::scaled(MM, T(-1)), M); - - std::vector ipvt(nc_r); - gmm::lu_factor(M, ipvt); - - R emax = R(0); - for (i = 0; i < nc_r; ++i) emax = std::max(emax, gmm::abs(M(i,i))); - - i = 0; - std::set c = columns; - for (TAB::iterator it = c.begin(); it != c.end(); ++it) - if (!(c_ortho[*it])) { - if (gmm::abs(M(i,i)) <= R(EPS)*emax) columns.erase(*it); - ++i; - } - } - } - - - // Range basis with Gram-Schmidt orthogonalization (sparse version) - // The sparse version is better when the sparsity is high and less efficient - // than the dense version for high degree elements (P3, P4 ...) - // Complex version not verified - template - void range_basis_eff_Gram_Schmidt_sparse(const Mat &BB, - std::set &columns, - std::vector &c_ortho, - double EPS) { - - typedef std::set TAB; - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - size_type nc = mat_ncols(BB), nr = mat_nrows(BB); - std::set c = columns, rc = columns; - - gmm::col_matrix< rsvector > B(nr, nc); - for (std::set::iterator it = columns.begin(); - it != columns.end(); ++it) { - gmm::copy(mat_col(BB, *it), mat_col(B, *it)); - gmm::scale(mat_col(B, *it), T(1)/vect_norm2(mat_col(B, *it))); - } - - for (std::set::iterator it = c.begin(); it != c.end(); ++it) - if (c_ortho[*it]) { - for (std::set::iterator it2 = rc.begin(); - it2 != rc.end(); ++it2) - if (!(c_ortho[*it2])) { - T r = -vect_hp(mat_col(B, *it2), mat_col(B, *it)); - if (r != T(0)) add(scaled(mat_col(B, *it), r), mat_col(B, *it2)); - } - rc.erase(*it); - } - - while (rc.size()) { - R nmax = R(0); size_type cmax = size_type(-1); - for (std::set::iterator it=rc.begin(); it != rc.end();) { - TAB::iterator itnext = it; ++itnext; - R n = vect_norm2(mat_col(B, *it)); - if (nmax < n) { nmax = n; cmax = *it; } - if (n < R(EPS)) { columns.erase(*it); rc.erase(*it); } - it = itnext; - } - - if (nmax < R(EPS)) break; - - gmm::scale(mat_col(B, cmax), T(1)/vect_norm2(mat_col(B, cmax))); - rc.erase(cmax); - for (std::set::iterator it=rc.begin(); it!=rc.end(); ++it) { - T r = -vect_hp(mat_col(B, *it), mat_col(B, cmax)); - if (r != T(0)) add(scaled(mat_col(B, cmax), r), mat_col(B, *it)); - } - } - for (std::set::iterator it=rc.begin(); it!=rc.end(); ++it) - columns.erase(*it); - } - - - // Range basis with Gram-Schmidt orthogonalization (dense version) - template - void range_basis_eff_Gram_Schmidt_dense(const Mat &B, - std::set &columns, - std::vector &c_ortho, - double EPS) { - - typedef std::set TAB; - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - size_type nc_r = columns.size(), nc = mat_ncols(B), nr = mat_nrows(B), i; - std::set rc; - - row_matrix< gmm::rsvector > H(nc, nc_r), BB(nr, nc_r); - std::vector v(nc_r); - std::vector ind(nc_r); - - i = 0; - for (TAB::iterator it = columns.begin(); it != columns.end(); ++it, ++i) - H(*it, i) = T(1) / vect_norm2(mat_col(B, *it)); - - mult(B, H, BB); - dense_matrix M(nc_r, nc_r); - mult(gmm::conjugated(BB), BB, M); - - i = 0; - for (TAB::iterator it = columns.begin(); it != columns.end(); ++it, ++i) - if (c_ortho[*it]) { - gmm::copy(mat_row(M, i), v); - rank_one_update(M, scaled(v, T(-1)), v); - M(i, i) = T(1); - } - else { rc.insert(i); ind[i] = *it; } - - while (rc.size() > 0) { - - // Next pivot - R nmax = R(0); size_type imax = size_type(-1); - for (TAB::iterator it = rc.begin(); it != rc.end();) { - TAB::iterator itnext = it; ++itnext; - R a = gmm::abs(M(*it, *it)); - if (a > nmax) { nmax = a; imax = *it; } - if (a < R(EPS)) { columns.erase(ind[*it]); rc.erase(*it); } - it = itnext; - } - - if (nmax < R(EPS)) break; - - // Normalization - gmm::scale(mat_row(M, imax), T(1) / sqrt(nmax)); - gmm::scale(mat_col(M, imax), T(1) / sqrt(nmax)); - - // orthogonalization - copy(mat_row(M, imax), v); - rank_one_update(M, scaled(v, T(-1)), v); - M(imax, imax) = T(1); - - rc.erase(imax); - } - for (std::set::iterator it=rc.begin(); it!=rc.end(); ++it) - columns.erase(ind[*it]); - } - - template size_type nnz_eps(const L& l, double eps) { - typename linalg_traits::const_iterator it = vect_const_begin(l), - ite = vect_const_end(l); - size_type res(0); - for (; it != ite; ++it) if (gmm::abs(*it) >= eps) ++res; - return res; - } - - template - bool reserve__rb(const L& l, std::vector &b, double eps) { - typename linalg_traits::const_iterator it = vect_const_begin(l), - ite = vect_const_end(l); - bool ok = true; - for (; it != ite; ++it) - if (gmm::abs(*it) >= eps && b[it.index()]) ok = false; - if (ok) { - for (it = vect_const_begin(l); it != ite; ++it) - if (gmm::abs(*it) >= eps) b[it.index()] = true; - } - return ok; - } - - template - void range_basis(const Mat &B, std::set &columns, - double EPS, col_major, bool skip_init=false) { - - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - size_type nc = mat_ncols(B), nr = mat_nrows(B); - - std::vector norms(nc); - std::vector c_ortho(nc), booked(nr); - std::vector< std::set > nnzs(mat_nrows(B)); - - if (!skip_init) { - - R norm_max = R(0); - for (size_type i = 0; i < nc; ++i) { - norms[i] = vect_norminf(mat_col(B, i)); - norm_max = std::max(norm_max, norms[i]); - } - - columns.clear(); - for (size_type i = 0; i < nc; ++i) - if (norms[i] > norm_max*R(EPS)) { - columns.insert(i); - nnzs[nnz_eps(mat_col(B, i), R(EPS) * norms[i])].insert(i); - } - - for (size_type i = 1; i < nr; ++i) - for (std::set::iterator it = nnzs[i].begin(); - it != nnzs[i].end(); ++it) - if (reserve__rb(mat_col(B, *it), booked, R(EPS) * norms[*it])) - c_ortho[*it] = true; - } - - size_type sizesm[7] = {125, 200, 350, 550, 800, 1100, 1500}, actsize; - for (int k = 0; k < 7; ++k) { - size_type nc_r = columns.size(); - std::set c1, cres; - actsize = sizesm[k]; - for (std::set::iterator it = columns.begin(); - it != columns.end(); ++it) { - c1.insert(*it); - if (c1.size() >= actsize) { - range_basis_eff_Gram_Schmidt_dense(B, c1, c_ortho, EPS); - for (std::set::iterator it2=c1.begin(); it2 != c1.end(); - ++it2) cres.insert(*it2); - c1.clear(); - } - } - if (c1.size() > 1) - range_basis_eff_Gram_Schmidt_dense(B, c1, c_ortho, EPS); - for (std::set::iterator it = c1.begin(); it != c1.end(); ++it) - cres.insert(*it); - columns = cres; - if (nc_r <= actsize) return; - if (columns.size() == nc_r) break; - if (sizesm[k] >= 350 && columns.size() > (nc_r*19)/20) break; - } - if (columns.size() > std::max(size_type(10), actsize)) - range_basis_eff_Lanczos(B, columns, EPS); - else - range_basis_eff_Gram_Schmidt_dense(B, columns, c_ortho, EPS); - } - - - template - void range_basis(const Mat &B, std::set &columns, - double EPS, row_major) { - typedef typename linalg_traits::value_type T; - gmm::col_matrix< rsvector > BB(mat_nrows(B), mat_ncols(B)); - GMM_WARNING3("A copy of a row matrix is done into a column matrix " - "for range basis algorithm."); - gmm::copy(B, BB); - range_basis(BB, columns, EPS); - } - - /** Range Basis : - Extract a basis of the range of a (large sparse) matrix selecting some - column vectors of this matrix. This is in particular useful to select - an independent set of linear constraints. - - The algorithm is optimized for two cases : - - when the (non trivial) kernel is small. An iterativ algorithm - based on Lanczos method is applied - - when the (non trivial) kernel is large and most of the dependencies - can be detected locally. A block Gram-Schmidt is applied first then - a restarted Lanczos method when the remaining kernel is greatly - smaller. - The restarted Lanczos method could be improved or replaced by a block - Lanczos method, a block Wiedelann method (in order to be parallelized for - instance) or simply could compute more than one vector of the null - space at each iteration. - The LU decomposition has been tested for local elimination but gives bad - results : the algorithm is unstable and do not permit to give the right - number of vector at the end of the process. Moreover, the number of final - vectors depends greatly on the number of vectors in a block of the local - analysis. - */ - template - void range_basis(const Mat &B, std::set &columns, - double EPS=1E-12) { - range_basis(B, columns, EPS, - typename principal_orientation_type - ::sub_orientation>::potype()); -} - -} - -#endif diff --git a/gmm/gmm_real_part.h b/gmm/gmm_real_part.h deleted file mode 100644 index c4e61d815..000000000 --- a/gmm/gmm_real_part.h +++ /dev/null @@ -1,605 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_real_part.h - @author Yves Renard - @date September 18, 2003. - @brief extract the real/imaginary part of vectors/matrices -*/ -#ifndef GMM_REAL_PART_H -#define GMM_REAL_PART_H - -#include "gmm_def.h" -#include "gmm_vector.h" - -namespace gmm { - - struct linalg_real_part {}; - struct linalg_imag_part {}; - template struct which_part {}; - - template typename number_traits::magnitude_type - real_or_imag_part(C x, linalg_real_part) { return gmm::real(x); } - template typename number_traits::magnitude_type - real_or_imag_part(C x, linalg_imag_part) { return gmm::imag(x); } - template C - complex_from(T x, C y, OP op, linalg_real_part) { return std::complex(op(std::real(y), x), std::imag(y)); } - template C - complex_from(T x, C y, OP op,linalg_imag_part) { return std::complex(std::real(y), op(std::imag(y), x)); } - - template struct project2nd { - T operator()(T , T b) const { return b; } - }; - - template class ref_elt_vector > { - - R r; - - public : - - operator T() const { return real_or_imag_part(std::complex(r), PART()); } - ref_elt_vector(R r_) : r(r_) {} - inline ref_elt_vector &operator =(T v) - { r = complex_from(v, std::complex(r), gmm::project2nd(), PART()); return *this; } - inline bool operator ==(T v) const { return (r == v); } - inline bool operator !=(T v) const { return (r != v); } - inline ref_elt_vector &operator +=(T v) - { r = complex_from(v, std::complex(r), std::plus(), PART()); return *this; } - inline ref_elt_vector &operator -=(T v) - { r = complex_from(v, std::complex(r), std::minus(), PART()); return *this; } - inline ref_elt_vector &operator /=(T v) - { r = complex_from(v, std::complex(r), std::divides(), PART()); return *this; } - inline ref_elt_vector &operator *=(T v) - { r = complex_from(v, std::complex(r), std::multiplies(), PART()); return *this; } - inline ref_elt_vector &operator =(const ref_elt_vector &re) - { *this = T(re); return *this; } - T operator +() { return T(*this); } // necessary for unknow reason - T operator -() { return -T(*this); } // necessary for unknow reason - T operator +(T v) { return T(*this)+ v; } // necessary for unknow reason - T operator -(T v) { return T(*this)- v; } // necessary for unknow reason - T operator *(T v) { return T(*this)* v; } // necessary for unknow reason - T operator /(T v) { return T(*this)/ v; } // necessary for unknow reason - }; - - template struct ref_or_value_type { - template - static W r(const T &x, linalg_real_part, W) { - return gmm::real(x); - } - template - static W r(const T &x, linalg_imag_part, W) { - return gmm::imag(x); - } - }; - - template - struct ref_or_value_type > > { - template - static const T &r(const T &x, linalg_real_part, W) - { return x; } - template - static const T &r(const T &x, linalg_imag_part, W) { - return x; - } - template - static T &r(T &x, linalg_real_part, W) - { return x; } - template - static T &r(T &x, linalg_imag_part, W) { - return x; - } - }; - - - /* ********************************************************************* */ - /* Reference to the real part of (complex) vectors */ - /* ********************************************************************* */ - - template - struct part_vector_iterator { - typedef typename std::iterator_traits::value_type vtype; - typedef typename gmm::number_traits::magnitude_type value_type; - typedef value_type *pointer; - typedef ref_elt_vector::reference, PART> > reference; - typedef typename std::iterator_traits::difference_type difference_type; - typedef typename std::iterator_traits::iterator_category - iterator_category; - - IT it; - - part_vector_iterator(void) {} - explicit part_vector_iterator(const IT &i) : it(i) {} - part_vector_iterator(const part_vector_iterator &i) : it(i.it) {} - - - size_type index(void) const { return it.index(); } - part_vector_iterator operator ++(int) - { part_vector_iterator tmp = *this; ++it; return tmp; } - part_vector_iterator operator --(int) - { part_vector_iterator tmp = *this; --it; return tmp; } - part_vector_iterator &operator ++() { ++it; return *this; } - part_vector_iterator &operator --() { --it; return *this; } - part_vector_iterator &operator +=(difference_type i) - { it += i; return *this; } - part_vector_iterator &operator -=(difference_type i) - { it -= i; return *this; } - part_vector_iterator operator +(difference_type i) const - { part_vector_iterator itb = *this; return (itb += i); } - part_vector_iterator operator -(difference_type i) const - { part_vector_iterator itb = *this; return (itb -= i); } - difference_type operator -(const part_vector_iterator &i) const - { return difference_type(it - i.it); } - - reference operator *() const { return reference(*it); } - reference operator [](size_type ii) const { return reference(it[ii]); } - - bool operator ==(const part_vector_iterator &i) const - { return (i.it == it); } - bool operator !=(const part_vector_iterator &i) const - { return (i.it != it); } - bool operator < (const part_vector_iterator &i) const - { return (it < i.it); } - }; - - - template struct part_vector { - typedef part_vector this_type; - typedef typename std::iterator_traits::value_type V; - typedef V * CPT; - typedef typename select_ref::const_iterator, - typename linalg_traits::iterator, PT>::ref_type iterator; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::value_type value_type; - typedef typename linalg_traits::porigin_type porigin_type; - - iterator begin_, end_; - porigin_type origin; - size_type size_; - - size_type size(void) const { return size_; } - - reference operator[](size_type i) const { - return reference(ref_or_value_type::r( - linalg_traits::access(origin, begin_, end_, i), - PART(), value_type())); - } - - part_vector(V &v) - : begin_(vect_begin(v)), end_(vect_end(v)), - origin(linalg_origin(v)), size_(gmm::vect_size(v)) {} - part_vector(const V &v) - : begin_(vect_begin(const_cast(v))), - end_(vect_end(const_cast(v))), - origin(linalg_origin(const_cast(v))), size_(gmm::vect_size(v)) {} - part_vector() {} - part_vector(const part_vector &cr) - : begin_(cr.begin_),end_(cr.end_),origin(cr.origin), size_(cr.size_) {} - }; - - template inline - void set_to_begin(part_vector_iterator &it, - ORG o, part_vector *, linalg_modifiable) { - typedef part_vector VECT; - typedef typename linalg_traits::V_reference ref_t; - set_to_begin(it.it, o, typename linalg_traits::pV(), ref_t()); - } - template inline - void set_to_begin(part_vector_iterator &it, - ORG o, const part_vector *, linalg_modifiable) { - typedef part_vector VECT; - typedef typename linalg_traits::V_reference ref_t; - set_to_begin(it.it, o, typename linalg_traits::pV(), ref_t()); - } - template inline - void set_to_end(part_vector_iterator &it, - ORG o, part_vector *, linalg_modifiable) { - typedef part_vector VECT; - typedef typename linalg_traits::V_reference ref_t; - set_to_end(it.it, o, typename linalg_traits::pV(), ref_t()); - } - template inline - void set_to_end(part_vector_iterator &it, - ORG o, const part_vector *, - linalg_modifiable) { - typedef part_vector VECT; - typedef typename linalg_traits::V_reference ref_t; - set_to_end(it.it, o, typename linalg_traits::pV(), ref_t()); - } - - template std::ostream &operator << - (std::ostream &o, const part_vector& m) - { gmm::write(o,m); return o; } - - - /* ********************************************************************* */ - /* Reference to the real or imaginary part of (complex) matrices */ - /* ********************************************************************* */ - - - template struct part_row_ref { - - typedef part_row_ref this_type; - typedef typename std::iterator_traits::value_type M; - typedef M * CPT; - typedef typename std::iterator_traits::reference ref_M; - typedef typename select_ref - ::const_row_iterator, typename linalg_traits - ::row_iterator, PT>::ref_type iterator; - typedef typename linalg_traits::value_type value_type; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::porigin_type porigin_type; - - iterator begin_, end_; - porigin_type origin; - size_type nr, nc; - - part_row_ref(ref_M m) - : begin_(mat_row_begin(m)), end_(mat_row_end(m)), - origin(linalg_origin(m)), nr(mat_nrows(m)), nc(mat_ncols(m)) {} - - part_row_ref(const part_row_ref &cr) : - begin_(cr.begin_),end_(cr.end_), origin(cr.origin),nr(cr.nr),nc(cr.nc) {} - - reference operator()(size_type i, size_type j) const { - return reference(ref_or_value_type::r( - linalg_traits::access(begin_+i, j), - PART(), value_type())); - } - }; - - template std::ostream &operator << - (std::ostream &o, const part_row_ref& m) - { gmm::write(o,m); return o; } - - template struct part_col_ref { - - typedef part_col_ref this_type; - typedef typename std::iterator_traits::value_type M; - typedef M * CPT; - typedef typename std::iterator_traits::reference ref_M; - typedef typename select_ref - ::const_col_iterator, typename linalg_traits - ::col_iterator, PT>::ref_type iterator; - typedef typename linalg_traits::value_type value_type; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::porigin_type porigin_type; - - iterator begin_, end_; - porigin_type origin; - size_type nr, nc; - - part_col_ref(ref_M m) - : begin_(mat_col_begin(m)), end_(mat_col_end(m)), - origin(linalg_origin(m)), nr(mat_nrows(m)), nc(mat_ncols(m)) {} - - part_col_ref(const part_col_ref &cr) : - begin_(cr.begin_),end_(cr.end_), origin(cr.origin),nr(cr.nr),nc(cr.nc) {} - - reference operator()(size_type i, size_type j) const { - return reference(ref_or_value_type::r( - linalg_traits::access(begin_+j, i), - PART(), value_type())); - } - }; - - - - template std::ostream &operator << - (std::ostream &o, const part_col_ref& m) - { gmm::write(o,m); return o; } - - - - - - -template - struct part_return_ { - typedef abstract_null_type return_type; - }; - template - struct part_return_ { - typedef typename std::iterator_traits::value_type L; - typedef typename select_return, - part_row_ref< L *, PART>, PT>::return_type return_type; - }; - template - struct part_return_ { - typedef typename std::iterator_traits::value_type L; - typedef typename select_return, - part_col_ref, PT>::return_type return_type; - }; - - template struct part_return__{ - typedef abstract_null_type return_type; - }; - - template - struct part_return__ { - typedef typename std::iterator_traits::value_type L; - typedef typename part_return_::sub_orientation>::potype, PART, - PT>::return_type return_type; - }; - - template - struct part_return__ { - typedef typename std::iterator_traits::value_type L; - typedef typename select_return, - part_vector, PT>::return_type return_type; - }; - - template struct part_return { - typedef typename std::iterator_traits::value_type L; - typedef typename part_return__::linalg_type>::return_type return_type; - }; - - template inline - typename part_return::return_type - real_part(const L &l) { - return typename part_return::return_type - (linalg_cast(const_cast(l))); - } - - template inline - typename part_return::return_type - real_part(L &l) { - return typename part_return::return_type(linalg_cast(l)); - } - - template inline - typename part_return::return_type - imag_part(const L &l) { - return typename part_return::return_type - (linalg_cast(const_cast(l))); - } - - template inline - typename part_return::return_type - imag_part(L &l) { - return typename part_return::return_type(linalg_cast(l)); - } - - - template - struct linalg_traits > { - typedef part_vector this_type; - typedef this_type * pthis_type; - typedef PT pV; - typedef typename std::iterator_traits::value_type V; - typedef typename linalg_traits::index_sorted index_sorted; - typedef typename linalg_traits::is_reference V_reference; - typedef typename linalg_traits::origin_type origin_type; - typedef typename select_ref::ref_type porigin_type; - typedef typename which_reference::is_reference is_reference; - typedef abstract_vector linalg_type; - typedef typename linalg_traits::value_type vtype; - typedef typename number_traits::magnitude_type value_type; - typedef typename select_ref::reference, - PART> >, PT>::ref_type reference; - typedef typename select_ref::const_iterator, - typename linalg_traits::iterator, PT>::ref_type pre_iterator; - typedef typename select_ref, - PT>::ref_type iterator; - typedef part_vector_iterator::const_iterator, - pre_iterator, PART> const_iterator; - typedef typename linalg_traits::storage_type storage_type; - static size_type size(const this_type &v) { return v.size(); } - static iterator begin(this_type &v) { - iterator it; it.it = v.begin_; - if (!is_const_reference(is_reference()) && is_sparse(storage_type())) - set_to_begin(it, v.origin, pthis_type(), is_reference()); - return it; - } - static const_iterator begin(const this_type &v) { - const_iterator it(v.begin_); - if (!is_const_reference(is_reference()) && is_sparse(storage_type())) - { set_to_begin(it, v.origin, pthis_type(), is_reference()); } - return it; - } - static iterator end(this_type &v) { - iterator it(v.end_); - if (!is_const_reference(is_reference()) && is_sparse(storage_type())) - set_to_end(it, v.origin, pthis_type(), is_reference()); - return it; - } - static const_iterator end(const this_type &v) { - const_iterator it(v.end_); - if (!is_const_reference(is_reference()) && is_sparse(storage_type())) - set_to_end(it, v.origin, pthis_type(), is_reference()); - return it; - } - static origin_type* origin(this_type &v) { return v.origin; } - static const origin_type* origin(const this_type &v) { return v.origin; } - - static void clear(origin_type* o, const iterator &begin_, - const iterator &end_, abstract_sparse) { - std::deque ind; - iterator it = begin_; - for (; it != end_; ++it) ind.push_front(it.index()); - for (; !(ind.empty()); ind.pop_back()) - access(o, begin_, end_, ind.back()) = value_type(0); - } - static void clear(origin_type* o, const iterator &begin_, - const iterator &end_, abstract_skyline) { - clear(o, begin_, end_, abstract_sparse()); - } - static void clear(origin_type* o, const iterator &begin_, - const iterator &end_, abstract_dense) { - for (iterator it = begin_; it != end_; ++it) *it = value_type(0); - } - - static void clear(origin_type* o, const iterator &begin_, - const iterator &end_) - { clear(o, begin_, end_, storage_type()); } - static void do_clear(this_type &v) { clear(v.origin, begin(v), end(v)); } - static value_type access(const origin_type *o, const const_iterator &it, - const const_iterator &ite, size_type i) { - return real_or_imag_part(linalg_traits::access(o, it.it, ite.it,i), - PART()); - } - static reference access(origin_type *o, const iterator &it, - const iterator &ite, size_type i) - { return reference(linalg_traits::access(o, it.it, ite.it,i)); } - }; - - template - struct linalg_traits > { - typedef part_row_ref this_type; - typedef typename std::iterator_traits::value_type M; - typedef typename linalg_traits::origin_type origin_type; - typedef typename select_ref::ref_type porigin_type; - typedef typename which_reference::is_reference is_reference; - typedef abstract_matrix linalg_type; - typedef typename linalg_traits::value_type vtype; - typedef typename number_traits::magnitude_type value_type; - typedef typename linalg_traits::storage_type storage_type; - typedef abstract_null_type sub_col_type; - typedef abstract_null_type const_sub_col_type; - typedef abstract_null_type col_iterator; - typedef abstract_null_type const_col_iterator; - typedef typename org_type::const_sub_row_type>::t - pre_const_sub_row_type; - typedef typename org_type::sub_row_type>::t pre_sub_row_type; - typedef part_vector - const_sub_row_type; - typedef typename select_ref, PT>::ref_type sub_row_type; - typedef typename linalg_traits::const_row_iterator const_row_iterator; - typedef typename select_ref::row_iterator, PT>::ref_type row_iterator; - typedef typename select_ref< - typename linalg_traits::reference, - typename linalg_traits::reference, - PT>::ref_type reference; - typedef row_major sub_orientation; - typedef typename linalg_traits::index_sorted index_sorted; - static size_type ncols(const this_type &v) { return v.nc; } - static size_type nrows(const this_type &v) { return v.nr; } - static const_sub_row_type row(const const_row_iterator &it) - { return const_sub_row_type(linalg_traits::row(it)); } - static sub_row_type row(const row_iterator &it) - { return sub_row_type(linalg_traits::row(it)); } - static row_iterator row_begin(this_type &m) { return m.begin_; } - static row_iterator row_end(this_type &m) { return m.end_; } - static const_row_iterator row_begin(const this_type &m) - { return m.begin_; } - static const_row_iterator row_end(const this_type &m) { return m.end_; } - static origin_type* origin(this_type &v) { return v.origin; } - static const origin_type* origin(const this_type &v) { return v.origin; } - static void do_clear(this_type &v); - static value_type access(const const_row_iterator &itrow, size_type i) - { return real_or_imag_part(linalg_traits::access(itrow, i), PART()); } - static reference access(const row_iterator &itrow, size_type i) { - return reference(ref_or_value_type::r( - linalg_traits::access(itrow, i), - PART(), value_type())); - } - }; - - template - struct linalg_traits > { - typedef part_col_ref this_type; - typedef typename std::iterator_traits::value_type M; - typedef typename linalg_traits::origin_type origin_type; - typedef typename select_ref::ref_type porigin_type; - typedef typename which_reference::is_reference is_reference; - typedef abstract_matrix linalg_type; - typedef typename linalg_traits::value_type vtype; - typedef typename number_traits::magnitude_type value_type; - typedef typename linalg_traits::storage_type storage_type; - typedef abstract_null_type sub_row_type; - typedef abstract_null_type const_sub_row_type; - typedef abstract_null_type row_iterator; - typedef abstract_null_type const_row_iterator; - typedef typename org_type::const_sub_col_type>::t - pre_const_sub_col_type; - typedef typename org_type::sub_col_type>::t pre_sub_col_type; - typedef part_vector - const_sub_col_type; - typedef typename select_ref, PT>::ref_type sub_col_type; - typedef typename linalg_traits::const_col_iterator const_col_iterator; - typedef typename select_ref::col_iterator, PT>::ref_type col_iterator; - typedef typename select_ref< - typename linalg_traits::reference, - typename linalg_traits::reference, - PT>::ref_type reference; - typedef col_major sub_orientation; - typedef typename linalg_traits::index_sorted index_sorted; - static size_type nrows(const this_type &v) { return v.nr; } - static size_type ncols(const this_type &v) { return v.nc; } - static const_sub_col_type col(const const_col_iterator &it) - { return const_sub_col_type(linalg_traits::col(it)); } - static sub_col_type col(const col_iterator &it) - { return sub_col_type(linalg_traits::col(it)); } - static col_iterator col_begin(this_type &m) { return m.begin_; } - static col_iterator col_end(this_type &m) { return m.end_; } - static const_col_iterator col_begin(const this_type &m) - { return m.begin_; } - static const_col_iterator col_end(const this_type &m) { return m.end_; } - static origin_type* origin(this_type &v) { return v.origin; } - static const origin_type* origin(const this_type &v) { return v.origin; } - static void do_clear(this_type &v); - static value_type access(const const_col_iterator &itcol, size_type i) - { return real_or_imag_part(linalg_traits::access(itcol, i), PART()); } - static reference access(const col_iterator &itcol, size_type i) { - return reference(ref_or_value_type::r( - linalg_traits::access(itcol, i), - PART(), value_type())); - } - }; - - template - void linalg_traits >::do_clear(this_type &v) { - col_iterator it = mat_col_begin(v), ite = mat_col_end(v); - for (; it != ite; ++it) clear(col(it)); - } - - template - void linalg_traits >::do_clear(this_type &v) { - row_iterator it = mat_row_begin(v), ite = mat_row_end(v); - for (; it != ite; ++it) clear(row(it)); - } -} - -#endif // GMM_REAL_PART_H diff --git a/gmm/gmm_ref.h b/gmm/gmm_ref.h deleted file mode 100644 index 67af37739..000000000 --- a/gmm/gmm_ref.h +++ /dev/null @@ -1,526 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2000-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - - -#ifndef GMM_REF_H__ -#define GMM_REF_H__ - -/** @file gmm_ref.h - @author Yves Renard - @date August 26, 2000. - * @brief Provide some simple pseudo-containers. - * - * WARNING : modifiying the container infirm the validity of references. - */ - - -#include -#include "gmm_except.h" - -namespace gmm { - - /* ********************************************************************* */ - /* Simple reference. */ - /* ********************************************************************* */ - - template class tab_ref { - - protected : - - ITER begin_, end_; - - public : - - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::pointer pointer; - typedef typename std::iterator_traits::pointer const_pointer; - typedef typename std::iterator_traits::reference reference; - typedef typename std::iterator_traits::reference const_reference; - typedef typename std::iterator_traits::difference_type - difference_type; - typedef ITER iterator; - typedef ITER const_iterator; - typedef std::reverse_iterator const_reverse_iterator; - typedef std::reverse_iterator reverse_iterator; - typedef size_t size_type; - - bool empty(void) const { return begin_ == end_; } - size_type size(void) const { return end_ - begin_; } - - const iterator &begin(void) { return begin_; } - const const_iterator &begin(void) const { return begin_; } - const iterator &end(void) { return end_; } - const const_iterator &end(void) const { return end_; } - reverse_iterator rbegin(void) { return reverse_iterator(end()); } - const_reverse_iterator rbegin(void) const - { return const_reverse_iterator(end()); } - reverse_iterator rend(void) { return reverse_iterator(begin()); } - const_reverse_iterator rend(void) const - { return const_reverse_iterator(begin()); } - - reference front(void) { return *begin(); } - const_reference front(void) const { return *begin(); } - reference back(void) { return *(--(end())); } - const_reference back(void) const { return *(--(end())); } - void pop_front(void) { ++begin_; } - - const_reference operator [](size_type ii) const { return *(begin_ + ii);} - reference operator [](size_type ii) { return *(begin_ + ii); } - - tab_ref(void) {} - tab_ref(const ITER &b, const ITER &e) : begin_(b), end_(e) {} - }; - - - /* ********************************************************************* */ - /* Reference with index. */ - /* ********************************************************************* */ - -// template struct tab_ref_index_iterator_ -// : public dynamic_array::const_iterator -// { -// typedef typename std::iterator_traits::value_type value_type; -// typedef typename std::iterator_traits::pointer pointer; -// typedef typename std::iterator_traits::reference reference; -// typedef typename std::iterator_traits::difference_type -// difference_type; -// typedef std::random_access_iterator_tag iterator_category; -// typedef size_t size_type; -// typedef dynamic_array::const_iterator dnas_iterator_; -// typedef tab_ref_index_iterator_ iterator; - - -// ITER piter; - -// iterator operator ++(int) -// { iterator tmp = *this; ++(*((dnas_iterator_ *)(this))); return tmp; } -// iterator operator --(int) -// { iterator tmp = *this; --(*((dnas_iterator_ *)(this))); return tmp; } -// iterator &operator ++() -// { ++(*((dnas_iterator_ *)(this))); return *this; } -// iterator &operator --() -// { --(*((dnas_iterator_ *)(this))); return *this; } -// iterator &operator +=(difference_type i) -// { (*((dnas_iterator_ *)(this))) += i; return *this; } -// iterator &operator -=(difference_type i) -// { (*((dnas_iterator_ *)(this))) -= i; return *this; } -// iterator operator +(difference_type i) const -// { iterator it = *this; return (it += i); } -// iterator operator -(difference_type i) const -// { iterator it = *this; return (it -= i); } -// difference_type operator -(const iterator &i) const -// { return *((dnas_iterator_ *)(this)) - *((dnas_iterator_ *)(&i)); } - -// reference operator *() const -// { return *(piter + *((*((dnas_iterator_ *)(this))))); } -// reference operator [](int ii) -// { return *(piter + *((*((dnas_iterator_ *)(this+ii))))); } - -// bool operator ==(const iterator &i) const -// { -// return ((piter) == ((i.piter)) -// && *((dnas_iterator_ *)(this)) == *((*((dnas_iterator_ *)(this))))); -// } -// bool operator !=(const iterator &i) const -// { return !(i == *this); } -// bool operator < (const iterator &i) const -// { -// return ((piter) == ((i.piter)) -// && *((dnas_iterator_ *)(this)) < *((*((dnas_iterator_ *)(this))))); -// } - -// tab_ref_index_iterator_(void) {} -// tab_ref_index_iterator_(const ITER &iter, const dnas_iterator_ &dnas_iter) -// : dnas_iterator_(dnas_iter), piter(iter) {} -// }; - - -// template class tab_ref_index -// { -// public : - -// typedef typename std::iterator_traits::value_type value_type; -// typedef typename std::iterator_traits::pointer pointer; -// typedef typename std::iterator_traits::pointer const_pointer; -// typedef typename std::iterator_traits::reference reference; -// typedef typename std::iterator_traits::reference const_reference; -// typedef typename std::iterator_traits::difference_type -// difference_type; -// typedef size_t size_type; -// typedef tab_ref_index_iterator_ iterator; -// typedef iterator const_iterator; -// typedef std::reverse_iterator const_reverse_iterator; -// typedef std::reverse_iterator reverse_iterator; - -// protected : - -// ITER begin_; -// dynamic_array index_; - -// public : - -// bool empty(void) const { return index_.empty(); } -// size_type size(void) const { return index_.size(); } - - -// iterator begin(void) { return iterator(begin_, index_.begin()); } -// const_iterator begin(void) const -// { return iterator(begin_, index_.begin()); } -// iterator end(void) { return iterator(begin_, index_.end()); } -// const_iterator end(void) const { return iterator(begin_, index_.end()); } -// reverse_iterator rbegin(void) { return reverse_iterator(end()); } -// const_reverse_iterator rbegin(void) const -// { return const_reverse_iterator(end()); } -// reverse_iterator rend(void) { return reverse_iterator(begin()); } -// const_reverse_iterator rend(void) const -// { return const_reverse_iterator(begin()); } - - -// reference front(void) { return *(begin_ +index_[0]); } -// const_reference front(void) const { return *(begin_ +index_[0]); } -// reference back(void) { return *(--(end())); } -// const_reference back(void) const { return *(--(end())); } - -// tab_ref_index(void) {} -// tab_ref_index(const ITER &b, const dynamic_array &ind) -// { begin_ = b; index_ = ind; } - -// // to be changed in a const_reference ? -// value_type operator [](size_type ii) const -// { return *(begin_ + index_[ii]);} -// reference operator [](size_type ii) { return *(begin_ + index_[ii]); } - -// }; - - - /// iterator over a gmm::tab_ref_index_ref - template - struct tab_ref_index_ref_iterator_ - { - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::pointer pointer; - typedef typename std::iterator_traits::reference reference; - typedef typename std::iterator_traits::difference_type - difference_type; - typedef std::random_access_iterator_tag iterator_category; - typedef tab_ref_index_ref_iterator_ iterator; - typedef size_t size_type; - - ITER piter; - ITER_INDEX iter_index; - - iterator operator ++(int) - { iterator tmp = *this; ++iter_index; return tmp; } - iterator operator --(int) - { iterator tmp = *this; --iter_index; return tmp; } - iterator &operator ++() { ++iter_index; return *this; } - iterator &operator --() { --iter_index; return *this; } - iterator &operator +=(difference_type i) - { iter_index += i; return *this; } - iterator &operator -=(difference_type i) - { iter_index -= i; return *this; } - iterator operator +(difference_type i) const - { iterator it = *this; return (it += i); } - iterator operator -(difference_type i) const - { iterator it = *this; return (it -= i); } - difference_type operator -(const iterator &i) const - { return iter_index - i.iter_index; } - - reference operator *() const - { return *(piter + *iter_index); } - reference operator [](size_type ii) const - { return *(piter + *(iter_index+ii)); } - - bool operator ==(const iterator &i) const - { return ((piter) == ((i.piter)) && iter_index == i.iter_index); } - bool operator !=(const iterator &i) const { return !(i == *this); } - bool operator < (const iterator &i) const - { return ((piter) == ((i.piter)) && iter_index < i.iter_index); } - - tab_ref_index_ref_iterator_(void) {} - tab_ref_index_ref_iterator_(const ITER &iter, - const ITER_INDEX &dnas_iter) - : piter(iter), iter_index(dnas_iter) {} - - }; - - /** - convenience template function for quick obtention of a indexed iterator - without having to specify its (long) typename - */ - template - tab_ref_index_ref_iterator_ - index_ref_iterator(ITER it, ITER_INDEX it_i) { - return tab_ref_index_ref_iterator_(it, it_i); - } - - /** indexed array reference (given a container X, and a set of indexes I, - this class provides a pseudo-container Y such that - @code Y[i] = X[I[i]] @endcode - */ - template class tab_ref_index_ref { - public : - - typedef std::iterator_traits traits_type; - typedef typename traits_type::value_type value_type; - typedef typename traits_type::pointer pointer; - typedef typename traits_type::pointer const_pointer; - typedef typename traits_type::reference reference; - typedef typename traits_type::reference const_reference; - typedef typename traits_type::difference_type difference_type; - typedef size_t size_type; - typedef tab_ref_index_ref_iterator_ iterator; - typedef iterator const_iterator; - typedef std::reverse_iterator const_reverse_iterator; - typedef std::reverse_iterator reverse_iterator; - - protected : - - ITER begin_; - ITER_INDEX index_begin_, index_end_; - - public : - - bool empty(void) const { return index_begin_ == index_end_; } - size_type size(void) const { return index_end_ - index_begin_; } - - iterator begin(void) { return iterator(begin_, index_begin_); } - const_iterator begin(void) const - { return iterator(begin_, index_begin_); } - iterator end(void) { return iterator(begin_, index_end_); } - const_iterator end(void) const { return iterator(begin_, index_end_); } - reverse_iterator rbegin(void) { return reverse_iterator(end()); } - const_reverse_iterator rbegin(void) const - { return const_reverse_iterator(end()); } - reverse_iterator rend(void) { return reverse_iterator(begin()); } - const_reverse_iterator rend(void) const - { return const_reverse_iterator(begin()); } - - reference front(void) { return *(begin_ + *index_begin_); } - const_reference front(void) const { return *(begin_ + *index_begin_); } - reference back(void) { return *(--(end())); } - const_reference back(void) const { return *(--(end())); } - void pop_front(void) { ++index_begin_; } - - tab_ref_index_ref(void) {} - tab_ref_index_ref(const ITER &b, const ITER_INDEX &bi, - const ITER_INDEX &ei) - : begin_(b), index_begin_(bi), index_end_(ei) {} - - // to be changed in a const_reference ? - const_reference operator [](size_type ii) const - { return *(begin_ + index_begin_[ii]);} - reference operator [](size_type ii) - { return *(begin_ + index_begin_[ii]); } - - }; - - - /* ********************************************************************* */ - /* Reference on regularly spaced elements. */ - /* ********************************************************************* */ - - template struct tab_ref_reg_spaced_iterator_ { - - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::pointer pointer; - typedef typename std::iterator_traits::reference reference; - typedef typename std::iterator_traits::difference_type - difference_type; - typedef typename std::iterator_traits::iterator_category - iterator_category; - typedef size_t size_type; - typedef tab_ref_reg_spaced_iterator_ iterator; - - ITER it; - size_type N, i; - - iterator operator ++(int) { iterator tmp = *this; i++; return tmp; } - iterator operator --(int) { iterator tmp = *this; i--; return tmp; } - iterator &operator ++() { i++; return *this; } - iterator &operator --() { i--; return *this; } - iterator &operator +=(difference_type ii) { i+=ii; return *this; } - iterator &operator -=(difference_type ii) { i-=ii; return *this; } - iterator operator +(difference_type ii) const - { iterator itt = *this; return (itt += ii); } - iterator operator -(difference_type ii) const - { iterator itt = *this; return (itt -= ii); } - difference_type operator -(const iterator &ii) const - { return (N ? (it - ii.it) / N : 0) + i - ii.i; } - - reference operator *() const { return *(it + i*N); } - reference operator [](size_type ii) const { return *(it + (i+ii)*N); } - - bool operator ==(const iterator &ii) const - { return (*this - ii) == difference_type(0); } - bool operator !=(const iterator &ii) const - { return (*this - ii) != difference_type(0); } - bool operator < (const iterator &ii) const - { return (*this - ii) < difference_type(0); } - - tab_ref_reg_spaced_iterator_(void) {} - tab_ref_reg_spaced_iterator_(const ITER &iter, size_type n, size_type ii) - : it(iter), N(n), i(ii) { } - - }; - - /** - convenience template function for quick obtention of a strided iterator - without having to specify its (long) typename - */ - template tab_ref_reg_spaced_iterator_ - reg_spaced_iterator(ITER it, size_t stride) { - return tab_ref_reg_spaced_iterator_(it, stride); - } - - /** - provide a "strided" view a of container - */ - template class tab_ref_reg_spaced { - public : - - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::pointer pointer; - typedef typename std::iterator_traits::pointer const_pointer; - typedef typename std::iterator_traits::reference reference; - typedef typename std::iterator_traits::reference const_reference; - typedef typename std::iterator_traits::difference_type - difference_type; - typedef size_t size_type; - typedef tab_ref_reg_spaced_iterator_ iterator; - typedef iterator const_iterator; - typedef std::reverse_iterator const_reverse_iterator; - typedef std::reverse_iterator reverse_iterator; - - protected : - - ITER begin_; - size_type N, size_; - - public : - - bool empty(void) const { return size_ == 0; } - size_type size(void) const { return size_; } - - iterator begin(void) { return iterator(begin_, N, 0); } - const_iterator begin(void) const { return iterator(begin_, N, 0); } - iterator end(void) { return iterator(begin_, N, size_); } - const_iterator end(void) const { return iterator(begin_, N, size_); } - reverse_iterator rbegin(void) { return reverse_iterator(end()); } - const_reverse_iterator rbegin(void) const - { return const_reverse_iterator(end()); } - reverse_iterator rend(void) { return reverse_iterator(begin()); } - const_reverse_iterator rend(void) const - { return const_reverse_iterator(begin()); } - - reference front(void) { return *begin_; } - const_reference front(void) const { return *begin_; } - reference back(void) { return *(begin_ + N * (size_-1)); } - const_reference back(void) const { return *(begin_ + N * (size_-1)); } - void pop_front(void) { begin_ += N; } - - tab_ref_reg_spaced(void) {} - tab_ref_reg_spaced(const ITER &b, size_type n, size_type s) - : begin_(b), N(n), size_(s) {} - - - const_reference operator [](size_type ii) const - { return *(begin_ + ii * N);} - reference operator [](size_type ii) { return *(begin_ + ii * N); } - - }; - - /// iterator over a tab_ref_with_selection - template - struct tab_ref_with_selection_iterator_ : public ITER { - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::pointer pointer; - typedef typename std::iterator_traits::reference reference; - typedef typename std::iterator_traits::difference_type - difference_type; - typedef std::forward_iterator_tag iterator_category; - typedef tab_ref_with_selection_iterator_ iterator; - const COND cond; - - void forward(void) { while (!(cond)(*this)) ITER::operator ++(); } - iterator &operator ++() - { ITER::operator ++(); forward(); return *this; } - iterator operator ++(int) - { iterator tmp = *this; ++(*this); return tmp; } - - tab_ref_with_selection_iterator_(void) {} - tab_ref_with_selection_iterator_(const ITER &iter, const COND c) - : ITER(iter), cond(c) {} - - }; - - /** - given a container X and a predicate P, provide pseudo-container Y - of all elements of X such that P(X[i]). - */ - template class tab_ref_with_selection { - - protected : - - ITER begin_, end_; - COND cond; - - public : - - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::pointer pointer; - typedef typename std::iterator_traits::pointer const_pointer; - typedef typename std::iterator_traits::reference reference; - typedef typename std::iterator_traits::reference const_reference; - typedef size_t size_type; - typedef tab_ref_with_selection_iterator_ iterator; - typedef iterator const_iterator; - - iterator begin(void) const - { iterator it(begin_, cond); it.forward(); return it; } - iterator end(void) const { return iterator(end_, cond); } - bool empty(void) const { return begin_ == end_; } - - value_type front(void) const { return *begin(); } - void pop_front(void) { ++begin_; begin_ = begin(); } - - COND &condition(void) { return cond; } - const COND &condition(void) const { return cond; } - - tab_ref_with_selection(void) {} - tab_ref_with_selection(const ITER &b, const ITER &e, const COND &c) - : begin_(b), end_(e), cond(c) { begin_ = begin(); } - - }; - -} - -#endif /* GMM_REF_H__ */ diff --git a/gmm/gmm_scaled.h b/gmm/gmm_scaled.h deleted file mode 100644 index 485af32a1..000000000 --- a/gmm/gmm_scaled.h +++ /dev/null @@ -1,434 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_scaled.h - @author Yves Renard - @date November 10, 2002. - @brief get a scaled view of a vector/matrix. -*/ -#ifndef GMM_SCALED_H__ -#define GMM_SCALED_H__ - -#include "gmm_def.h" - -namespace gmm { - - /* ********************************************************************* */ - /* Scaled references on vectors */ - /* ********************************************************************* */ - - template struct scaled_const_iterator { - typedef typename strongest_numeric_type::value_type, - S>::T value_type; - - typedef typename std::iterator_traits::pointer pointer; - typedef typename std::iterator_traits::reference reference; - typedef typename std::iterator_traits::difference_type difference_type; - typedef typename std::iterator_traits::iterator_category - iterator_category; - - IT it; - S r; - - scaled_const_iterator(void) {} - scaled_const_iterator(const IT &i, S x) : it(i), r(x) {} - - inline size_type index(void) const { return it.index(); } - inline scaled_const_iterator operator ++(int) - { scaled_const_iterator tmp = *this; ++it; return tmp; } - inline scaled_const_iterator operator --(int) - { scaled_const_iterator tmp = *this; --it; return tmp; } - inline scaled_const_iterator &operator ++() { ++it; return *this; } - inline scaled_const_iterator &operator --() { --it; return *this; } - inline scaled_const_iterator &operator +=(difference_type i) - { it += i; return *this; } - inline scaled_const_iterator &operator -=(difference_type i) - { it -= i; return *this; } - inline scaled_const_iterator operator +(difference_type i) const - { scaled_const_iterator itb = *this; return (itb += i); } - inline scaled_const_iterator operator -(difference_type i) const - { scaled_const_iterator itb = *this; return (itb -= i); } - inline difference_type operator -(const scaled_const_iterator &i) const - { return difference_type(it - i.it); } - - inline value_type operator *() const { return (*it) * value_type(r); } - inline value_type operator [](size_type ii) const { return it[ii] * r; } - - inline bool operator ==(const scaled_const_iterator &i) const - { return (i.it == it); } - inline bool operator !=(const scaled_const_iterator &i) const - { return (i.it != it); } - inline bool operator < (const scaled_const_iterator &i) const - { return (it < i.it); } - }; - - template struct scaled_vector_const_ref { - typedef scaled_vector_const_ref this_type; - typedef typename linalg_traits::value_type value_type; - typedef typename linalg_traits::const_iterator iterator; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::origin_type origin_type; - - iterator begin_, end_; - const origin_type *origin; - size_type size_; - S r; - - scaled_vector_const_ref(const V &v, S rr) - : begin_(vect_const_begin(v)), end_(vect_const_end(v)), - origin(linalg_origin(v)), size_(vect_size(v)), r(rr) {} - - reference operator[](size_type i) const - { return value_type(r) * linalg_traits::access(origin, begin_, end_, i); } - }; - - - template std::ostream &operator << - (std::ostream &o, const scaled_vector_const_ref& m) - { gmm::write(o,m); return o; } - - /* ********************************************************************* */ - /* Scaled references on matrices */ - /* ********************************************************************* */ - - template struct scaled_row_const_iterator { - typedef scaled_row_const_iterator iterator; - typedef typename linalg_traits::const_row_iterator ITER; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - - ITER it; - S r; - - inline iterator operator ++(int) { iterator tmp=*this; it++; return tmp; } - inline iterator operator --(int) { iterator tmp=*this; it--; return tmp; } - inline iterator &operator ++() { it++; return *this; } - inline iterator &operator --() { it--; return *this; } - iterator &operator +=(difference_type i) { it += i; return *this; } - iterator &operator -=(difference_type i) { it -= i; return *this; } - iterator operator +(difference_type i) const - { iterator itt = *this; return (itt += i); } - iterator operator -(difference_type i) const - { iterator itt = *this; return (itt -= i); } - difference_type operator -(const iterator &i) const - { return it - i.it; } - - inline ITER operator *() const { return it; } - inline ITER operator [](int i) { return it + i; } - - inline bool operator ==(const iterator &i) const { return (it == i.it); } - inline bool operator !=(const iterator &i) const { return !(i == *this); } - inline bool operator < (const iterator &i) const { return (it < i.it); } - - scaled_row_const_iterator(void) {} - scaled_row_const_iterator(const ITER &i, S rr) - : it(i), r(rr) { } - - }; - - template struct scaled_row_matrix_const_ref { - - typedef scaled_row_matrix_const_ref this_type; - typedef typename linalg_traits::const_row_iterator iterator; - typedef typename linalg_traits::value_type value_type; - typedef typename linalg_traits::origin_type origin_type; - - iterator begin_, end_; - const origin_type *origin; - S r; - size_type nr, nc; - - scaled_row_matrix_const_ref(const M &m, S rr) - : begin_(mat_row_begin(m)), end_(mat_row_end(m)), - origin(linalg_origin(m)), r(rr), nr(mat_nrows(m)), nc(mat_ncols(m)) {} - - value_type operator()(size_type i, size_type j) const - { return r * linalg_traits::access(begin_+i, j); } - }; - - - template std::ostream &operator << - (std::ostream &o, const scaled_row_matrix_const_ref& m) - { gmm::write(o,m); return o; } - - - template struct scaled_col_const_iterator { - typedef scaled_col_const_iterator iterator; - typedef typename linalg_traits::const_col_iterator ITER; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - - ITER it; - S r; - - iterator operator ++(int) { iterator tmp = *this; it++; return tmp; } - iterator operator --(int) { iterator tmp = *this; it--; return tmp; } - iterator &operator ++() { it++; return *this; } - iterator &operator --() { it--; return *this; } - iterator &operator +=(difference_type i) { it += i; return *this; } - iterator &operator -=(difference_type i) { it -= i; return *this; } - iterator operator +(difference_type i) const - { iterator itt = *this; return (itt += i); } - iterator operator -(difference_type i) const - { iterator itt = *this; return (itt -= i); } - difference_type operator -(const iterator &i) const - { return it - i.it; } - - ITER operator *() const { return it; } - ITER operator [](int i) { return it + i; } - - bool operator ==(const iterator &i) const { return (it == i.it); } - bool operator !=(const iterator &i) const { return !(i == *this); } - bool operator < (const iterator &i) const { return (it < i.it); } - - scaled_col_const_iterator(void) {} - scaled_col_const_iterator(const ITER &i, S rr) - : it(i), r(rr) { } - - }; - - template struct scaled_col_matrix_const_ref { - - typedef scaled_col_matrix_const_ref this_type; - typedef typename linalg_traits::const_col_iterator iterator; - typedef typename linalg_traits::value_type value_type; - typedef typename linalg_traits::origin_type origin_type; - - iterator begin_, end_; - const origin_type *origin; - S r; - size_type nr, nc; - - scaled_col_matrix_const_ref(const M &m, S rr) - : begin_(mat_col_begin(m)), end_(mat_col_end(m)), - origin(linalg_origin(m)), r(rr), nr(mat_nrows(m)), nc(mat_ncols(m)) {} - - value_type operator()(size_type i, size_type j) const - { return r * linalg_traits::access(begin_+j, i); } - }; - - - - template std::ostream &operator << - (std::ostream &o, const scaled_col_matrix_const_ref& m) - { gmm::write(o,m); return o; } - - - template struct scaled_return__ { - typedef abstract_null_type return_type; - }; - template struct scaled_return__ - { typedef scaled_row_matrix_const_ref return_type; }; - template struct scaled_return__ - { typedef scaled_col_matrix_const_ref return_type; }; - - - template struct scaled_return_ { - typedef abstract_null_type return_type; - }; - template struct scaled_return_ - { typedef scaled_vector_const_ref return_type; }; - template struct scaled_return_ { - typedef typename scaled_return__::sub_orientation>::potype>::return_type return_type; - }; - - template struct scaled_return { - typedef typename scaled_return_::linalg_type>::return_type return_type; - }; - - template inline - typename scaled_return::return_type - scaled(const L &v, S x) - { return scaled(v, x, typename linalg_traits::linalg_type()); } - - template inline - typename scaled_return::return_type - scaled(const V &v, S x, abstract_vector) - { return scaled_vector_const_ref(v, x); } - - template inline - typename scaled_return::return_type - scaled(const M &m, S x,abstract_matrix) { - return scaled(m, x, typename principal_orientation_type::sub_orientation>::potype()); - } - - template inline - typename scaled_return::return_type - scaled(const M &m, S x, row_major) { - return scaled_row_matrix_const_ref(m, x); - } - - template inline - typename scaled_return::return_type - scaled(const M &m, S x, col_major) { - return scaled_col_matrix_const_ref(m, x); - } - - - /* ******************************************************************** */ - /* matrix or vector scale */ - /* ******************************************************************** */ - - template inline - void scale(L& l, typename linalg_traits::value_type a) - { scale(l, a, typename linalg_traits::linalg_type()); } - - template inline - void scale(const L& l, typename linalg_traits::value_type a) - { scale(linalg_const_cast(l), a); } - - template inline - void scale(L& l, typename linalg_traits::value_type a, abstract_vector) { - typename linalg_traits::iterator it = vect_begin(l), ite = vect_end(l); - for ( ; it != ite; ++it) *it *= a; - } - - template - void scale(L& l, typename linalg_traits::value_type a, abstract_matrix) { - scale(l, a, typename principal_orientation_type::sub_orientation>::potype()); - } - - template - void scale(L& l, typename linalg_traits::value_type a, row_major) { - typename linalg_traits::row_iterator it = mat_row_begin(l), - ite = mat_row_end(l); - for ( ; it != ite; ++it) scale(linalg_traits::row(it), a); - } - - template - void scale(L& l, typename linalg_traits::value_type a, col_major) { - typename linalg_traits::col_iterator it = mat_col_begin(l), - ite = mat_col_end(l); - for ( ; it != ite; ++it) scale(linalg_traits::col(it), a); - } - - template struct linalg_traits > { - typedef scaled_vector_const_ref this_type; - typedef linalg_const is_reference; - typedef abstract_vector linalg_type; - typedef typename strongest_numeric_type::value_type>::T value_type; - typedef typename linalg_traits::origin_type origin_type; - typedef value_type reference; - typedef abstract_null_type iterator; - typedef scaled_const_iterator::const_iterator, S> - const_iterator; - typedef typename linalg_traits::storage_type storage_type; - typedef typename linalg_traits::index_sorted index_sorted; - static size_type size(const this_type &v) { return v.size_; } - static const_iterator begin(const this_type &v) - { return const_iterator(v.begin_, v.r); } - static const_iterator end(const this_type &v) - { return const_iterator(v.end_, v.r); } - static const origin_type* origin(const this_type &v) { return v.origin; } - static value_type access(const origin_type *o, const const_iterator &it, - const const_iterator &ite, size_type i) - { return it.r * (linalg_traits::access(o, it.it, ite.it, i)); } - - }; - - - template struct linalg_traits > { - typedef scaled_row_matrix_const_ref this_type; - typedef linalg_const is_reference; - typedef abstract_matrix linalg_type; - typedef typename linalg_traits::origin_type origin_type; - typedef typename strongest_numeric_type::value_type>::T value_type; - typedef value_type reference; - typedef typename linalg_traits::storage_type storage_type; - typedef typename org_type::const_sub_row_type>::t vector_type; - typedef scaled_vector_const_ref sub_row_type; - typedef scaled_vector_const_ref const_sub_row_type; - typedef scaled_row_const_iterator row_iterator; - typedef scaled_row_const_iterator const_row_iterator; - typedef abstract_null_type const_sub_col_type; - typedef abstract_null_type sub_col_type; - typedef abstract_null_type const_col_iterator; - typedef abstract_null_type col_iterator; - typedef row_major sub_orientation; - typedef typename linalg_traits::index_sorted index_sorted; - static size_type nrows(const this_type &m) - { return m.nr; } - static size_type ncols(const this_type &m) - { return m.nc; } - static const_sub_row_type row(const const_row_iterator &it) - { return scaled(linalg_traits::row(it.it), it.r); } - static const_row_iterator row_begin(const this_type &m) - { return const_row_iterator(m.begin_, m.r); } - static const_row_iterator row_end(const this_type &m) - { return const_row_iterator(m.end_, m.r); } - static const origin_type* origin(const this_type &m) { return m.origin; } - static value_type access(const const_row_iterator &it, size_type i) - { return it.r * (linalg_traits::access(it.it, i)); } - }; - - template struct linalg_traits > { - typedef scaled_col_matrix_const_ref this_type; - typedef linalg_const is_reference; - typedef abstract_matrix linalg_type; - typedef typename strongest_numeric_type::value_type>::T value_type; - typedef typename linalg_traits::origin_type origin_type; - typedef value_type reference; - typedef typename linalg_traits::storage_type storage_type; - typedef typename org_type::const_sub_col_type>::t vector_type; - typedef abstract_null_type sub_col_type; - typedef scaled_vector_const_ref const_sub_col_type; - typedef abstract_null_type col_iterator; - typedef scaled_col_const_iterator const_col_iterator; - typedef abstract_null_type const_sub_row_type; - typedef abstract_null_type sub_row_type; - typedef abstract_null_type const_row_iterator; - typedef abstract_null_type row_iterator; - typedef col_major sub_orientation; - typedef typename linalg_traits::index_sorted index_sorted; - static size_type ncols(const this_type &m) - { return m.nc; } - static size_type nrows(const this_type &m) - { return m.nr; } - static const_sub_col_type col(const const_col_iterator &it) - { return scaled(linalg_traits::col(it.it), it.r); } - static const_col_iterator col_begin(const this_type &m) - { return const_col_iterator(m.begin_, m.r); } - static const_col_iterator col_end(const this_type &m) - { return const_col_iterator(m.end_, m.r); } - static const origin_type* origin(const this_type &m) { return m.origin; } - static value_type access(const const_col_iterator &it, size_type i) - { return it.r * (linalg_traits::access(it.it, i)); } - }; - - -} - -#endif // GMM_SCALED_H__ diff --git a/gmm/gmm_solver_Schwarz_additive.h b/gmm/gmm_solver_Schwarz_additive.h deleted file mode 100644 index 7f8554b5a..000000000 --- a/gmm/gmm_solver_Schwarz_additive.h +++ /dev/null @@ -1,805 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_solver_Schwarz_additive.h - @author Yves Renard - @author Michel Fournie - @date October 13, 2002. -*/ - -#ifndef GMM_SOLVERS_SCHWARZ_ADDITIVE_H__ -#define GMM_SOLVERS_SCHWARZ_ADDITIVE_H__ - -#include "gmm_kernel.h" -#include "gmm_superlu_interface.h" -#include "gmm_solver_cg.h" -#include "gmm_solver_gmres.h" -#include "gmm_solver_bicgstab.h" -#include "gmm_solver_qmr.h" - -namespace gmm { - - /* ******************************************************************** */ - /* Additive Schwarz interfaced local solvers */ - /* ******************************************************************** */ - - struct using_cg {}; - struct using_gmres {}; - struct using_bicgstab {}; - struct using_qmr {}; - - template - struct actual_precond { - typedef P APrecond; - static const APrecond &transform(const P &PP) { return PP; } - }; - - template - void AS_local_solve(using_cg, const Matrix1 &A, Vector &x, const Vector &b, - const Precond &P, iteration &iter) - { cg(A, x, b, P, iter); } - - template - void AS_local_solve(using_gmres, const Matrix1 &A, Vector &x, - const Vector &b, const Precond &P, iteration &iter) - { gmres(A, x, b, P, 100, iter); } - - template - void AS_local_solve(using_bicgstab, const Matrix1 &A, Vector &x, - const Vector &b, const Precond &P, iteration &iter) - { bicgstab(A, x, b, P, iter); } - - template - void AS_local_solve(using_qmr, const Matrix1 &A, Vector &x, - const Vector &b, const Precond &P, iteration &iter) - { qmr(A, x, b, P, iter); } - -#if defined(GMM_USES_SUPERLU) - struct using_superlu {}; - - template - struct actual_precond { - typedef typename linalg_traits::value_type value_type; - typedef SuperLU_factor APrecond; - template - static APrecond transform(const PR &) { return APrecond(); } - static const APrecond &transform(const APrecond &PP) { return PP; } - }; - - template - void AS_local_solve(using_superlu, const Matrix1 &, Vector &x, - const Vector &b, const Precond &P, iteration &iter) - { P.solve(x, b); iter.set_iteration(1); } -#endif - - /* ******************************************************************** */ - /* Additive Schwarz Linear system */ - /* ******************************************************************** */ - - template - struct add_schwarz_mat{ - typedef typename linalg_traits::value_type value_type; - - const Matrix1 *A; - const std::vector *vB; - std::vector vAloc; - mutable iteration iter; - double residual; - mutable size_type itebilan; - mutable std::vector > gi, fi; - std::vector::APrecond> precond1; - - void init(const Matrix1 &A_, const std::vector &vB_, - iteration iter_, const Precond &P, double residual_); - - add_schwarz_mat(void) {} - add_schwarz_mat(const Matrix1 &A_, const std::vector &vB_, - iteration iter_, const Precond &P, double residual_) - { init(A_, vB_, iter_, P, residual_); } - }; - - template - void add_schwarz_mat::init( - const Matrix1 &A_, const std::vector &vB_, - iteration iter_, const Precond &P, double residual_) { - - vB = &vB_; A = &A_; iter = iter_; - residual = residual_; - - size_type nb_sub = vB->size(); - vAloc.resize(nb_sub); - gi.resize(nb_sub); fi.resize(nb_sub); - precond1.resize(nb_sub); - std::fill(precond1.begin(), precond1.end(), - actual_precond::transform(P)); - itebilan = 0; - - if (iter.get_noisy()) cout << "Init pour sub dom "; -#ifdef GMM_USES_MPI - int size,tranche,borne_sup,borne_inf,rank,tag1=11,tag2=12,tag3=13,sizepr = 0; - // int tab[4]; - double t_ref,t_final; - MPI_Status status; - t_ref=MPI_Wtime(); - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &size); - tranche=nb_sub/size; - borne_inf=rank*tranche; - borne_sup=(rank+1)*tranche; - // if (rank==size-1) borne_sup = nb_sub; - - cout << "Nombre de sous domaines " << borne_sup - borne_inf << endl; - - int sizeA = mat_nrows(*A); - gmm::csr_matrix Acsr(sizeA, sizeA), Acsrtemp(sizeA, sizeA); - gmm::copy(gmm::eff_matrix(*A), Acsr); - int next = (rank + 1) % size; - int previous = (rank + size - 1) % size; - //communication of local information on ring pattern - //Each process receive Nproc-1 contributions - - for (int nproc = 0; nproc < size; ++nproc) { - for (size_type i = size_type(borne_inf); i < size_type(borne_sup); ++i) { -// for (size_type i = 0; i < nb_sub/size; ++i) { -// for (size_type i = 0; i < nb_sub; ++i) { - // size_type i=(rank+size*(j-1)+nb_sub)%nb_sub; - - cout << "Sous domaines " << i << " : " << mat_ncols((*vB)[i]) << endl; -#else - for (size_type i = 0; i < nb_sub; ++i) { -#endif - - if (iter.get_noisy()) cout << i << " " << std::flush; - Matrix2 Maux(mat_ncols((*vB)[i]), mat_nrows((*vB)[i])); - -#ifdef GMM_USES_MPI - Matrix2 Maux2(mat_ncols((*vB)[i]), mat_ncols((*vB)[i])); - if (nproc == 0) { - gmm::resize(vAloc[i], mat_ncols((*vB)[i]), mat_ncols((*vB)[i])); - gmm::clear(vAloc[i]); - } - gmm::mult(gmm::transposed((*vB)[i]), Acsr, Maux); - gmm::mult(Maux, (*vB)[i], Maux2); - gmm::add(Maux2, vAloc[i]); -#else - gmm::resize(vAloc[i], mat_ncols((*vB)[i]), mat_ncols((*vB)[i])); - gmm::mult(gmm::transposed((*vB)[i]), *A, Maux); - gmm::mult(Maux, (*vB)[i], vAloc[i]); -#endif - -#ifdef GMM_USES_MPI - if (nproc == size - 1 ) { -#endif - precond1[i].build_with(vAloc[i]); - gmm::resize(fi[i], mat_ncols((*vB)[i])); - gmm::resize(gi[i], mat_ncols((*vB)[i])); -#ifdef GMM_USES_MPI - } -#else - } -#endif -#ifdef GMM_USES_MPI - } - if (nproc != size - 1) { - MPI_Sendrecv(&(Acsr.jc[0]), sizeA+1, MPI_INT, next, tag2, - &(Acsrtemp.jc[0]), sizeA+1, MPI_INT, previous, tag2, - MPI_COMM_WORLD, &status); - if (Acsrtemp.jc[sizeA] > size_type(sizepr)) { - sizepr = Acsrtemp.jc[sizeA]; - gmm::resize(Acsrtemp.pr, sizepr); - gmm::resize(Acsrtemp.ir, sizepr); - } - MPI_Sendrecv(&(Acsr.ir[0]), Acsr.jc[sizeA], MPI_INT, next, tag1, - &(Acsrtemp.ir[0]), Acsrtemp.jc[sizeA], MPI_INT, previous, tag1, - MPI_COMM_WORLD, &status); - - MPI_Sendrecv(&(Acsr.pr[0]), Acsr.jc[sizeA], mpi_type(value_type()), next, tag3, - &(Acsrtemp.pr[0]), Acsrtemp.jc[sizeA], mpi_type(value_type()), previous, tag3, - MPI_COMM_WORLD, &status); - gmm::copy(Acsrtemp, Acsr); - } - } - t_final=MPI_Wtime(); - cout<<"temps boucle precond "<< t_final-t_ref< - void mult(const add_schwarz_mat &M, - const Vector2 &p, Vector3 &q) { - size_type itebilan = 0; -#ifdef GMM_USES_MPI - static double tmult_tot = 0.0; - double t_ref = MPI_Wtime(); -#endif - // cout << "tmult AS begin " << endl; - mult(*(M.A), p, q); -#ifdef GMM_USES_MPI - tmult_tot += MPI_Wtime()-t_ref; - cout << "tmult_tot = " << tmult_tot << endl; -#endif - std::vector qbis(gmm::vect_size(q)); - std::vector qter(gmm::vect_size(q)); -#ifdef GMM_USES_MPI - // MPI_Status status; - // MPI_Request request,request1; - // int tag=111; - int size,tranche,borne_sup,borne_inf,rank; - size_type nb_sub=M.fi.size(); - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &size); - tranche=nb_sub/size; - borne_inf=rank*tranche; - borne_sup=(rank+1)*tranche; - // if (rank==size-1) borne_sup=nb_sub; - // int next = (rank + 1) % size; - // int previous = (rank + size - 1) % size; - t_ref = MPI_Wtime(); - for (size_type i = size_type(borne_inf); i < size_type(borne_sup); ++i) -// for (size_type i = 0; i < nb_sub/size; ++i) - // for (size_type j = 0; j < nb_sub; ++j) -#else - for (size_type i = 0; i < M.fi.size(); ++i) -#endif - { -#ifdef GMM_USES_MPI - // size_type i=j; // (rank+size*(j-1)+nb_sub)%nb_sub; -#endif - gmm::mult(gmm::transposed((*(M.vB))[i]), q, M.fi[i]); - M.iter.init(); - AS_local_solve(local_solver(), (M.vAloc)[i], (M.gi)[i], - (M.fi)[i],(M.precond1)[i],M.iter); - itebilan = std::max(itebilan, M.iter.get_iteration()); - } - -#ifdef GMM_USES_MPI - cout << "First AS loop time " << MPI_Wtime() - t_ref << endl; -#endif - - gmm::clear(q); -#ifdef GMM_USES_MPI - t_ref = MPI_Wtime(); - // for (size_type j = 0; j < nb_sub; ++j) - for (size_type i = size_type(borne_inf); i < size_type(borne_sup); ++i) - -#else - for (size_type i = 0; i < M.gi.size(); ++i) -#endif - { - -#ifdef GMM_USES_MPI - // size_type i=j; // (rank+size*(j-1)+nb_sub)%nb_sub; -// gmm::mult((*(M.vB))[i], M.gi[i], qbis,qbis); - gmm::mult((*(M.vB))[i], M.gi[i], qter); - add(qter,qbis,qbis); -#else - gmm::mult((*(M.vB))[i], M.gi[i], q, q); -#endif - } -#ifdef GMM_USES_MPI - //WARNING this add only if you use the ring pattern below - // need to do this below if using a n explicit ring pattern communication - -// add(qbis,q,q); - cout << "Second AS loop time " << MPI_Wtime() - t_ref << endl; -#endif - - -#ifdef GMM_USES_MPI - // int tag1=11; - static double t_tot = 0.0; - double t_final; - t_ref=MPI_Wtime(); -// int next = (rank + 1) % size; -// int previous = (rank + size - 1) % size; - //communication of local information on ring pattern - //Each process receive Nproc-1 contributions - -// if (size > 1) { -// for (int nproc = 0; nproc < size-1; ++nproc) -// { - -// MPI_Sendrecv(&(qbis[0]), gmm::vect_size(q), MPI_DOUBLE, next, tag1, -// &(qter[0]), gmm::vect_size(q),MPI_DOUBLE,previous,tag1, -// MPI_COMM_WORLD,&status); -// gmm::copy(qter, qbis); -// add(qbis,q,q); -// } -// } - MPI_Allreduce(&(qbis[0]), &(q[0]),gmm::vect_size(q), MPI_DOUBLE, - MPI_SUM,MPI_COMM_WORLD); - t_final=MPI_Wtime(); - t_tot += t_final-t_ref; - cout<<"["<< rank<<"] temps reduce Resol "<< t_final-t_ref << " t_tot = " << t_tot << endl; -#endif - - if (M.iter.get_noisy() > 0) cout << "itebloc = " << itebilan << endl; - M.itebilan += itebilan; - M.iter.set_resmax((M.iter.get_resmax() + M.residual) * 0.5); - } - - template - void mult(const add_schwarz_mat &M, - const Vector2 &p, const Vector3 &q) { - mult(M, p, const_cast(q)); - } - - template - void mult(const add_schwarz_mat &M, - const Vector2 &p, const Vector3 &p2, Vector4 &q) - { mult(M, p, q); add(p2, q); } - - template - void mult(const add_schwarz_mat &M, - const Vector2 &p, const Vector3 &p2, const Vector4 &q) - { mult(M, p, const_cast(q)); add(p2, q); } - - /* ******************************************************************** */ - /* Additive Schwarz interfaced global solvers */ - /* ******************************************************************** */ - - template - void AS_global_solve(using_cg, const ASM_type &ASM, Vect &x, - const Vect &b, iteration &iter) - { cg(ASM, x, b, *(ASM.A), identity_matrix(), iter); } - - template - void AS_global_solve(using_gmres, const ASM_type &ASM, Vect &x, - const Vect &b, iteration &iter) - { gmres(ASM, x, b, identity_matrix(), 100, iter); } - - template - void AS_global_solve(using_bicgstab, const ASM_type &ASM, Vect &x, - const Vect &b, iteration &iter) - { bicgstab(ASM, x, b, identity_matrix(), iter); } - - template - void AS_global_solve(using_qmr,const ASM_type &ASM, Vect &x, - const Vect &b, iteration &iter) - { qmr(ASM, x, b, identity_matrix(), iter); } - -#if defined(GMM_USES_SUPERLU) - template - void AS_global_solve(using_superlu, const ASM_type &, Vect &, - const Vect &, iteration &) { - GMM_ASSERT1(false, "You cannot use SuperLU as " - "global solver in additive Schwarz meethod"); - } -#endif - - /* ******************************************************************** */ - /* Linear Additive Schwarz method */ - /* ******************************************************************** */ - /* ref : Domain decomposition algorithms for the p-version finite */ - /* element method for elliptic problems, Luca F. Pavarino, */ - /* PhD thesis, Courant Institute of Mathematical Sciences, 1992. */ - /* ******************************************************************** */ - - /** Function to call if the ASM matrix is precomputed for successive solve - * with the same system. - */ - template - void additive_schwarz( - add_schwarz_mat &ASM, Vector3 &u, - const Vector2 &f, iteration &iter, const global_solver&) { - - typedef typename linalg_traits::value_type value_type; - - size_type nb_sub = ASM.vB->size(), nb_dof = gmm::vect_size(f); - ASM.itebilan = 0; - std::vector g(nb_dof); - std::vector gbis(nb_dof); -#ifdef GMM_USES_MPI - double t_init=MPI_Wtime(); - int size,tranche,borne_sup,borne_inf,rank; - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &size); - tranche=nb_sub/size; - borne_inf=rank*tranche; - borne_sup=(rank+1)*tranche; - // if (rank==size-1) borne_sup=nb_sub*size; - for (size_type i = size_type(borne_inf); i < size_type(borne_sup); ++i) -// for (size_type i = 0; i < nb_sub/size; ++i) - // for (size_type j = 0; j < nb_sub; ++j) - // for (size_type i = rank; i < nb_sub; i+=size) -#else - for (size_type i = 0; i < nb_sub; ++i) -#endif - { - -#ifdef GMM_USES_MPI - // size_type i=j; // (rank+size*(j-1)+nb_sub)%nb_sub; -#endif - gmm::mult(gmm::transposed((*(ASM.vB))[i]), f, ASM.fi[i]); - ASM.iter.init(); - AS_local_solve(local_solver(), ASM.vAloc[i], ASM.gi[i], ASM.fi[i], - ASM.precond1[i], ASM.iter); - ASM.itebilan = std::max(ASM.itebilan, ASM.iter.get_iteration()); -#ifdef GMM_USES_MPI - gmm::mult((*(ASM.vB))[i], ASM.gi[i], gbis,gbis); -#else - gmm::mult((*(ASM.vB))[i], ASM.gi[i], g, g); -#endif - } -#ifdef GMM_USES_MPI - cout<<"temps boucle init "<< MPI_Wtime()-t_init< - void additive_schwarz(const Matrix1 &A, Vector3 &u, - const Vector2 &f, const Precond &P, - const std::vector &vB, - iteration &iter, local_solver, - global_solver) { - iter.set_rhsnorm(vect_norm2(f)); - if (iter.get_rhsnorm() == 0.0) { gmm::clear(u); return; } - iteration iter2 = iter; iter2.reduce_noisy(); - iter2.set_maxiter(size_type(-1)); - add_schwarz_mat - ASM(A, vB, iter2, P, iter.get_resmax()); - additive_schwarz(ASM, u, f, iter, global_solver()); - } - - /* ******************************************************************** */ - /* Sequential Non-Linear Additive Schwarz method */ - /* ******************************************************************** */ - /* ref : Nonlinearly Preconditionned Inexact Newton Algorithms, */ - /* Xiao-Chuan Cai, David E. Keyes, */ - /* SIAM J. Sci. Comp. 24: p183-200. l */ - /* ******************************************************************** */ - - template - class NewtonAS_struct { - - public : - typedef Matrixt tangent_matrix_type; - typedef MatrixBi B_matrix_type; - typedef typename linalg_traits::value_type value_type; - typedef std::vector Vector; - - virtual size_type size(void) = 0; - virtual const std::vector &get_vB() = 0; - - virtual void compute_F(Vector &f, Vector &x) = 0; - virtual void compute_tangent_matrix(Matrixt &M, Vector &x) = 0; - // compute Bi^T grad(F(X)) Bi - virtual void compute_sub_tangent_matrix(Matrixt &Mloc, Vector &x, - size_type i) = 0; - // compute Bi^T F(X) - virtual void compute_sub_F(Vector &fi, Vector &x, size_type i) = 0; - - virtual ~NewtonAS_struct() {} - }; - - template - struct AS_exact_gradient { - const std::vector &vB; - std::vector vM; - std::vector vMloc; - - void init(void) { - for (size_type i = 0; i < vB.size(); ++i) { - Matrixt aux(gmm::mat_ncols(vB[i]), gmm::mat_ncols(vM[i])); - gmm::resize(vMloc[i], gmm::mat_ncols(vB[i]), gmm::mat_ncols(vB[i])); - gmm::mult(gmm::transposed(vB[i]), vM[i], aux); - gmm::mult(aux, vB[i], vMloc[i]); - } - } - AS_exact_gradient(const std::vector &vB_) : vB(vB_) { - vM.resize(vB.size()); vMloc.resize(vB.size()); - for (size_type i = 0; i < vB.size(); ++i) { - gmm::resize(vM[i], gmm::mat_nrows(vB[i]), gmm::mat_nrows(vB[i])); - } - } - }; - - template - void mult(const AS_exact_gradient &M, - const Vector2 &p, Vector3 &q) { - gmm::clear(q); - typedef typename gmm::linalg_traits::value_type T; - std::vector v(gmm::vect_size(p)), w, x; - for (size_type i = 0; i < M.vB.size(); ++i) { - w.resize(gmm::mat_ncols(M.vB[i])); - x.resize(gmm::mat_ncols(M.vB[i])); - gmm::mult(M.vM[i], p, v); - gmm::mult(gmm::transposed(M.vB[i]), v, w); - double rcond; - SuperLU_solve(M.vMloc[i], x, w, rcond); - // gmm::iteration iter(1E-10, 0, 100000); - //gmm::gmres(M.vMloc[i], x, w, gmm::identity_matrix(), 50, iter); - gmm::mult_add(M.vB[i], x, q); - } - } - - template - void mult(const AS_exact_gradient &M, - const Vector2 &p, const Vector3 &q) { - mult(M, p, const_cast(q)); - } - - template - void mult(const AS_exact_gradient &M, - const Vector2 &p, const Vector3 &p2, Vector4 &q) - { mult(M, p, q); add(p2, q); } - - template - void mult(const AS_exact_gradient &M, - const Vector2 &p, const Vector3 &p2, const Vector4 &q) - { mult(M, p, const_cast(q)); add(p2, q); } - - struct S_default_newton_line_search { - - double conv_alpha, conv_r; - size_t it, itmax, glob_it; - - double alpha, alpha_old, alpha_mult, first_res, alpha_max_ratio; - double alpha_min_ratio, alpha_min; - size_type count, count_pat; - bool max_ratio_reached; - double alpha_max_ratio_reached, r_max_ratio_reached; - size_type it_max_ratio_reached; - - - double converged_value(void) { return conv_alpha; }; - double converged_residual(void) { return conv_r; }; - - virtual void init_search(double r, size_t git, double = 0.0) { - alpha_min_ratio = 0.9; - alpha_min = 1e-10; - alpha_max_ratio = 10.0; - alpha_mult = 0.25; - itmax = size_type(-1); - glob_it = git; if (git <= 1) count_pat = 0; - conv_alpha = alpha = alpha_old = 1.; - conv_r = first_res = r; it = 0; - count = 0; - max_ratio_reached = false; - } - virtual double next_try(void) { - alpha_old = alpha; - if (alpha >= 0.4) alpha *= 0.5; else alpha *= alpha_mult; ++it; - return alpha_old; - } - virtual bool is_converged(double r, double = 0.0) { - // cout << "r = " << r << " alpha = " << alpha / alpha_mult << " count_pat = " << count_pat << endl; - if (!max_ratio_reached && r < first_res * alpha_max_ratio) { - alpha_max_ratio_reached = alpha_old; r_max_ratio_reached = r; - it_max_ratio_reached = it; max_ratio_reached = true; - } - if (max_ratio_reached && r < r_max_ratio_reached * 0.5 - && r > first_res * 1.1 && it <= it_max_ratio_reached+1) { - alpha_max_ratio_reached = alpha_old; r_max_ratio_reached = r; - it_max_ratio_reached = it; - } - if (count == 0 || r < conv_r) - { conv_r = r; conv_alpha = alpha_old; count = 1; } - if (conv_r < first_res) ++count; - - if (r < first_res * alpha_min_ratio) - { count_pat = 0; return true; } - if (count >= 5 || (alpha < alpha_min && max_ratio_reached)) { - if (conv_r < first_res * 0.99) count_pat = 0; - if (/*gmm::random() * 50. < -log(conv_alpha)-4.0 ||*/ count_pat >= 3) - { conv_r=r_max_ratio_reached; conv_alpha=alpha_max_ratio_reached; } - if (conv_r >= first_res * 0.9999) count_pat++; - return true; - } - return false; - } - S_default_newton_line_search(void) { count_pat = 0; } - }; - - - - template - void Newton_additive_Schwarz(NewtonAS_struct &NS, - const Vector &u_, - iteration &iter, const Precond &P, - local_solver, global_solver) { - Vector &u = const_cast(u_); - typedef typename linalg_traits::value_type value_type; - typedef typename number_traits::magnitude_type mtype; - typedef actual_precond chgt_precond; - - double residual = iter.get_resmax(); - - S_default_newton_line_search internal_ls; - S_default_newton_line_search external_ls; - - typename chgt_precond::APrecond PP = chgt_precond::transform(P); - iter.set_rhsnorm(mtype(1)); - iteration iternc(iter); - iternc.reduce_noisy(); iternc.set_maxiter(size_type(-1)); - iteration iter2(iternc); - iteration iter3(iter2); iter3.reduce_noisy(); - iteration iter4(iter3); - iternc.set_name("Local Newton"); - iter2.set_name("Linear System for Global Newton"); - iternc.set_resmax(residual/100.0); - iter3.set_resmax(residual/10000.0); - iter2.set_resmax(residual/1000.0); - iter4.set_resmax(residual/1000.0); - std::vector rhs(NS.size()), x(NS.size()), d(NS.size()); - std::vector xi, xii, fi, di; - - std::vector< std::vector > vx(NS.get_vB().size()); - for (size_type i = 0; i < NS.get_vB().size(); ++i) // for exact gradient - vx[i].resize(NS.size()); // for exact gradient - - Matrixt Mloc, M(NS.size(), NS.size()); - NS.compute_F(rhs, u); - mtype act_res=gmm::vect_norm2(rhs), act_res_new(0), precond_res = act_res; - mtype alpha; - - while(!iter.finished(std::min(act_res, precond_res))) { - for (int SOR_step = 0; SOR_step >= 0; --SOR_step) { - gmm::clear(rhs); - for (size_type isd = 0; isd < NS.get_vB().size(); ++isd) { - const MatrixBi &Bi = (NS.get_vB())[isd]; - size_type si = mat_ncols(Bi); - gmm::resize(Mloc, si, si); - xi.resize(si); xii.resize(si); fi.resize(si); di.resize(si); - - iternc.init(); - iternc.set_maxiter(30); // ? - if (iternc.get_noisy()) - cout << "Non-linear local problem " << isd << endl; - gmm::clear(xi); - gmm::copy(u, x); - NS.compute_sub_F(fi, x, isd); gmm::scale(fi, value_type(-1)); - mtype r = gmm::vect_norm2(fi), r_t(r); - if (r > value_type(0)) { - iternc.set_rhsnorm(std::max(r, mtype(1))); - while(!iternc.finished(r)) { - NS.compute_sub_tangent_matrix(Mloc, x, isd); - - PP.build_with(Mloc); - iter3.init(); - AS_local_solve(local_solver(), Mloc, di, fi, PP, iter3); - - internal_ls.init_search(r, iternc.get_iteration()); - do { - alpha = internal_ls.next_try(); - gmm::add(xi, gmm::scaled(di, -alpha), xii); - gmm::mult(Bi, gmm::scaled(xii, -1.0), u, x); - NS.compute_sub_F(fi, x, isd); gmm::scale(fi, value_type(-1)); - r_t = gmm::vect_norm2(fi); - } while (!internal_ls.is_converged(r_t)); - - if (alpha != internal_ls.converged_value()) { - alpha = internal_ls.converged_value(); - gmm::add(xi, gmm::scaled(di, -alpha), xii); - gmm::mult(Bi, gmm::scaled(xii, -1.0), u, x); - NS.compute_sub_F(fi, x, isd); gmm::scale(fi, value_type(-1)); - r_t = gmm::vect_norm2(fi); - } - gmm::copy(x, vx[isd]); // for exact gradient - - if (iternc.get_noisy()) cout << "(step=" << alpha << ")\t"; - ++iternc; r = r_t; gmm::copy(xii, xi); - } - if (SOR_step) gmm::mult(Bi, gmm::scaled(xii, -1.0), u, u); - gmm::mult(Bi, gmm::scaled(xii, -1.0), rhs, rhs); - } - } - precond_res = gmm::vect_norm2(rhs); - if (SOR_step) cout << "SOR step residual = " << precond_res << endl; - if (precond_res < residual) break; - cout << "Precond residual = " << precond_res << endl; - } - - iter2.init(); - // solving linear system for the global Newton method - if (0) { - NS.compute_tangent_matrix(M, u); - add_schwarz_mat - ASM(M, NS.get_vB(), iter4, P, iter.get_resmax()); - AS_global_solve(global_solver(), ASM, d, rhs, iter2); - } - else { // for exact gradient - AS_exact_gradient eg(NS.get_vB()); - for (size_type i = 0; i < NS.get_vB().size(); ++i) { - NS.compute_tangent_matrix(eg.vM[i], vx[i]); - } - eg.init(); - gmres(eg, d, rhs, gmm::identity_matrix(), 50, iter2); - } - - // gmm::add(gmm::scaled(rhs, 0.1), u); ++iter; - external_ls.init_search(act_res, iter.get_iteration()); - do { - alpha = external_ls.next_try(); - gmm::add(gmm::scaled(d, alpha), u, x); - NS.compute_F(rhs, x); - act_res_new = gmm::vect_norm2(rhs); - } while (!external_ls.is_converged(act_res_new)); - - if (alpha != external_ls.converged_value()) { - alpha = external_ls.converged_value(); - gmm::add(gmm::scaled(d, alpha), u, x); - NS.compute_F(rhs, x); - act_res_new = gmm::vect_norm2(rhs); - } - - if (iter.get_noisy() > 1) cout << endl; - act_res = act_res_new; - if (iter.get_noisy()) cout << "(step=" << alpha << ")\t unprecond res = " << act_res << " "; - - - ++iter; gmm::copy(x, u); - } - } - -} - - -#endif // GMM_SOLVERS_SCHWARZ_ADDITIVE_H__ diff --git a/gmm/gmm_solver_bfgs.h b/gmm/gmm_solver_bfgs.h deleted file mode 100644 index 28a1bc01f..000000000 --- a/gmm/gmm_solver_bfgs.h +++ /dev/null @@ -1,210 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2004-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_solver_bfgs.h - @author Yves Renard - @date October 14 2004. - @brief Implements BFGS (Broyden, Fletcher, Goldfarb, Shanno) algorithm. - */ -#ifndef GMM_BFGS_H -#define GMM_BFGS_H - -#include "gmm_kernel.h" -#include "gmm_iter.h" - -namespace gmm { - - // BFGS algorithm (Broyden, Fletcher, Goldfarb, Shanno) - // Quasi Newton method for optimization problems. - // with Wolfe Line search. - - - // delta[k] = x[k+1] - x[k] - // gamma[k] = grad f(x[k+1]) - grad f(x[k]) - // H[0] = I - // BFGS : zeta[k] = delta[k] - H[k] gamma[k] - // DFP : zeta[k] = H[k] gamma[k] - // tau[k] = gamma[k]^T zeta[k] - // rho[k] = 1 / gamma[k]^T delta[k] - // BFGS : H[k+1] = H[k] + rho[k](zeta[k] delta[k]^T + delta[k] zeta[k]^T) - // - rho[k]^2 tau[k] delta[k] delta[k]^T - // DFP : H[k+1] = H[k] + rho[k] delta[k] delta[k]^T - // - (1/tau[k])zeta[k] zeta[k]^T - - // Object representing the inverse of the Hessian - template struct bfgs_invhessian { - - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - std::vector delta, gamma, zeta; - std::vector tau, rho; - int version; - - template void hmult(const VEC1 &X, VEC2 &Y) { - copy(X, Y); - for (size_type k = 0 ; k < delta.size(); ++k) { - T xdelta = vect_sp(X, delta[k]), xzeta = vect_sp(X, zeta[k]); - switch (version) { - case 0 : // BFGS - add(scaled(zeta[k], rho[k]*xdelta), Y); - add(scaled(delta[k], rho[k]*(xzeta-rho[k]*tau[k]*xdelta)), Y); - break; - case 1 : // DFP - add(scaled(delta[k], rho[k]*xdelta), Y); - add(scaled(zeta[k], -xzeta/tau[k]), Y); - break; - } - } - } - - void restart(void) { - delta.resize(0); gamma.resize(0); zeta.resize(0); - tau.resize(0); rho.resize(0); - } - - template - void update(const VECT1 &deltak, const VECT2 &gammak) { - T vsp = vect_sp(deltak, gammak); - if (vsp == T(0)) return; - size_type N = vect_size(deltak), k = delta.size(); - VECTOR Y(N); - hmult(gammak, Y); - delta.resize(k+1); gamma.resize(k+1); zeta.resize(k+1); - tau.resize(k+1); rho.resize(k+1); - resize(delta[k], N); resize(gamma[k], N); resize(zeta[k], N); - gmm::copy(deltak, delta[k]); - gmm::copy(gammak, gamma[k]); - rho[k] = R(1) / vsp; - if (version == 0) - add(delta[k], scaled(Y, -1), zeta[k]); - else - gmm::copy(Y, zeta[k]); - tau[k] = vect_sp(gammak, zeta[k]); - } - - bfgs_invhessian(int v = 0) { version = v; } - }; - - - template - void bfgs(const FUNCTION &f, const DERIVATIVE &grad, VECTOR &x, - int restart, iteration& iter, int version = 0, - double lambda_init=0.001, double print_norm=1.0) { - - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - bfgs_invhessian invhessian(version); - VECTOR r(vect_size(x)), d(vect_size(x)), y(vect_size(x)), r2(vect_size(x)); - grad(x, r); - R lambda = lambda_init, valx = f(x), valy; - int nb_restart(0); - - if (iter.get_noisy() >= 1) cout << "value " << valx / print_norm << " "; - while (! iter.finished_vect(r)) { - - invhessian.hmult(r, d); gmm::scale(d, T(-1)); - - // Wolfe Line search - R derivative = gmm::vect_sp(r, d); - R lambda_min(0), lambda_max(0), m1 = 0.27, m2 = 0.57; - bool unbounded = true, blocked = false, grad_computed = false; - - for(;;) { - add(x, scaled(d, lambda), y); - valy = f(y); - if (iter.get_noisy() >= 2) { - cout.precision(15); - cout << "Wolfe line search, lambda = " << lambda - << " value = " << valy /print_norm << endl; -// << " derivative = " << derivative -// << " lambda min = " << lambda_min << " lambda max = " -// << lambda_max << endl; getchar(); - } - if (valy <= valx + m1 * lambda * derivative) { - grad(y, r2); grad_computed = true; - T derivative2 = gmm::vect_sp(r2, d); - if (derivative2 >= m2*derivative) break; - lambda_min = lambda; - } - else { - lambda_max = lambda; - unbounded = false; - } - if (unbounded) lambda *= R(10); - else lambda = (lambda_max + lambda_min) / R(2); - if (lambda == lambda_max || lambda == lambda_min) break; - // valy <= R(2)*valx replaced by - // valy <= valx + gmm::abs(derivative)*lambda_init - // for compatibility with negative values (08.24.07). - if (valy <= valx + R(2)*gmm::abs(derivative)*lambda && - (lambda < R(lambda_init*1E-8) || - (!unbounded && lambda_max-lambda_min < R(lambda_init*1E-8)))) - { blocked = true; lambda = lambda_init; break; } - } - - // Rank two update - ++iter; - if (!grad_computed) grad(y, r2); - gmm::add(scaled(r2, -1), r); - if ((iter.get_iteration() % restart) == 0 || blocked) { - if (iter.get_noisy() >= 1) cout << "Restart\n"; - invhessian.restart(); - if (++nb_restart > 10) { - if (iter.get_noisy() >= 1) cout << "BFGS is blocked, exiting\n"; - return; - } - } - else { - invhessian.update(gmm::scaled(d,lambda), gmm::scaled(r,-1)); - nb_restart = 0; - } - copy(r2, r); copy(y, x); valx = valy; - if (iter.get_noisy() >= 1) - cout << "BFGS value " << valx/print_norm << "\t"; - } - - } - - - template - inline void dfp(const FUNCTION &f, const DERIVATIVE &grad, VECTOR &x, - int restart, iteration& iter, int version = 1) { - bfgs(f, grad, x, restart, iter, version); - - } - - -} - -#endif - diff --git a/gmm/gmm_solver_bicgstab.h b/gmm/gmm_solver_bicgstab.h deleted file mode 100644 index 858478fbe..000000000 --- a/gmm/gmm_solver_bicgstab.h +++ /dev/null @@ -1,160 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -// This file is a modified version of bicgstab.h from ITL. -// See http://osl.iu.edu/research/itl/ -// Following the corresponding Copyright notice. -//=========================================================================== -// -// Copyright (c) 1998-2001, University of Notre Dame. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of Notre Dame nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE TRUSTEES OF INDIANA UNIVERSITY AND -// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES -// OF INDIANA UNIVERSITY AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//=========================================================================== - -/**@file gmm_solver_bicgstab.h - @author Andrew Lumsdaine - @author Lie-Quan Lee - @author Yves Renard - @date October 13, 2002. - @brief BiCGStab iterative solver. -*/ - -#ifndef GMM_SOLVER_BICGSTAB_H__ -#define GMM_SOLVER_BICGSTAB_H__ - -#include "gmm_kernel.h" -#include "gmm_iter.h" - -namespace gmm { - - /* ******************************************************************** */ - /* BiConjugate Gradient Stabilized */ - /* (preconditionned, with parametrable scalar product) */ - /* ******************************************************************** */ - - template - void bicgstab(const Matrix& A, Vector& x, const VectorB& b, - const Preconditioner& M, iteration &iter) { - - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - typedef typename temporary_dense_vector::vector_type temp_vector; - - T rho_1, rho_2(0), alpha(0), beta, omega(0); - temp_vector p(vect_size(x)), phat(vect_size(x)), s(vect_size(x)), - shat(vect_size(x)), - t(vect_size(x)), v(vect_size(x)), r(vect_size(x)), rtilde(vect_size(x)); - - gmm::mult(A, gmm::scaled(x, -T(1)), b, r); - gmm::copy(r, rtilde); - R norm_r = gmm::vect_norm2(r); - iter.set_rhsnorm(gmm::vect_norm2(b)); - - if (iter.get_rhsnorm() == 0.0) { clear(x); return; } - - while (!iter.finished(norm_r)) { - - rho_1 = gmm::vect_sp(rtilde, r); - if (rho_1 == T(0)) { - if (iter.get_maxiter() == size_type(-1)) - { GMM_ASSERT1(false, "Bicgstab failed to converge"); } - else { GMM_WARNING1("Bicgstab failed to converge"); return; } - } - - if (iter.first()) - gmm::copy(r, p); - else { - if (omega == T(0)) { - if (iter.get_maxiter() == size_type(-1)) - { GMM_ASSERT1(false, "Bicgstab failed to converge"); } - else { GMM_WARNING1("Bicgstab failed to converge"); return; } - } - - beta = (rho_1 / rho_2) * (alpha / omega); - - gmm::add(gmm::scaled(v, -omega), p); - gmm::add(r, gmm::scaled(p, beta), p); - } - gmm::mult(M, p, phat); - gmm::mult(A, phat, v); - alpha = rho_1 / gmm::vect_sp(v, rtilde); - gmm::add(r, gmm::scaled(v, -alpha), s); - - if (iter.finished_vect(s)) - { gmm::add(gmm::scaled(phat, alpha), x); break; } - - gmm::mult(M, s, shat); - gmm::mult(A, shat, t); - omega = gmm::vect_sp(t, s) / gmm::vect_norm2_sqr(t); - - gmm::add(gmm::scaled(phat, alpha), x); - gmm::add(gmm::scaled(shat, omega), x); - gmm::add(s, gmm::scaled(t, -omega), r); - norm_r = gmm::vect_norm2(r); - rho_2 = rho_1; - - ++iter; - } - } - - template - void bicgstab(const Matrix& A, const Vector& x, const VectorB& b, - const Preconditioner& M, iteration &iter) - { bicgstab(A, linalg_const_cast(x), b, M, iter); } - -} - - -#endif // GMM_SOLVER_BICGSTAB_H__ diff --git a/gmm/gmm_solver_cg.h b/gmm/gmm_solver_cg.h deleted file mode 100644 index a2876786a..000000000 --- a/gmm/gmm_solver_cg.h +++ /dev/null @@ -1,180 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -// This file is a modified version of cg.h from ITL. -// See http://osl.iu.edu/research/itl/ -// Following the corresponding Copyright notice. -//=========================================================================== -// -// Copyright (c) 1998-2001, University of Notre Dame. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of Notre Dame nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE TRUSTEES OF INDIANA UNIVERSITY AND -// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES -// OF INDIANA UNIVERSITY AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//=========================================================================== - -/**@file gmm_solver_cg.h - @author Andrew Lumsdaine - @author Lie-Quan Lee - @author Yves Renard - @date October 13, 2002. - @brief Conjugate gradient iterative solver. -*/ -#ifndef GMM_SOLVER_CG_H__ -#define GMM_SOLVER_CG_H__ - -#include "gmm_kernel.h" -#include "gmm_iter.h" - -namespace gmm { - - /* ******************************************************************** */ - /* conjugate gradient */ - /* (preconditionned, with parametrable additional scalar product) */ - /* ******************************************************************** */ - - template - void cg(const Matrix& A, Vector1& x, const Vector2& b, const Matps& PS, - const Precond &P, iteration &iter) { - - typedef typename temporary_dense_vector::vector_type temp_vector; - typedef typename linalg_traits::value_type T; - - T rho, rho_1(0), a; - temp_vector p(vect_size(x)), q(vect_size(x)), r(vect_size(x)), - z(vect_size(x)); - iter.set_rhsnorm(gmm::sqrt(gmm::abs(vect_hp(PS, b, b)))); - - if (iter.get_rhsnorm() == 0.0) - clear(x); - else { - mult(A, scaled(x, T(-1)), b, r); - mult(P, r, z); - rho = vect_hp(PS, z, r); - copy(z, p); - - while (!iter.finished_vect(r)) { - - if (!iter.first()) { - mult(P, r, z); - rho = vect_hp(PS, z, r); - add(z, scaled(p, rho / rho_1), p); - } - mult(A, p, q); - - a = rho / vect_hp(PS, q, p); - add(scaled(p, a), x); - add(scaled(q, -a), r); - rho_1 = rho; - - ++iter; - } - } - } - - template - void cg(const Matrix& A, Vector1& x, const Vector2& b, const Matps& PS, - const gmm::identity_matrix &, iteration &iter) { - - typedef typename temporary_dense_vector::vector_type temp_vector; - typedef typename linalg_traits::value_type T; - - T rho, rho_1(0), a; - temp_vector p(vect_size(x)), q(vect_size(x)), r(vect_size(x)); - iter.set_rhsnorm(gmm::sqrt(gmm::abs(vect_hp(PS, b, b)))); - - if (iter.get_rhsnorm() == 0.0) - clear(x); - else { - mult(A, scaled(x, T(-1)), b, r); - rho = vect_hp(PS, r, r); - copy(r, p); - - while (!iter.finished_vect(r)) { - - if (!iter.first()) { - rho = vect_hp(PS, r, r); - add(r, scaled(p, rho / rho_1), p); - } - mult(A, p, q); - a = rho / vect_hp(PS, q, p); - add(scaled(p, a), x); - add(scaled(q, -a), r); - rho_1 = rho; - ++iter; - } - } - } - - template inline - void cg(const Matrix& A, const Vector1& x, const Vector2& b, const Matps& PS, - const Precond &P, iteration &iter) - { cg(A, linalg_const_cast(x), b, PS, P, iter); } - - template inline - void cg(const Matrix& A, Vector1& x, const Vector2& b, - const Precond &P, iteration &iter) - { cg(A, x , b, identity_matrix(), P, iter); } - - template inline - void cg(const Matrix& A, const Vector1& x, const Vector2& b, - const Precond &P, iteration &iter) - { cg(A, x , b , identity_matrix(), P , iter); } - -} - - -#endif // GMM_SOLVER_CG_H__ diff --git a/gmm/gmm_solver_constrained_cg.h b/gmm/gmm_solver_constrained_cg.h deleted file mode 100644 index 44716bffe..000000000 --- a/gmm/gmm_solver_constrained_cg.h +++ /dev/null @@ -1,165 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_solver_constrained_cg.h - @author Yves Renard - @date October 13, 2002. - @brief Constrained conjugate gradient. */ -// preconditionning does not work - -#ifndef GMM_SOLVER_CCG_H__ -#define GMM_SOLVER_CCG_H__ - -#include "gmm_kernel.h" -#include "gmm_iter.h" - -namespace gmm { - - template - void pseudo_inverse(const CMatrix &C, CINVMatrix &CINV, - const Matps& /* PS */, VectorX&) { - // compute the pseudo inverse of the non-square matrix C such - // CINV = inv(C * trans(C)) * C. - // based on a conjugate gradient method. - - // optimisable : copie de la ligne, precalcul de C * trans(C). - - typedef VectorX TmpVec; - typedef typename linalg_traits::value_type value_type; - - size_type nr = mat_nrows(C), nc = mat_ncols(C); - - TmpVec d(nr), e(nr), l(nc), p(nr), q(nr), r(nr); - value_type rho, rho_1, alpha; - clear(d); - clear(CINV); - - for (size_type i = 0; i < nr; ++i) { - d[i] = 1.0; rho = 1.0; - clear(e); - copy(d, r); - copy(d, p); - - while (rho >= 1E-38) { /* conjugate gradient to compute e */ - /* which is the i nd row of inv(C * trans(C)) */ - mult(gmm::transposed(C), p, l); - mult(C, l, q); - alpha = rho / vect_sp(p, q); - add(scaled(p, alpha), e); - add(scaled(q, -alpha), r); - rho_1 = rho; - rho = vect_sp(r, r); - add(r, scaled(p, rho / rho_1), p); - } - - mult(transposed(C), e, l); /* l is the i nd row of CINV */ - // cout << "l = " << l << endl; - clean(l, 1E-15); - copy(l, mat_row(CINV, i)); - - d[i] = 0.0; - } - } - - /** Compute the minimum of @f$ 1/2((Ax).x) - bx @f$ under the contraint @f$ Cx <= f @f$ */ - template < typename Matrix, typename CMatrix, typename Matps, - typename VectorX, typename VectorB, typename VectorF, - typename Preconditioner > - void constrained_cg(const Matrix& A, const CMatrix& C, VectorX& x, - const VectorB& b, const VectorF& f,const Matps& PS, - const Preconditioner& M, iteration &iter) { - typedef typename temporary_dense_vector::vector_type TmpVec; - typedef typename temporary_vector::vector_type TmpCVec; - typedef row_matrix TmpCmat; - - typedef typename linalg_traits::value_type value_type; - value_type rho = 1.0, rho_1, lambda, gamma; - TmpVec p(vect_size(x)), q(vect_size(x)), q2(vect_size(x)), - r(vect_size(x)), old_z(vect_size(x)), z(vect_size(x)), - memox(vect_size(x)); - std::vector satured(mat_nrows(C)); - clear(p); - iter.set_rhsnorm(sqrt(vect_sp(PS, b, b))); - if (iter.get_rhsnorm() == 0.0) iter.set_rhsnorm(1.0); - - TmpCmat CINV(mat_nrows(C), mat_ncols(C)); - pseudo_inverse(C, CINV, PS, x); - - while(true) { - // computation of residu - copy(z, old_z); - copy(x, memox); - mult(A, scaled(x, -1.0), b, r); - mult(M, r, z); // preconditionner not coherent - bool transition = false; - for (size_type i = 0; i < mat_nrows(C); ++i) { - value_type al = vect_sp(mat_row(C, i), x) - f[i]; - if (al >= -1.0E-15) { - if (!satured[i]) { satured[i] = true; transition = true; } - value_type bb = vect_sp(mat_row(CINV, i), z); - if (bb > 0.0) add(scaled(mat_row(C, i), -bb), z); - } - else - satured[i] = false; - } - - // descent direction - rho_1 = rho; rho = vect_sp(PS, r, z); // ... - - if (iter.finished(rho)) break; - - if (iter.get_noisy() > 0 && transition) std::cout << "transition\n"; - if (transition || iter.first()) gamma = 0.0; - else gamma = std::max(0.0, (rho - vect_sp(PS, old_z, z) ) / rho_1); - // std::cout << "gamma = " << gamma << endl; - // itl::add(r, itl::scaled(p, gamma), p); - add(z, scaled(p, gamma), p); // ... - - ++iter; - // one dimensionnal optimization - mult(A, p, q); - lambda = rho / vect_sp(PS, q, p); - for (size_type i = 0; i < mat_nrows(C); ++i) - if (!satured[i]) { - value_type bb = vect_sp(mat_row(C, i), p) - f[i]; - if (bb > 0.0) - lambda = std::min(lambda, (f[i]-vect_sp(mat_row(C, i), x)) / bb); - } - add(x, scaled(p, lambda), x); - add(memox, scaled(x, -1.0), memox); - - } - } - -} - -#endif // GMM_SOLVER_CCG_H__ diff --git a/gmm/gmm_solver_gmres.h b/gmm/gmm_solver_gmres.h deleted file mode 100644 index b124905e2..000000000 --- a/gmm/gmm_solver_gmres.h +++ /dev/null @@ -1,173 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -// This file is a modified version of gmres.h from ITL. -// See http://osl.iu.edu/research/itl/ -// Following the corresponding Copyright notice. -//=========================================================================== -// -// Copyright (c) 1998-2001, University of Notre Dame. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of Notre Dame nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE TRUSTEES OF INDIANA UNIVERSITY AND -// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES -// OF INDIANA UNIVERSITY AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//=========================================================================== - -/**@file gmm_solver_gmres.h - @author Andrew Lumsdaine - @author Lie-Quan Lee - @author Yves Renard - @date October 13, 2002. - @brief GMRES (Generalized Minimum Residual) iterative solver. -*/ -#ifndef GMM_KRYLOV_GMRES_H -#define GMM_KRYLOV_GMRES_H - -#include "gmm_kernel.h" -#include "gmm_iter.h" -#include "gmm_modified_gram_schmidt.h" - -namespace gmm { - - /** Generalized Minimum Residual - - This solve the unsymmetric linear system Ax = b using restarted GMRES. - - See: Y. Saad and M. Schulter. GMRES: A generalized minimum residual - algorithm for solving nonsysmmetric linear systems, SIAM - J. Sci. Statist. Comp. 7(1986), pp, 856-869 - */ - template - void gmres(const Mat &A, Vec &x, const VecB &b, const Precond &M, - int restart, iteration &outer, Basis& KS) { - - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - std::vector w(vect_size(x)), r(vect_size(x)), u(vect_size(x)); - std::vector c_rot(restart+1), s_rot(restart+1), s(restart+1); - gmm::dense_matrix H(restart+1, restart); -#ifdef GMM_USES_MPI - double t_ref, t_prec = MPI_Wtime(), t_tot = 0; - static double tmult_tot = 0.0; -t_ref = MPI_Wtime(); - cout << "GMRES " << endl; -#endif - mult(M,b,r); - outer.set_rhsnorm(gmm::vect_norm2(r)); - if (outer.get_rhsnorm() == 0.0) { clear(x); return; } - - mult(A, scaled(x, T(-1)), b, w); - mult(M, w, r); - R beta = gmm::vect_norm2(r), beta_old = beta; - int blocked = 0; - - iteration inner = outer; - inner.reduce_noisy(); - inner.set_maxiter(restart); - inner.set_name("GMRes inner"); - - while (! outer.finished(beta)) { - - gmm::copy(gmm::scaled(r, R(1)/beta), KS[0]); - gmm::clear(s); - s[0] = beta; - - size_type i = 0; inner.init(); - - do { - mult(A, KS[i], u); - mult(M, u, KS[i+1]); - orthogonalize(KS, mat_col(H, i), i); - R a = gmm::vect_norm2(KS[i+1]); - H(i+1, i) = T(a); - gmm::scale(KS[i+1], T(1) / a); - for (size_type k = 0; k < i; ++k) - Apply_Givens_rotation_left(H(k,i), H(k+1,i), c_rot[k], s_rot[k]); - - Givens_rotation(H(i,i), H(i+1,i), c_rot[i], s_rot[i]); - Apply_Givens_rotation_left(H(i,i), H(i+1,i), c_rot[i], s_rot[i]); - Apply_Givens_rotation_left(s[i], s[i+1], c_rot[i], s_rot[i]); - - ++inner, ++outer, ++i; - } while (! inner.finished(gmm::abs(s[i]))); - - upper_tri_solve(H, s, i, false); - combine(KS, s, x, i); - mult(A, gmm::scaled(x, T(-1)), b, w); - mult(M, w, r); - beta_old = std::min(beta, beta_old); beta = gmm::vect_norm2(r); - if (int(inner.get_iteration()) < restart -1 || beta_old <= beta) - ++blocked; else blocked = 0; - if (blocked > 10) { - if (outer.get_noisy()) cout << "Gmres is blocked, exiting\n"; - break; - } -#ifdef GMM_USES_MPI - t_tot = MPI_Wtime() - t_ref; - cout << "temps GMRES : " << t_tot << endl; -#endif - } - } - - - template - void gmres(const Mat &A, Vec &x, const VecB &b, - const Precond &M, int restart, iteration& outer) { - typedef typename linalg_traits::value_type T; - modified_gram_schmidt orth(restart, vect_size(x)); - gmres(A, x, b, M, restart, outer, orth); - } - -} - -#endif diff --git a/gmm/gmm_solver_idgmres.h b/gmm/gmm_solver_idgmres.h deleted file mode 100644 index 79bb9064d..000000000 --- a/gmm/gmm_solver_idgmres.h +++ /dev/null @@ -1,805 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard, Caroline Lecalvez - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_solver_idgmres.h - @author Caroline Lecalvez - @author Yves Renard - @date October 6, 2003. - @brief Implicitly restarted and deflated Generalized Minimum Residual. -*/ -#ifndef GMM_IDGMRES_H -#define GMM_IDGMRES_H - -#include "gmm_kernel.h" -#include "gmm_iter.h" -#include "gmm_dense_sylvester.h" - -namespace gmm { - - template compare_vp { - bool operator()(const std::pair &a, - const std::pair &b) const - { return (gmm::abs(a.first) > gmm::abs(b.first)); } - } - - struct idgmres_state { - size_type m, tb_deb, tb_def, p, k, nb_want, nb_unwant; - size_type nb_nolong, tb_deftot, tb_defwant, conv, nb_un, fin; - bool ok; - - idgmres_state(size_type mm, size_type pp, size_type kk) - : m(mm), tb_deb(1), tb_def(0), p(pp), k(kk), nb_want(0), - nb_unwant(0), nb_nolong(0), tb_deftot(0), tb_defwant(0), - conv(0), nb_un(0), fin(0), ok(false); {} - } - - idgmres_state(size_type mm, size_type pp, size_type kk) - : m(mm), tb_deb(1), tb_def(0), p(pp), k(kk), nb_want(0), - nb_unwant(0), nb_nolong(0), tb_deftot(0), tb_defwant(0), - conv(0), nb_un(0), fin(0), ok(false); {} - - - template - apply_permutation(CONT &cont, const IND &ind) { - size_type m = ind.end() - ind.begin(); - std::vector sorted(m, false); - - for (size_type l = 0; l < m; ++l) - if (!sorted[l] && ind[l] != l) { - - typeid(cont[0]) aux = cont[l]; - k = ind[l]; - cont[l] = cont[k]; - sorted[l] = true; - - for(k2 = ind[k]; k2 != l; k2 = ind[k]) { - cont[k] = cont[k2]; - sorted[k] = true; - k = k2; - } - cont[k] = aux; - } - } - - - /** Implicitly restarted and deflated Generalized Minimum Residual - - See: C. Le Calvez, B. Molina, Implicitly restarted and deflated - FOM and GMRES, numerical applied mathematics, - (30) 2-3 (1999) pp191-212. - - @param A Real or complex unsymmetric matrix. - @param x initial guess vector and final result. - @param b right hand side - @param M preconditionner - @param m size of the subspace between two restarts - @param p number of converged ritz values seeked - @param k size of the remaining Krylov subspace when the p ritz values - have not yet converged 0 <= p <= k < m. - @param tol_vp : tolerance on the ritz values. - @param outer - @param KS - */ - template < typename Mat, typename Vec, typename VecB, typename Precond, - typename Basis > - void idgmres(const Mat &A, Vec &x, const VecB &b, const Precond &M, - size_type m, size_type p, size_type k, double tol_vp, - iteration &outer, Basis& KS) { - - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - R a, beta; - idgmres_state st(m, p, k); - - std::vector w(vect_size(x)), r(vect_size(x)), u(vect_size(x)); - std::vector c_rot(m+1), s_rot(m+1), s(m+1); - std::vector y(m+1), ztest(m+1), gam(m+1); - std::vector gamma(m+1); - gmm::dense_matrix H(m+1, m), Hess(m+1, m), - Hobl(m+1, m), W(vect_size(x), m+1); - - gmm::clear(H); - - outer.set_rhsnorm(gmm::vect_norm2(b)); - if (outer.get_rhsnorm() == 0.0) { clear(x); return; } - - mult(A, scaled(x, -1.0), b, w); - mult(M, w, r); - beta = gmm::vect_norm2(r); - - iteration inner = outer; - inner.reduce_noisy(); - inner.set_maxiter(m); - inner.set_name("GMRes inner iter"); - - while (! outer.finished(beta)) { - - gmm::copy(gmm::scaled(r, 1.0/beta), KS[0]); - gmm::clear(s); - s[0] = beta; - gmm::copy(s, gamma); - - inner.set_maxiter(m - st.tb_deb + 1); - size_type i = st.tb_deb - 1; inner.init(); - - do { - mult(A, KS[i], u); - mult(M, u, KS[i+1]); - orthogonalize_with_refinment(KS, mat_col(H, i), i); - H(i+1, i) = a = gmm::vect_norm2(KS[i+1]); - gmm::scale(KS[i+1], R(1) / a); - - gmm::copy(mat_col(H, i), mat_col(Hess, i)); - gmm::copy(mat_col(H, i), mat_col(Hobl, i)); - - - for (size_type l = 0; l < i; ++l) - Apply_Givens_rotation_left(H(l,i), H(l+1,i), c_rot[l], s_rot[l]); - - Givens_rotation(H(i,i), H(i+1,i), c_rot[i], s_rot[i]); - Apply_Givens_rotation_left(H(i,i), H(i+1,i), c_rot[i], s_rot[i]); - H(i+1, i) = T(0); - Apply_Givens_rotation_left(s[i], s[i+1], c_rot[i], s_rot[i]); - - ++inner, ++outer, ++i; - } while (! inner.finished(gmm::abs(s[i]))); - - if (inner.converged()) { - gmm::copy(s, y); - upper_tri_solve(H, y, i, false); - combine(KS, y, x, i); - mult(A, gmm::scaled(x, T(-1)), b, w); - mult(M, w, r); - beta = gmm::vect_norm2(r); // + verif sur beta ... à faire - break; - } - - gmm::clear(gam); gam[m] = s[i]; - for (size_type l = m; l > 0; --l) - Apply_Givens_rotation_left(gam[l-1], gam[l], gmm::conj(c_rot[l-1]), - -s_rot[l-1]); - - mult(KS.mat(), gam, r); - beta = gmm::vect_norm2(r); - - mult(Hess, scaled(y, T(-1)), gamma, ztest); - // En fait, d'après Caroline qui s'y connait ztest et gam devrait - // être confondus - // Quand on aura vérifié que ça marche, il faudra utiliser gam à la - // place de ztest. - if (st.tb_def < p) { - T nss = H(m,m-1) / ztest[m]; - nss /= gmm::abs(nss); // ns à calculer plus tard aussi - gmm::copy(KS.mat(), W); gmm::copy(scaled(r, nss /beta), mat_col(W, m)); - - // Computation of the oblique matrix - sub_interval SUBI(0, m); - add(scaled(sub_vector(ztest, SUBI), -Hobl(m, m-1) / ztest[m]), - sub_vector(mat_col(Hobl, m-1), SUBI)); - Hobl(m, m-1) *= nss * beta / ztest[m]; - - /* **************************************************************** */ - /* Locking */ - /* **************************************************************** */ - - // Computation of the Ritz eigenpairs. - std::vector > eval(m); - dense_matrix YB(m-st.tb_def, m-st.tb_def); - std::vector pure(m-st.tb_def, 0); - gmm::clear(YB); - - select_eval(Hobl, eval, YB, pure, st); - - if (st.conv != 0) { - // DEFLATION using the QR Factorization of YB - - T alpha = Lock(W, Hobl, - sub_matrix(YB, sub_interval(0, m-st.tb_def)), - sub_interval(st.tb_def, m-st.tb_def), - (st.tb_defwant < p)); - // ns *= alpha; // à calculer plus tard ?? - // V(:,m+1) = alpha*V(:, m+1); ça devait servir à qlq chose ... - - - // Clean the portions below the diagonal corresponding - // to the lock Schur vectors - - for (size_type j = st.tb_def; j < st.tb_deftot; ++j) { - if ( pure[j-st.tb_def] == 0) - gmm::clear(sub_vector(mat_col(Hobl,j), sub_interval(j+1,m-j))); - else if (pure[j-st.tb_def] == 1) { - gmm::clear(sub_matrix(Hobl, sub_interval(j+2,m-j-1), - sub_interval(j, 2))); - ++j; - } - else GMM_ASSERT3(false, "internal error"); - } - - if (!st.ok) { - - // attention si m = 0; - size_type mm = std::min(k+st.nb_unwant+st.nb_nolong, m-1); - - if (eval_sort[m-mm-1].second != R(0) - && eval_sort[m-mm-1].second == -eval_sort[m-mm].second) ++mm; - - std::vector > shifts(m-mm); - for (size_type i = 0; i < m-mm; ++i) - shifts[i] = eval_sort[i].second; - - apply_shift_to_Arnoldi_factorization(W, Hobl, shifts, mm, - m-mm, true); - - st.fin = mm; - } - else - st.fin = st.tb_deftot; - - - /* ************************************************************** */ - /* Purge */ - /* ************************************************************** */ - - if (st.nb_nolong + st.nb_unwant > 0) { - - std::vector > eval(m); - dense_matrix YB(st.fin, st.tb_deftot); - std::vector pure(st.tb_deftot, 0); - gmm::clear(YB); - st.nb_un = st.nb_nolong + st.nb_unwant; - - select_eval_for_purging(Hobl, eval, YB, pure, st); - - T alpha = Lock(W, Hobl, YB, sub_interval(0, st.fin), ok); - - // Clean the portions below the diagonal corresponding - // to the unwanted lock Schur vectors - - for (size_type j = 0; j < st.tb_deftot; ++j) { - if ( pure[j] == 0) - gmm::clear(sub_vector(mat_col(Hobl,j), sub_interval(j+1,m-j))); - else if (pure[j] == 1) { - gmm::clear(sub_matrix(Hobl, sub_interval(j+2,m-j-1), - sub_interval(j, 2))); - ++j; - } - else GMM_ASSERT3(false, "internal error"); - } - - gmm::dense_matrix z(st.nb_un, st.fin - st.nb_un); - sub_interval SUBI(0, st.nb_un), SUBJ(st.nb_un, st.fin - st.nb_un); - sylvester(sub_matrix(Hobl, SUBI), - sub_matrix(Hobl, SUBJ), - sub_matrix(gmm::scaled(Hobl, -T(1)), SUBI, SUBJ), z); - - } - - } - - } - } - } - - - template < typename Mat, typename Vec, typename VecB, typename Precond > - void idgmres(const Mat &A, Vec &x, const VecB &b, - const Precond &M, size_type m, iteration& outer) { - typedef typename linalg_traits::value_type T; - modified_gram_schmidt orth(m, vect_size(x)); - gmres(A, x, b, M, m, outer, orth); - } - - - // Lock stage of an implicit restarted Arnoldi process. - // 1- QR factorization of YB through Householder matrices - // Q(Rl) = YB - // (0 ) - // 2- Update of the Arnoldi factorization. - // H <- Q*HQ, W <- WQ - // 3- Restore the Hessemberg form of H. - - template - void Lock(gmm::dense_matrix &W, gmm::dense_matrix &H, - const MATYB &YB, const sub_interval SUB, - bool restore, T &ns) { - - size_type n = mat_nrows(W), m = mat_ncols(W) - 1; - size_type ncols = mat_ncols(YB), nrows = mat_nrows(YB); - size_type begin = min(SUB); end = max(SUB) - 1; - sub_interval SUBR(0, nrows), SUBC(0, ncols); - T alpha(1); - - GMM_ASSERT2(((end-begin) == ncols) && (m == mat_nrows(H)) - && (m+1 == mat_ncols(H)), "dimensions mismatch"); - - // DEFLATION using the QR Factorization of YB - - dense_matrix QR(n_rows, n_rows); - gmmm::copy(YB, sub_matrix(QR, SUBR, SUBC)); - gmm::clear(submatrix(QR, SUBR, sub_interval(ncols, nrows-ncols))); - qr_factor(QR); - - - apply_house_left(QR, sub_matrix(H, SUB)); - apply_house_right(QR, sub_matrix(H, SUBR, SUB)); - apply_house_right(QR, sub_matrix(W, sub_interval(0, n), SUB)); - - // Restore to the initial block hessenberg form - - if (restore) { - - // verifier quand m = 0 ... - gmm::dense_matrix tab_p(end - st.tb_deftot, end - st.tb_deftot); - gmm::copy(identity_matrix(), tab_p); - - for (size_type j = end-1; j >= st.tb_deftot+2; --j) { - - size_type jm = j-1; - std::vector v(jm - st.tb_deftot); - sub_interval SUBtot(st.tb_deftot, jm - st.tb_deftot); - sub_interval SUBtot2(st.tb_deftot, end - st.tb_deftot); - gmm::copy(sub_vector(mat_row(H, j), SUBtot), v); - house_vector_last(v); - w.resize(end); - col_house_update(sub_matrix(H, SUBI, SUBtot), v, w); - w.resize(end - st.tb_deftot); - row_house_update(sub_matrix(H, SUBtot, SUBtot2), v, w); - gmm::clear(sub_vector(mat_row(H, j), - sub_interval(st.tb_deftot, j-1-st.tb_deftot))); - w.resize(end - st.tb_deftot); - col_house_update(sub_matrix(tab_p, sub_interval(0, end-st.tb_deftot), - sub_interval(0, jm-st.tb_deftot)), v, w); - w.resize(n); - col_house_update(sub_matrix(W, sub_interval(0, n), SUBtot), v, w); - } - - // restore positive subdiagonal elements - - std::vector d(fin-st.tb_deftot); d[0] = T(1); - - // We compute d[i+1] in order - // (d[i+1] * H(st.tb_deftot+i+1,st.tb_deftoti)) / d[i] - // be equal to |H(st.tb_deftot+i+1,st.tb_deftot+i))|. - for (size_type j = 0; j+1 < end-st.tb_deftot; ++j) { - T e = H(st.tb_deftot+j, st.tb_deftot+j-1); - d[j+1] = (e == T(0)) ? T(1) : d[j] * gmm::abs(e) / e; - scale(sub_vector(mat_row(H, st.tb_deftot+j+1), - sub_interval(st.tb_deftot, m-st.tb_deftot)), d[j+1]); - scale(mat_col(H, st.tb_deftot+j+1), T(1) / d[j+1]); - scale(mat_col(W, st.tb_deftot+j+1), T(1) / d[j+1]); - } - - alpha = tab_p(end-st.tb_deftot-1, end-st.tb_deftot-1) / d[end-st.tb_deftot-1]; - alpha /= gmm::abs(alpha); - scale(mat_col(W, m), alpha); - - } - - return alpha; - } - - - - - - - - - // Apply p implicit shifts to the Arnoldi factorization - // AV = VH+H(k+p+1,k+p) V(:,k+p+1) e_{k+p}* - // and produces the following new Arnoldi factorization - // A(VQ) = (VQ)(Q*HQ)+H(k+p+1,k+p) V(:,k+p+1) e_{k+p}* Q - // where only the first k columns are relevant. - // - // Dan Sorensen and Richard J. Radke, 11/95 - template - apply_shift_to_Arnoldi_factorization(dense_matrix V, dense_matrix H, - std::vector Lambda, size_type &k, - size_type p, bool true_shift = false) { - - - size_type k1 = 0, num = 0, kend = k+p, kp1 = k + 1; - bool mark = false; - T c, s, x, y, z; - - dense_matrix q(1, kend); - gmm::clear(q); q(0,kend-1) = T(1); - std::vector hv(3), w(std::max(kend, mat_nrows(V))); - - for(size_type jj = 0; jj < p; ++jj) { - // compute and apply a bulge chase sweep initiated by the - // implicit shift held in w(jj) - - if (abs(Lambda[jj].real()) == 0.0) { - // apply a real shift using 2 by 2 Givens rotations - - for (size_type k1 = 0, k2 = 0; k2 != kend-1; k1 = k2+1) { - k2 = k1; - while (h(k2+1, k2) != T(0) && k2 < kend-1) ++k2; - - Givens_rotation(H(k1, k1) - Lambda[jj], H(k1+1, k1), c, s); - - for (i = k1; i <= k2; ++i) { - if (i > k1) Givens_rotation(H(i, i-1), H(i+1, i-1), c, s); - - // Ne pas oublier de nettoyer H(i+1,i-1) (le mettre à zéro). - // Vérifier qu'au final H(i+1,i) est bien un réel positif. - - // apply rotation from left to rows of H - row_rot(sub_matrix(H, sub_interval(i,2), sub_interval(i, kend-i)), - c, s, 0, 0); - - // apply rotation from right to columns of H - size_type ip2 = std::min(i+2, kend); - col_rot(sub_matrix(H, sub_interval(0, ip2), sub_interval(i, 2)) - c, s, 0, 0); - - // apply rotation from right to columns of V - col_rot(V, c, s, i, i+1); - - // accumulate e' Q so residual can be updated k+p - Apply_Givens_rotation_left(q(0,i), q(0,i+1), c, s); - // peut être que nous utilisons G au lieu de G* et que - // nous allons trop loin en k2. - } - } - - num = num + 1; - } - else { - - // Apply a double complex shift using 3 by 3 Householder - // transformations - - if (jj == p || mark) - mark = false; // skip application of conjugate shift - else { - num = num + 2; // mark that a complex conjugate - mark = true; // pair has been applied - - // Indices de fin de boucle à surveiller... de près ! - for (size_type k1 = 0, k3 = 0; k3 != kend-2; k1 = k3+1) { - k3 = k1; - while (h(k3+1, k3) != T(0) && k3 < kend-2) ++k3; - size_type k2 = k1+1; - - - x = H(k1,k1) * H(k1,k1) + H(k1,k2) * H(k2,k1) - - 2.0*Lambda[jj].real() * H(k1,k1) + gmm::abs_sqr(Lambda[jj]); - y = H(k2,k1) * (H(k1,k1) + H(k2,k2) - 2.0*Lambda[jj].real()); - z = H(k2+1,k2) * H(k2,k1); - - for (size_type i = k1; i <= k3; ++i) { - if (i > k1) { - x = H(i, i-1); - y = H(i+1, i-1); - z = H(i+2, i-1); - // Ne pas oublier de nettoyer H(i+1,i-1) et H(i+2,i-1) - // (les mettre à zéro). - } - - hv[0] = x; hv[1] = y; hv[2] = z; - house_vector(v); - - // Vérifier qu'au final H(i+1,i) est bien un réel positif - - // apply transformation from left to rows of H - w.resize(kend-i); - row_house_update(sub_matrix(H, sub_interval(i, 2), - sub_interval(i, kend-i)), v, w); - - // apply transformation from right to columns of H - - size_type ip3 = std::min(kend, i + 3); - w.resize(ip3); - col_house_update(sub_matrix(H, sub_interval(0, ip3), - sub_interval(i, 2)), v, w); - - // apply transformation from right to columns of V - - w.resize(mat_nrows(V)); - col_house_update(sub_matrix(V, sub_interval(0, mat_nrows(V)), - sub_interval(i, 2)), v, w); - - // accumulate e' Q so residual can be updated k+p - - w.resize(1); - col_house_update(sub_matrix(q, sub_interval(0,1), - sub_interval(i,2)), v, w); - - } - } - - // clean up step with Givens rotation - - i = kend-2; - c = x; s = y; - if (i > k1) Givens_rotation(H(i, i-1), H(i+1, i-1), c, s); - - // Ne pas oublier de nettoyer H(i+1,i-1) (le mettre à zéro). - // Vérifier qu'au final H(i+1,i) est bien un réel positif. - - // apply rotation from left to rows of H - row_rot(sub_matrix(H, sub_interval(i,2), sub_interval(i, kend-i)), - c, s, 0, 0); - - // apply rotation from right to columns of H - size_type ip2 = std::min(i+2, kend); - col_rot(sub_matrix(H, sub_interval(0, ip2), sub_interval(i, 2)) - c, s, 0, 0); - - // apply rotation from right to columns of V - col_rot(V, c, s, i, i+1); - - // accumulate e' Q so residual can be updated k+p - Apply_Givens_rotation_left(q(0,i), q(0,i+1), c, s); - - } - } - } - - // update residual and store in the k+1 -st column of v - - k = kend - num; - scale(mat_col(V, kend), q(0, k)); - - if (k < mat_nrows(H)) { - if (true_shift) - gmm::copy(mat_col(V, kend), mat_col(V, k)); - else - // v(:,k+1) = v(:,kend+1) + v(:,k+1)*h(k+1,k); - // v(:,k+1) = v(:,kend+1) ; - gmm::add(scaled(mat_col(V, kend), H(kend, kend-1)), - scaled(mat_col(V, k), H(k, k-1)), mat_col(V, k)); - } - - H(k, k-1) = vect_norm2(mat_col(V, k)); - scale(mat_col(V, kend), T(1) / H(k, k-1)); - } - - - - template - void select_eval(const MAT &Hobl, EVAL &eval, MAT &YB, PURE &pure, - idgmres_state &st) { - - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - size_type m = st.m; - - // Computation of the Ritz eigenpairs. - - col_matrix< std::vector > evect(m-st.tb_def, m-st.tb_def); - // std::vector > eval(m); - std::vector ritznew(m, T(-1)); - - // dense_matrix evect_lock(st.tb_def, st.tb_def); - - sub_interval SUB1(st.tb_def, m-st.tb_def); - implicit_qr_algorithm(sub_matrix(Hobl, SUB1), - sub_vector(eval, SUB1), evect); - sub_interval SUB2(0, st.tb_def); - implicit_qr_algorithm(sub_matrix(Hobl, SUB2), - sub_vector(eval, SUB2), /* evect_lock */); - - for (size_type l = st.tb_def; l < m; ++l) - ritznew[l] = gmm::abs(evect(m-st.tb_def-1, l-st.tb_def) * Hobl(m, m-1)); - - std::vector< std::pair > eval_sort(m); - for (size_type l = 0; l < m; ++l) - eval_sort[l] = std::pair(eval[l], l); - std::sort(eval_sort.begin(), eval_sort.end(), compare_vp()); - - std::vector index(m); - for (size_type l = 0; l < m; ++l) index[l] = eval_sort[l].second; - - std::vector kept(m, false); - std::fill(kept.begin(), kept.begin()+st.tb_def, true); - - apply_permutation(eval, index); - apply_permutation(evect, index); - apply_permutation(ritznew, index); - apply_permutation(kept, index); - - // Which are the eigenvalues that converged ? - // - // nb_want is the number of eigenvalues of - // Hess(tb_def+1:n,tb_def+1:n) that converged and are WANTED - // - // nb_unwant is the number of eigenvalues of - // Hess(tb_def+1:n,tb_def+1:n) that converged and are UNWANTED - // - // nb_nolong is the number of eigenvalues of - // Hess(1:tb_def,1:tb_def) that are NO LONGER WANTED. - // - // tb_deftot is the number of the deflated eigenvalues - // that is tb_def + nb_want + nb_unwant - // - // tb_defwant is the number of the wanted deflated eigenvalues - // that is tb_def + nb_want - nb_nolong - - st.nb_want = 0, st.nb_unwant = 0, st.nb_nolong = 0; - size_type j, ind; - - for (j = 0, ind = 0; j < m-p; ++j) { - if (ritznew[j] == R(-1)) { - if (std::imag(eval[j]) != R(0)) { - st.nb_nolong += 2; ++j; // à adapter dans le cas complexe ... - } - else st.nb_nolong++; - } - else { - if (ritznew[j] - < tol_vp * gmm::abs(eval[j])) { - - for (size_type l = 0, l < m-st.tb_def; ++l) - YB(l, ind) = std::real(evect(l, j)); - kept[j] = true; - ++j; ++st.nb_unwant; ind++; - - if (std::imag(eval[j]) != R(0)) { - for (size_type l = 0, l < m-st.tb_def; ++l) - YB(l, ind) = std::imag(evect(l, j)); - pure[ind-1] = 1; - pure[ind] = 2; - - kept[j] = true; - - st.nb_unwant++; - ++ind; - } - } - } - } - - - for (; j < m; ++j) { - if (ritznew[j] != R(-1)) { - - for (size_type l = 0, l < m-st.tb_def; ++l) - YB(l, ind) = std::real(evect(l, j)); - pure[ind] = 1; - ++ind; - kept[j] = true; - ++st.nb_want; - - if (ritznew[j] - < tol_vp * gmm::abs(eval[j])) { - for (size_type l = 0, l < m-st.tb_def; ++l) - YB(l, ind) = std::imag(evect(l, j)); - pure[ind] = 2; - - j++; - kept[j] = true; - - st.nb_want++; - ++ind; - } - } - } - - std::vector shift(m - st.tb_def - st.nb_want - st.nb_unwant); - for (size_type j = 0, i = 0; j < m; ++j) - if (!kept[j]) shift[i++] = eval[j]; - - // st.conv (st.nb_want+st.nb_unwant) is the number of eigenpairs that - // have just converged. - // st.tb_deftot is the total number of eigenpairs that have converged. - - size_type st.conv = ind; - size_type st.tb_deftot = st.tb_def + st.conv; - size_type st.tb_defwant = st.tb_def + st.nb_want - st.nb_nolong; - - sub_interval SUBYB(0, st.conv); - - if ( st.tb_defwant >= p ) { // An invariant subspace has been found. - - st.nb_unwant = 0; - st.nb_want = p + st.nb_nolong - st.tb_def; - st.tb_defwant = p; - - if ( pure[st.conv - st.nb_want + 1] == 2 ) { - ++st.nb_want; st.tb_defwant = ++p;// il faudrait que ce soit un p local - } - - SUBYB = sub_interval(st.conv - st.nb_want, st.nb_want); - // YB = YB(:, st.conv-st.nb_want+1 : st.conv); // On laisse en suspend .. - // pure = pure(st.conv-st.nb_want+1 : st.conv,1); // On laisse suspend .. - st.conv = st.nb_want; - st.tb_deftot = st.tb_def + st.conv; - st.ok = true; - } - - } - - - - template - void select_eval_for_purging(const MAT &Hobl, EVAL &eval, MAT &YB, - PURE &pure, idgmres_state &st) { - - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - size_type m = st.m; - - // Computation of the Ritz eigenpairs. - - col_matrix< std::vector > evect(st.tb_deftot, st.tb_deftot); - - sub_interval SUB1(0, st.tb_deftot); - implicit_qr_algorithm(sub_matrix(Hobl, SUB1), - sub_vector(eval, SUB1), evect); - std::fill(eval.begin() + st.tb_deftot, eval.end(), std::complex(0)); - - std::vector< std::pair > eval_sort(m); - for (size_type l = 0; l < m; ++l) - eval_sort[l] = std::pair(eval[l], l); - std::sort(eval_sort.begin(), eval_sort.end(), compare_vp()); - - std::vector sorted(m); - std::fill(sorted.begin(), sorted.end(), false); - - std::vector ind(m); - for (size_type l = 0; l < m; ++l) ind[l] = eval_sort[l].second; - - std::vector kept(m, false); - std::fill(kept.begin(), kept.begin()+st.tb_def, true); - - apply_permutation(eval, ind); - apply_permutation(evect, ind); - - size_type j; - for (j = 0; j < st.tb_deftot; ++j) { - - for (size_type l = 0, l < st.tb_deftot; ++l) - YB(l, j) = std::real(evect(l, j)); - - if (std::imag(eval[j]) != R(0)) { - for (size_type l = 0, l < m-st.tb_def; ++l) - YB(l, j+1) = std::imag(evect(l, j)); - pure[j] = 1; - pure[j+1] = 2; - - j += 2; - } - else ++j; - } - } - - - - - - -} - -#endif diff --git a/gmm/gmm_solver_qmr.h b/gmm/gmm_solver_qmr.h deleted file mode 100644 index ca6b8e075..000000000 --- a/gmm/gmm_solver_qmr.h +++ /dev/null @@ -1,210 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -// This file is a modified version of qmr.h from ITL. -// See http://osl.iu.edu/research/itl/ -// Following the corresponding Copyright notice. -//=========================================================================== -// -// Copyright (c) 1997-2001, The Trustees of Indiana University. -// All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the University of Notre Dame nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE TRUSTEES OF INDIANA UNIVERSITY AND -// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES -// OF INDIANA UNIVERSITY AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -//=========================================================================== - -/**@file gmm_solver_qmr.h - @author Andrew Lumsdaine - @author Lie-Quan Lee - @author Yves Renard - @date October 13, 2002. - @brief Quasi-Minimal Residual iterative solver. -*/ -#ifndef GMM_QMR_H -#define GMM_QMR_H - -#include "gmm_kernel.h" -#include "gmm_iter.h" - -namespace gmm { - - /** Quasi-Minimal Residual. - - This routine solves the unsymmetric linear system Ax = b using - the Quasi-Minimal Residual method. - - See: R. W. Freund and N. M. Nachtigal, A quasi-minimal residual - method for non-Hermitian linear systems, Numerical Math., - 60(1991), pp. 315-339 - - Preconditioner - Incomplete LU, Incomplete LU with threshold, - SSOR or identity_preconditioner. - */ - template - void qmr(const Matrix &A, Vector &x, const VectorB &b, const Precond1 &M1, - iteration& iter) { - - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - T delta(0), ep(0), beta(0), theta_1(0), gamma_1(0); - T theta(0), gamma(1), eta(-1); - R rho_1(0), rho, xi; - - typedef typename temporary_vector::vector_type TmpVec; - size_type nn = vect_size(x); - TmpVec r(nn), v_tld(nn), y(nn), w_tld(nn), z(nn), v(nn), w(nn); - TmpVec y_tld(nn), z_tld(nn), p(nn), q(nn), p_tld(nn), d(nn), s(nn); - - iter.set_rhsnorm(double(gmm::vect_norm2(b))); - if (iter.get_rhsnorm() == 0.0) { clear(x); return; } - - gmm::mult(A, gmm::scaled(x, T(-1)), b, r); - gmm::copy(r, v_tld); - - gmm::left_mult(M1, v_tld, y); - rho = gmm::vect_norm2(y); - - gmm::copy(r, w_tld); - gmm::transposed_right_mult(M1, w_tld, z); - xi = gmm::vect_norm2(z); - - while (! iter.finished_vect(r)) { - - if (rho == R(0) || xi == R(0)) { - if (iter.get_maxiter() == size_type(-1)) - { GMM_ASSERT1(false, "QMR failed to converge"); } - else { GMM_WARNING1("QMR failed to converge"); return; } - } - gmm::copy(gmm::scaled(v_tld, T(R(1)/rho)), v); - gmm::scale(y, T(R(1)/rho)); - - gmm::copy(gmm::scaled(w_tld, T(R(1)/xi)), w); - gmm::scale(z, T(R(1)/xi)); - - delta = gmm::vect_sp(z, y); - if (delta == T(0)) { - if (iter.get_maxiter() == size_type(-1)) - { GMM_ASSERT1(false, "QMR failed to converge"); } - else { GMM_WARNING1("QMR failed to converge"); return; } - } - gmm::right_mult(M1, y, y_tld); - gmm::transposed_left_mult(M1, z, z_tld); - - if (iter.first()) { - gmm::copy(y_tld, p); - gmm::copy(z_tld, q); - } else { - gmm::add(y_tld, gmm::scaled(p, -(T(xi * delta) / ep)), p); - gmm::add(z_tld, gmm::scaled(q, -(T(rho * delta) / ep)), q); - } - - gmm::mult(A, p, p_tld); - - ep = gmm::vect_sp(q, p_tld); - if (ep == T(0)) { - if (iter.get_maxiter() == size_type(-1)) - { GMM_ASSERT1(false, "QMR failed to converge"); } - else { GMM_WARNING1("QMR failed to converge"); return; } - } - beta = ep / delta; - if (beta == T(0)) { - if (iter.get_maxiter() == size_type(-1)) - { GMM_ASSERT1(false, "QMR failed to converge"); } - else { GMM_WARNING1("QMR failed to converge"); return; } - } - gmm::add(p_tld, gmm::scaled(v, -beta), v_tld); - gmm::left_mult(M1, v_tld, y); - - rho_1 = rho; - rho = gmm::vect_norm2(y); - - gmm::mult(gmm::transposed(A), q, w_tld); - gmm::add(w_tld, gmm::scaled(w, -beta), w_tld); - gmm::transposed_right_mult(M1, w_tld, z); - - xi = gmm::vect_norm2(z); - - gamma_1 = gamma; - theta_1 = theta; - - theta = rho / (gamma_1 * beta); - gamma = T(1) / gmm::sqrt(T(1) + gmm::sqr(theta)); - - if (gamma == T(0)) { - if (iter.get_maxiter() == size_type(-1)) - { GMM_ASSERT1(false, "QMR failed to converge"); } - else { GMM_WARNING1("QMR failed to converge"); return; } - } - eta = -eta * T(rho_1) * gmm::sqr(gamma) / (beta * gmm::sqr(gamma_1)); - - if (iter.first()) { - gmm::copy(gmm::scaled(p, eta), d); - gmm::copy(gmm::scaled(p_tld, eta), s); - } else { - T tmp = gmm::sqr(theta_1 * gamma); - gmm::add(gmm::scaled(p, eta), gmm::scaled(d, tmp), d); - gmm::add(gmm::scaled(p_tld, eta), gmm::scaled(s, tmp), s); - } - gmm::add(d, x); - gmm::add(gmm::scaled(s, T(-1)), r); - - ++iter; - } - } - - -} - -#endif - diff --git a/gmm/gmm_std.h b/gmm/gmm_std.h deleted file mode 100644 index 40d7d19a6..000000000 --- a/gmm/gmm_std.h +++ /dev/null @@ -1,417 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_std.h -@author Yves Renard , -@author Julien Pommier -@date June 01, 1995. -@brief basic setup for gmm (includes, typedefs etc.) -*/ -#ifndef GMM_STD_H__ -#define GMM_STD_H__ - -#ifndef __USE_STD_IOSTREAM -# define __USE_STD_IOSTREAM -#endif - -#ifndef __USE_BSD -# define __USE_BSD -#endif - -#ifndef __USE_ISOC99 -# define __USE_ISOC99 -#endif - -#if defined(_MSC_VER) && _MSC_VER >= 1400 // Secure versions for VC++ -# define GMM_SECURE_CRT -# define SECURE_NONCHAR_SSCANF sscanf_s -# define SECURE_NONCHAR_FSCANF fscanf_s -# define SECURE_STRNCPY(a, la, b, lb) strncpy_s(a, la, b, lb) -# define SECURE_FOPEN(F, filename, mode) (*(F) = 0, fopen_s(F, filename, mode)) -# define SECURE_SPRINTF1(S, l, st, p1) sprintf_s(S, l, st, p1) -# define SECURE_SPRINTF2(S, l, st, p1, p2) sprintf_s(S, l, st, p1, p2) -# define SECURE_SPRINTF4(S, l, st, p1, p2, p3, p4) sprintf_s(S, l, st, p1, p2, p3, p4) -# define SECURE_STRDUP(s) _strdup(s) -# ifndef _SCL_SECURE_NO_DEPRECATE -# error Add the option /D_SCL_SECURE_NO_DEPRECATE to the compilation command -# endif -#else -# define SECURE_NONCHAR_SSCANF sscanf -# define SECURE_NONCHAR_FSCANF fscanf -# define SECURE_STRNCPY(a, la, b, lb) strncpy(a, b, lb) -# define SECURE_FOPEN(F, filename, mode) ((*(F)) = fopen(filename, mode)) -# define SECURE_SPRINTF1(S, l, st, p1) sprintf(S, st, p1) -# define SECURE_SPRINTF2(S, l, st, p1, p2) sprintf(S, st, p1, p2) -# define SECURE_SPRINTF4(S, l, st, p1, p2, p3, p4) sprintf(S, st, p1, p2, p3, p4) -# define SECURE_STRDUP(s) strdup(s) -#endif - -inline void GMM_NOPERATION_(int) { } -#define GMM_NOPERATION(a) { GMM_NOPERATION_(abs(&(a) != &(a))); } - -/* ********************************************************************** */ -/* Compilers detection. */ -/* ********************************************************************** */ - -/* for VISUAL C++ ... -#if defined(_MSC_VER) // && !defined(__MWERKS__) -#define _GETFEM_MSVCPP_ _MSC_VER -#endif -*/ - -#if defined(__GNUC__) -# if (__GNUC__ < 4) -# error : PLEASE UPDATE g++ TO AT LEAST 4.8 VERSION -# endif -#endif - -/* ********************************************************************** */ -/* C++ Standard Headers. */ -/* ********************************************************************** */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace std { -#if defined(__GNUC__) && (__cplusplus <= 201103L) - template - struct _MakeUniq - { typedef unique_ptr<_Tp> __single_object; }; - template - struct _MakeUniq<_Tp[]> - { typedef unique_ptr<_Tp[]> __array; }; - template - struct _MakeUniq<_Tp[_Bound]> - { struct __invalid_type { }; }; - /// std::make_unique for single objects - template - inline typename _MakeUniq<_Tp>::__single_object - make_unique(_Args&&... __args) - { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } - /// std::make_unique for arrays of unknown bound - template - inline typename _MakeUniq<_Tp>::__array - make_unique(size_t __num) - { return unique_ptr<_Tp>(new typename remove_extent<_Tp>::type[__num]()); } - /// Disable std::make_unique for arrays of known bound - template - inline typename _MakeUniq<_Tp>::__invalid_type - make_unique(_Args&&...) = delete; -#endif - - - // Should simply be replaced by std::shared_ptr when it will be supported - // by the STL - template class shared_array_ptr : shared_ptr { - public: - shared_array_ptr() {} - shared_array_ptr(T *q) : std::shared_ptr(q, default_delete()) {} - template shared_array_ptr(const std::shared_ptr &p, T *q) - : std::shared_ptr(p, q) {} - T *get() const { return shared_ptr::get(); } - T& operator*() const { return shared_ptr::operator*(); } - T* operator->() const { return shared_ptr::operator->(); } - }; - - template shared_array_ptr make_shared_array(size_t num) - { return shared_array_ptr(new T[num]); } -} - - - - -#ifdef GMM_HAVE_OPENMP - -#include - /**number of OpenMP threads*/ - inline size_t num_threads(){return omp_get_max_threads();} - /**index of the current thread*/ - inline size_t this_thread() {return omp_get_thread_num();} - /**is the program running in the parallel section*/ - inline bool me_is_multithreaded_now(){return static_cast(omp_in_parallel());} -#else - inline size_t num_threads(){return size_t(1);} - inline size_t this_thread() {return size_t(0);} - inline bool me_is_multithreaded_now(){return false;} -#endif - -namespace gmm { - - using std::endl; using std::cout; using std::cerr; - using std::ends; using std::cin; using std::isnan; - -#ifdef _WIN32 - - class standard_locale { - std::string cloc; - std::locale cinloc; - public : - inline standard_locale(void) : cinloc(cin.getloc()) - { - if (!me_is_multithreaded_now()){ - cloc=setlocale(LC_NUMERIC, 0); - setlocale(LC_NUMERIC,"C"); - } - } - - inline ~standard_locale() { - if (!me_is_multithreaded_now()) - setlocale(LC_NUMERIC, cloc.c_str()); - - } - }; -#else - /**this is the above solutions for linux, but it still needs to be tested.*/ - //class standard_locale { - // locale_t oldloc; - // locale_t temploc; - - //public : - // inline standard_locale(void) : oldloc(uselocale((locale_t)0)) - // { - // temploc = newlocale(LC_NUMERIC, "C", NULL); - // uselocale(temploc); - // } - - // inline ~standard_locale() - // { - // uselocale(oldloc); - // freelocale(temploc); - // } - //}; - - - class standard_locale { - std::string cloc; - std::locale cinloc; - - public : - inline standard_locale(void) - : cloc(setlocale(LC_NUMERIC, 0)), cinloc(cin.getloc()) - { setlocale(LC_NUMERIC,"C"); cin.imbue(std::locale("C")); } - inline ~standard_locale() - { setlocale(LC_NUMERIC, cloc.c_str()); cin.imbue(cinloc); } - }; - - -#endif - - class stream_standard_locale { - std::locale cloc; - std::ios &io; - - public : - inline stream_standard_locale(std::ios &i) - : cloc(i.getloc()), io(i) { io.imbue(std::locale("C")); } - inline ~stream_standard_locale() { io.imbue(cloc); } - }; - - - - - /* ******************************************************************* */ - /* Clock functions. */ - /* ******************************************************************* */ - -# if defined(HAVE_SYS_TIMES) - inline double uclock_sec(void) { - static double ttclk = 0.; - if (ttclk == 0.) ttclk = sysconf(_SC_CLK_TCK); - tms t; times(&t); return double(t.tms_utime) / ttclk; - } -# else - inline double uclock_sec(void) - { return double(clock())/double(CLOCKS_PER_SEC); } -# endif - - /* ******************************************************************** */ - /* Fixed size integer types. */ - /* ******************************************************************** */ - // Remark : the test program dynamic_array tests the length of - // resulting integers - - template struct fixed_size_integer_generator { - typedef void int_base_type; - typedef void uint_base_type; - }; - - template <> struct fixed_size_integer_generator { - typedef signed char int_base_type; - typedef unsigned char uint_base_type; - }; - - template <> struct fixed_size_integer_generator { - typedef signed short int int_base_type; - typedef unsigned short int uint_base_type; -}; - -template <> struct fixed_size_integer_generator { - typedef signed int int_base_type; - typedef unsigned int uint_base_type; - }; - -template <> struct fixed_size_integer_generator { - typedef signed long int_base_type; - typedef unsigned long uint_base_type; - }; - -template <> struct fixed_size_integer_generator { - typedef signed long long int_base_type; - typedef unsigned long long uint_base_type; - }; - -typedef fixed_size_integer_generator<1>::int_base_type int8_type; -typedef fixed_size_integer_generator<1>::uint_base_type uint8_type; -typedef fixed_size_integer_generator<2>::int_base_type int16_type; -typedef fixed_size_integer_generator<2>::uint_base_type uint16_type; -typedef fixed_size_integer_generator<4>::int_base_type int32_type; -typedef fixed_size_integer_generator<4>::uint_base_type uint32_type; -typedef fixed_size_integer_generator<8>::int_base_type int64_type; -typedef fixed_size_integer_generator<8>::uint_base_type uint64_type; - -// #if INT_MAX == 32767 -// typedef signed int int16_type; -// typedef unsigned int uint16_type; -// #elif SHRT_MAX == 32767 -// typedef signed short int int16_type; -// typedef unsigned short int uint16_type; -// #else -// # error "impossible to build a 16 bits integer" -// #endif - -// #if INT_MAX == 2147483647 -// typedef signed int int32_type; -// typedef unsigned int uint32_type; -// #elif SHRT_MAX == 2147483647 -// typedef signed short int int32_type; -// typedef unsigned short int uint32_type; -// #elif LONG_MAX == 2147483647 -// typedef signed long int int32_type; -// typedef unsigned long int uint32_type; -// #else -// # error "impossible to build a 32 bits integer" -// #endif - -// #if INT_MAX == 9223372036854775807L || INT_MAX == 9223372036854775807 -// typedef signed int int64_type; -// typedef unsigned int uint64_type; -// #elif LONG_MAX == 9223372036854775807L || LONG_MAX == 9223372036854775807 -// typedef signed long int int64_type; -// typedef unsigned long int uint64_type; -// #elif LLONG_MAX == 9223372036854775807LL || LLONG_MAX == 9223372036854775807L || LLONG_MAX == 9223372036854775807 -// typedef signed long long int int64_type; -// typedef unsigned long long int uint64_type; -// #else -// # error "impossible to build a 64 bits integer" -// #endif - -#if defined(__GNUC__) && !defined(__ICC) -/* - g++ can issue a warning at each usage of a function declared with this special attribute - (also works with typedefs and variable declarations) -*/ -# define IS_DEPRECATED __attribute__ ((__deprecated__)) -/* - the specified function is inlined at any optimization level -*/ -# define ALWAYS_INLINE __attribute__((always_inline)) -#else -# define IS_DEPRECATED -# define ALWAYS_INLINE -#endif - -} - - /* ******************************************************************** */ - /* Import/export classes and interfaces from a shared library */ - /* ******************************************************************** */ - -#if defined(EXPORTED_TO_SHARED_LIB) -# if defined(_MSC_VER) || defined(__INTEL_COMPILER) -# define APIDECL __declspec(dllexport) -# elif defined(__GNUC__) -# define __attribute__((visibility("default"))) -# else -# define APIDECL -# endif -# if defined(IMPORTED_FROM_SHARED_LIB) -# error INTENTIONAL COMPILCATION ERROR, DLL IMPORT AND EXPORT ARE INCOMPITABLE -# endif -#endif - -#if defined(IMPORTED_FROM_SHARED_LIB) -# if defined(_MSC_VER) || defined(__INTEL_COMPILER) -# define APIDECL __declspec(dllimport) -# else -# define APIDECL -# endif -# if defined(EXPORTED_TO_SHARED_LIB) -# error INTENTIONAL COMPILCATION ERROR, DLL IMPORT AND EXPORT ARE INCOMPITABLE -# endif -#endif - -#ifndef EXPORTED_TO_SHARED_LIB -# ifndef IMPORTED_FROM_SHARED_LIB -# define APIDECL //empty, used during static linking -# endif -#endif - -#endif /* GMM_STD_H__ */ diff --git a/gmm/gmm_sub_index.h b/gmm/gmm_sub_index.h deleted file mode 100644 index f1f0097ce..000000000 --- a/gmm/gmm_sub_index.h +++ /dev/null @@ -1,224 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_sub_index.h - @author Yves Renard - @date October 13, 2002. - @brief sub-indices. -*/ - -#ifndef GMM_SUB_INDEX_H__ -#define GMM_SUB_INDEX_H__ - -#include "gmm_def.h" - -namespace gmm { - - /* ******************************************************************** */ - /* sub indices */ - /* ******************************************************************** */ - - struct basic_index : public std::vector { - - mutable size_type nb_ref; - // size_type key1; faire la somme des composantes - // const basic_index *rind; rindex s'il existe - - - size_t operator[](size_type i) const { - return (i < size()) ? std::vector::operator[](i) : size_type(-1); - } - - basic_index() : nb_ref(1) {} - basic_index(size_type j) : std::vector(j), nb_ref(1) {} - template basic_index(IT b, IT e) - : std::vector(e-b), nb_ref(1) { std::copy(b, e, begin()); } - basic_index(const basic_index *pbi) : nb_ref(1) { - const_iterator it = pbi->begin(), ite = pbi->end(); - size_type i = 0; - for ( ; it != ite; ++it) i = std::max(i, *it); - resize(i+1); std::fill(begin(), end(), size_type(-1)); - for (it = pbi->begin(), i = 0; it != ite; ++it, ++i) - std::vector::operator[](*it) = i; - } - void swap(size_type i, size_type j) { - std::swap(std::vector::operator[](i), - std::vector::operator[](j)); - } - - }; - - typedef basic_index *pbasic_index; - - struct index_generator { - - template static pbasic_index create_index(IT begin, IT end) - { return new basic_index(begin, end); } - static pbasic_index create_rindex(pbasic_index pbi) - { return new basic_index(pbi); } - static void attach(pbasic_index pbi) { if (pbi) pbi->nb_ref++; } - static void unattach(pbasic_index pbi) - { if (pbi && --(pbi->nb_ref) == 0) delete pbi; } - - }; - - struct sub_index { - - size_type first_, last_; - typedef basic_index base_type; - typedef base_type::const_iterator const_iterator; - - mutable pbasic_index ind; - mutable pbasic_index rind; - - void comp_extr(void) { - std::vector::const_iterator it = ind->begin(), ite = ind->end(); - if (it != ite) { first_=last_= *it; ++it; } else { first_=last_= 0; } - for (; it != ite; ++it) - { first_ = std::min(first_, *it); last_ = std::max(last_, *it); } - } - - inline void test_rind(void) const - { if (!rind) rind = index_generator::create_rindex(ind); } - size_type size(void) const { return ind->size(); } - size_type first(void) const { return first_; } - size_type last(void) const { return last_; } - size_type index(size_type i) const { return (*ind)[i]; } - size_type rindex(size_type i) const { - test_rind(); - if (i < rind->size()) return (*rind)[i]; else return size_type(-1); - } - - const_iterator begin(void) const { return ind->begin(); } - const_iterator end(void) const { return ind->end(); } - const_iterator rbegin(void) const { test_rind(); return rind->begin(); } - const_iterator rend(void) const { test_rind(); return rind->end(); } - - sub_index() : ind(0), rind(0) {} - template sub_index(IT it, IT ite) - : ind(index_generator::create_index(it, ite)), - rind(0) { comp_extr(); } - template sub_index(const CONT &c) - : ind(index_generator::create_index(c.begin(), c.end())), - rind(0) { comp_extr(); } - ~sub_index() { - index_generator::unattach(rind); - index_generator::unattach(ind); - } - sub_index(const sub_index &si) : first_(si.first_), last_(si.last_), - ind(si.ind), rind(si.rind) - { index_generator::attach(rind); index_generator::attach(ind); } - sub_index &operator =(const sub_index &si) { - index_generator::unattach(rind); - index_generator::unattach(ind); - ind = si.ind; rind = si.rind; - index_generator::attach(rind); - index_generator::attach(ind); - first_ = si.first_; last_ = si.last_; - return *this; - } - }; - - struct unsorted_sub_index : public sub_index { - typedef basic_index base_type; - typedef base_type::const_iterator const_iterator; - - template unsorted_sub_index(IT it, IT ite) - : sub_index(it, ite) {} - template unsorted_sub_index(const CONT &c) - : sub_index(c) {} - unsorted_sub_index() {} - unsorted_sub_index(const unsorted_sub_index &si) : sub_index((const sub_index &)(si)) { } - unsorted_sub_index &operator =(const unsorted_sub_index &si) - { sub_index::operator =(si); return *this; } - void swap(size_type i, size_type j) { - GMM_ASSERT2(ind->nb_ref <= 1, "Operation not allowed on this index"); - if (rind) rind->swap((*ind)[i], (*ind)[j]); - ind->swap(i, j); - } - }; - - inline std::ostream &operator << (std::ostream &o, const sub_index &si) { - o << "sub_index("; - if (si.size() != 0) o << si.index(0); - for (size_type i = 1; i < si.size(); ++i) o << ", " << si.index(i); - o << ")"; - return o; - } - - struct sub_interval { - size_type min, max; - - size_type size(void) const { return max - min; } - size_type first(void) const { return min; } - size_type last(void) const { return max; } - size_type index(size_type i) const { return min + i; } - size_type step(void) const { return 1; } - size_type rindex(size_type i) const - { if (i >= min && i < max) return i - min; return size_type(-1); } - sub_interval(size_type mi, size_type l) : min(mi), max(mi+l) {} - sub_interval() {} - }; - - inline std::ostream &operator << (std::ostream &o, const sub_interval &si) - { o << "sub_interval(" << si.min << ", " << si.size() << ")"; return o; } - - struct sub_slice { - size_type min, max, N; - - size_type size(void) const { return (max - min) / N; } - size_type first(void) const { return min; } - size_type last(void) const { return (min == max) ? max : max+1-N; } - size_type step(void) const { return N; } - size_type index(size_type i) const { return min + N * i; } - size_type rindex(size_type i) const { - if (i >= min && i < max) - { size_type j = (i - min); if (j % N == 0) return j / N; } - return size_type(-1); - } - sub_slice(size_type mi, size_type l, size_type n) - : min(mi), max(mi+l*n), N(n) {} - sub_slice(void) {} - }; - - inline std::ostream &operator << (std::ostream &o, const sub_slice &si) { - o << "sub_slice(" << si.min << ", " << si.size() << ", " << si.step() - << ")"; return o; - } - - template struct index_is_sorted - { typedef linalg_true bool_type; }; - template<> struct index_is_sorted - { typedef linalg_false bool_type; }; - -} - -#endif // GMM_SUB_INDEX_H__ diff --git a/gmm/gmm_sub_matrix.h b/gmm/gmm_sub_matrix.h deleted file mode 100644 index e79883c31..000000000 --- a/gmm/gmm_sub_matrix.h +++ /dev/null @@ -1,406 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_sub_matrix.h - @author Yves Renard - @date October 13, 2002. - @brief Generic sub-matrices. -*/ - -#ifndef GMM_SUB_MATRIX_H__ -#define GMM_SUB_MATRIX_H__ - -#include "gmm_sub_vector.h" - -namespace gmm { - - /* ********************************************************************* */ - /* sub row matrices type */ - /* ********************************************************************* */ - - template - struct gen_sub_row_matrix { - typedef gen_sub_row_matrix this_type; - typedef typename std::iterator_traits::value_type M; - typedef M * CPT; - typedef typename std::iterator_traits::reference ref_M; - typedef typename select_ref - ::const_row_iterator, typename linalg_traits::row_iterator, - PT>::ref_type iterator; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::porigin_type porigin_type; - - SUBI1 si1; - SUBI2 si2; - iterator begin_; - porigin_type origin; - - reference operator()(size_type i, size_type j) const - { return linalg_traits::access(begin_ + si1.index(i), si2.index(j)); } - - size_type nrows(void) const { return si1.size(); } - size_type ncols(void) const { return si2.size(); } - - gen_sub_row_matrix(ref_M m, const SUBI1 &s1, const SUBI2 &s2) - : si1(s1), si2(s2), begin_(mat_row_begin(m)), - origin(linalg_origin(m)) {} - gen_sub_row_matrix() {} - gen_sub_row_matrix(const gen_sub_row_matrix &cr) : - si1(cr.si1), si2(cr.si2), begin_(cr.begin_),origin(cr.origin) {} - }; - - template - struct gen_sub_row_matrix_iterator { - typedef gen_sub_row_matrix this_type; - typedef typename modifiable_pointer::pointer MPT; - typedef typename std::iterator_traits::value_type M; - typedef typename select_ref - ::const_row_iterator, typename linalg_traits::row_iterator, - PT>::ref_type ITER; - typedef ITER value_type; - typedef ITER *pointer; - typedef ITER &reference; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - typedef std::random_access_iterator_tag iterator_category; - typedef gen_sub_row_matrix_iterator iterator; - - ITER it; - SUBI1 si1; - SUBI2 si2; - size_type ii; - - iterator operator ++(int) { iterator tmp = *this; ii++; return tmp; } - iterator operator --(int) { iterator tmp = *this; ii--; return tmp; } - iterator &operator ++() { ii++; return *this; } - iterator &operator --() { ii--; return *this; } - iterator &operator +=(difference_type i) { ii += i; return *this; } - iterator &operator -=(difference_type i) { ii -= i; return *this; } - iterator operator +(difference_type i) const - { iterator itt = *this; return (itt += i); } - iterator operator -(difference_type i) const - { iterator itt = *this; return (itt -= i); } - difference_type operator -(const iterator &i) const { return ii - i.ii; } - - ITER operator *() const { return it + si1.index(ii); } - ITER operator [](int i) { return it + si1.index(ii+i); } - - bool operator ==(const iterator &i) const { return (ii == i.ii); } - bool operator !=(const iterator &i) const { return !(i == *this); } - bool operator < (const iterator &i) const { return (ii < i.ii); } - - gen_sub_row_matrix_iterator(void) {} - gen_sub_row_matrix_iterator(const - gen_sub_row_matrix_iterator &itm) - : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {} - gen_sub_row_matrix_iterator(const ITER &iter, const SUBI1 &s1, - const SUBI2 &s2, size_type i) - : it(iter), si1(s1), si2(s2), ii(i) { } - - }; - - template - struct linalg_traits > { - typedef gen_sub_row_matrix this_type; - typedef typename std::iterator_traits::value_type M; - typedef typename which_reference::is_reference is_reference; - typedef abstract_matrix linalg_type; - typedef typename linalg_traits::origin_type origin_type; - typedef typename select_ref::ref_type porigin_type; - typedef typename linalg_traits::value_type value_type; - typedef typename select_ref::reference, PT>::ref_type reference; - typedef abstract_null_type sub_col_type; - typedef abstract_null_type col_iterator; - typedef abstract_null_type const_sub_col_type; - typedef abstract_null_type const_col_iterator; - typedef typename sub_vector_type::const_sub_row_type>::t *, SUBI2>::vector_type - const_sub_row_type; - typedef typename select_ref::sub_row_type>::t *, - SUBI2>::vector_type, PT>::ref_type sub_row_type; - typedef gen_sub_row_matrix_iterator::pointer, - SUBI1, SUBI2> const_row_iterator; - typedef typename select_ref, PT>::ref_type - row_iterator; - typedef typename linalg_traits::storage_type - storage_type; - typedef row_major sub_orientation; - typedef linalg_true index_sorted; - static size_type nrows(const this_type &m) { return m.nrows(); } - static size_type ncols(const this_type &m) { return m.ncols(); } - static const_sub_row_type row(const const_row_iterator &it) - { return const_sub_row_type(linalg_traits::row(*it), it.si2); } - static sub_row_type row(const row_iterator &it) - { return sub_row_type(linalg_traits::row(*it), it.si2); } - static const_row_iterator row_begin(const this_type &m) - { return const_row_iterator(m.begin_, m.si1, m.si2, 0); } - static row_iterator row_begin(this_type &m) - { return row_iterator(m.begin_, m.si1, m.si2, 0); } - static const_row_iterator row_end(const this_type &m) - { return const_row_iterator(m.begin_, m.si1, m.si2, m.nrows()); } - static row_iterator row_end(this_type &m) - { return row_iterator(m.begin_, m.si1, m.si2, m.nrows()); } - static origin_type* origin(this_type &v) { return v.origin; } - static const origin_type* origin(const this_type &v) { return v.origin; } - static void do_clear(this_type &m) { - row_iterator it = mat_row_begin(m), ite = mat_row_end(m); - for (; it != ite; ++it) clear(row(it)); - } - static value_type access(const const_row_iterator &itrow, size_type i) - { return linalg_traits::access(*itrow, itrow.si2.index(i)); } - static reference access(const row_iterator &itrow, size_type i) - { return linalg_traits::access(*itrow, itrow.si2.index(i)); } - }; - - template - std::ostream &operator <<(std::ostream &o, - const gen_sub_row_matrix& m) - { gmm::write(o,m); return o; } - - - /* ********************************************************************* */ - /* sub column matrices type */ - /* ********************************************************************* */ - - template - struct gen_sub_col_matrix { - typedef gen_sub_col_matrix this_type; - typedef typename std::iterator_traits::value_type M; - typedef M * CPT; - typedef typename std::iterator_traits::reference ref_M; - typedef typename select_ref - ::const_col_iterator, typename linalg_traits::col_iterator, - PT>::ref_type iterator; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::porigin_type porigin_type; - - SUBI1 si1; - SUBI2 si2; - iterator begin_; - porigin_type origin; - - reference operator()(size_type i, size_type j) const - { return linalg_traits::access(begin_ + si2.index(j), si1.index(i)); } - - size_type nrows(void) const { return si1.size(); } - size_type ncols(void) const { return si2.size(); } - - gen_sub_col_matrix(ref_M m, const SUBI1 &s1, const SUBI2 &s2) - : si1(s1), si2(s2), begin_(mat_col_begin(m)), - origin(linalg_origin(m)) {} - gen_sub_col_matrix() {} - gen_sub_col_matrix(const gen_sub_col_matrix &cr) : - si1(cr.si1), si2(cr.si2), begin_(cr.begin_),origin(cr.origin) {} - }; - - template - struct gen_sub_col_matrix_iterator { - typedef gen_sub_col_matrix this_type; - typedef typename modifiable_pointer::pointer MPT; - typedef typename std::iterator_traits::value_type M; - typedef typename select_ref::const_col_iterator, - typename linalg_traits::col_iterator, - PT>::ref_type ITER; - typedef ITER value_type; - typedef ITER *pointer; - typedef ITER &reference; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - typedef std::random_access_iterator_tag iterator_category; - typedef gen_sub_col_matrix_iterator iterator; - - ITER it; - SUBI1 si1; - SUBI2 si2; - size_type ii; - - iterator operator ++(int) { iterator tmp = *this; ii++; return tmp; } - iterator operator --(int) { iterator tmp = *this; ii--; return tmp; } - iterator &operator ++() { ii++; return *this; } - iterator &operator --() { ii--; return *this; } - iterator &operator +=(difference_type i) { ii += i; return *this; } - iterator &operator -=(difference_type i) { ii -= i; return *this; } - iterator operator +(difference_type i) const - { iterator itt = *this; return (itt += i); } - iterator operator -(difference_type i) const - { iterator itt = *this; return (itt -= i); } - difference_type operator -(const iterator &i) const { return ii - i.ii; } - - ITER operator *() const { return it + si2.index(ii); } - ITER operator [](int i) { return it + si2.index(ii+i); } - - bool operator ==(const iterator &i) const { return (ii == i.ii); } - bool operator !=(const iterator &i) const { return !(i == *this); } - bool operator < (const iterator &i) const { return (ii < i.ii); } - - gen_sub_col_matrix_iterator(void) {} - gen_sub_col_matrix_iterator(const - gen_sub_col_matrix_iterator &itm) - : it(itm.it), si1(itm.si1), si2(itm.si2), ii(itm.ii) {} - gen_sub_col_matrix_iterator(const ITER &iter, const SUBI1 &s1, - const SUBI2 &s2, size_type i) - : it(iter), si1(s1), si2(s2), ii(i) { } - }; - - template - struct linalg_traits > { - typedef gen_sub_col_matrix this_type; - typedef typename std::iterator_traits::value_type M; - typedef typename linalg_traits::origin_type origin_type; - typedef typename select_ref::ref_type porigin_type; - typedef typename which_reference::is_reference is_reference; - typedef abstract_matrix linalg_type; - typedef typename linalg_traits::value_type value_type; - typedef typename select_ref::reference, PT>::ref_type reference; - typedef abstract_null_type sub_row_type; - typedef abstract_null_type row_iterator; - typedef abstract_null_type const_sub_row_type; - typedef abstract_null_type const_row_iterator; - typedef typename sub_vector_type::const_sub_col_type>::t *, SUBI1>::vector_type const_sub_col_type; - typedef typename select_ref::sub_col_type>::t *, SUBI1>::vector_type, PT>::ref_type sub_col_type; - typedef gen_sub_col_matrix_iterator::pointer, - SUBI1, SUBI2> const_col_iterator; - typedef typename select_ref, PT>::ref_type - col_iterator; - typedef col_major sub_orientation; - typedef linalg_true index_sorted; - typedef typename linalg_traits::storage_type - storage_type; - static size_type nrows(const this_type &m) { return m.nrows(); } - static size_type ncols(const this_type &m) { return m.ncols(); } - static const_sub_col_type col(const const_col_iterator &it) - { return const_sub_col_type(linalg_traits::col(*it), it.si1); } - static sub_col_type col(const col_iterator &it) - { return sub_col_type(linalg_traits::col(*it), it.si1); } - static const_col_iterator col_begin(const this_type &m) - { return const_col_iterator(m.begin_, m.si1, m.si2, 0); } - static col_iterator col_begin(this_type &m) - { return col_iterator(m.begin_, m.si1, m.si2, 0); } - static const_col_iterator col_end(const this_type &m) - { return const_col_iterator(m.begin_, m.si1, m.si2, m.ncols()); } - static col_iterator col_end(this_type &m) - { return col_iterator(m.begin_, m.si1, m.si2, m.ncols()); } - static origin_type* origin(this_type &v) { return v.origin; } - static const origin_type* origin(const this_type &v) { return v.origin; } - static void do_clear(this_type &m) { - col_iterator it = mat_col_begin(m), ite = mat_col_end(m); - for (; it != ite; ++it) clear(col(it)); - } - static value_type access(const const_col_iterator &itcol, size_type i) - { return linalg_traits::access(*itcol, itcol.si1.index(i)); } - static reference access(const col_iterator &itcol, size_type i) - { return linalg_traits::access(*itcol, itcol.si1.index(i)); } - }; - - template std::ostream &operator << - (std::ostream &o, const gen_sub_col_matrix& m) - { gmm::write(o,m); return o; } - - /* ******************************************************************** */ - /* sub matrices */ - /* ******************************************************************** */ - - template - struct sub_matrix_type_ { - typedef abstract_null_type return_type; - }; - template - struct sub_matrix_type_ - { typedef gen_sub_col_matrix matrix_type; }; - template - struct sub_matrix_type_ - { typedef gen_sub_row_matrix matrix_type; }; - template - struct sub_matrix_type { - typedef typename std::iterator_traits::value_type M; - typedef typename sub_matrix_type_::sub_orientation>::potype>::matrix_type matrix_type; - }; - - template inline - typename select_return - ::matrix_type, typename sub_matrix_type::matrix_type, - M *>::return_type - sub_matrix(M &m, const SUBI1 &si1, const SUBI2 &si2) { - GMM_ASSERT2(si1.last() <= mat_nrows(m) && si2.last() <= mat_ncols(m), - "sub matrix too large"); - return typename select_return::matrix_type, typename sub_matrix_type - ::matrix_type, M *>::return_type(linalg_cast(m), si1, si2); - } - - template inline - typename select_return - ::matrix_type, typename sub_matrix_type::matrix_type, - const M *>::return_type - sub_matrix(const M &m, const SUBI1 &si1, const SUBI2 &si2) { - GMM_ASSERT2(si1.last() <= mat_nrows(m) && si2.last() <= mat_ncols(m), - "sub matrix too large"); - return typename select_return::matrix_type, typename sub_matrix_type - ::matrix_type, const M *>::return_type(linalg_cast(m), si1, si2); - } - - template inline - typename select_return - ::matrix_type, typename sub_matrix_type::matrix_type, - M *>::return_type - sub_matrix(M &m, const SUBI1 &si1) { - GMM_ASSERT2(si1.last() <= mat_nrows(m) && si1.last() <= mat_ncols(m), - "sub matrix too large"); - return typename select_return::matrix_type, typename sub_matrix_type - ::matrix_type, M *>::return_type(linalg_cast(m), si1, si1); - } - - template inline - typename select_return - ::matrix_type, typename sub_matrix_type::matrix_type, - const M *>::return_type - sub_matrix(const M &m, const SUBI1 &si1) { - GMM_ASSERT2(si1.last() <= mat_nrows(m) && si1.last() <= mat_ncols(m), - "sub matrix too large"); - return typename select_return::matrix_type, typename sub_matrix_type - ::matrix_type, const M *>::return_type(linalg_cast(m), si1, si1); - } - -} - -#endif // GMM_SUB_MATRIX_H__ diff --git a/gmm/gmm_sub_vector.h b/gmm/gmm_sub_vector.h deleted file mode 100644 index d35f908d5..000000000 --- a/gmm/gmm_sub_vector.h +++ /dev/null @@ -1,560 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_sub_vector.h - @author Yves Renard - @date October 13, 2002. - @brief Generic sub-vectors. -*/ - -#ifndef GMM_SUB_VECTOR_H__ -#define GMM_SUB_VECTOR_H__ - -#include "gmm_interface.h" -#include "gmm_sub_index.h" - -namespace gmm { - - /* ********************************************************************* */ - /* sparse sub-vectors */ - /* ********************************************************************* */ - - template - struct sparse_sub_vector_iterator { - - IT itb, itbe; - SUBI si; - - typedef std::iterator_traits traits_type; - typedef typename traits_type::value_type value_type; - typedef typename traits_type::pointer pointer; - typedef typename traits_type::reference reference; - typedef typename traits_type::difference_type difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - typedef size_t size_type; - typedef sparse_sub_vector_iterator iterator; - - size_type index(void) const { return si.rindex(itb.index()); } - void forward(void); - void backward(void); - iterator &operator ++() - { ++itb; forward(); return *this; } - iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; } - iterator &operator --() - { --itb; backward(); return *this; } - iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; } - reference operator *() const { return *itb; } - - bool operator ==(const iterator &i) const { return itb == i.itb; } - bool operator !=(const iterator &i) const { return !(i == *this); } - - sparse_sub_vector_iterator(void) {} - sparse_sub_vector_iterator(const IT &it, const IT &ite, const SUBI &s) - : itb(it), itbe(ite), si(s) { forward(); } - sparse_sub_vector_iterator(const sparse_sub_vector_iterator &it) : itb(it.itb), itbe(it.itbe), si(it.si) {} - }; - - template - void sparse_sub_vector_iterator::forward(void) - { while(itb!=itbe && index()==size_type(-1)) { ++itb; } } - - template - void sparse_sub_vector_iterator::backward(void) - { while(itb!=itbe && index()==size_type(-1)) --itb; } - - template struct sparse_sub_vector { - typedef sparse_sub_vector this_type; - typedef typename std::iterator_traits::value_type V; - typedef V * CPT; - typedef typename select_ref::const_iterator, - typename linalg_traits::iterator, PT>::ref_type iterator; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::porigin_type porigin_type; - - iterator begin_, end_; - porigin_type origin; - SUBI si; - - size_type size(void) const { return si.size(); } - - reference operator[](size_type i) const - { return linalg_traits::access(origin, begin_, end_, si.index(i)); } - - sparse_sub_vector(V &v, const SUBI &s) : begin_(vect_begin(v)), - end_(vect_end(v)), origin(linalg_origin(v)), si(s) {} - sparse_sub_vector(const V &v, const SUBI &s) - : begin_(vect_begin(const_cast(v))), - end_(vect_end(const_cast(v))), - origin(linalg_origin(const_cast(v))), si(s) {} - sparse_sub_vector() {} - sparse_sub_vector(const sparse_sub_vector &cr) - : begin_(cr.begin_),end_(cr.end_),origin(cr.origin), si(cr.si) {} - }; - - template inline - void set_to_begin(sparse_sub_vector_iterator &it, - ORG o, sparse_sub_vector *, - linalg_modifiable) { - typedef sparse_sub_vector VECT; - typedef typename linalg_traits::V_reference ref_t; - set_to_begin(it.itb, o, typename linalg_traits::pV(), ref_t()); - set_to_end(it.itbe, o, typename linalg_traits::pV(), ref_t()); - it.forward(); - } - template inline - void set_to_begin(sparse_sub_vector_iterator &it, - ORG o, const sparse_sub_vector *, - linalg_modifiable) { - typedef sparse_sub_vector VECT; - typedef typename linalg_traits::V_reference ref_t; - set_to_begin(it.itb, o, typename linalg_traits::pV(), ref_t()); - set_to_end(it.itbe, o, typename linalg_traits::pV(), ref_t()); - it.forward(); - } - - template inline - void set_to_end(sparse_sub_vector_iterator &it, - ORG o, sparse_sub_vector *, linalg_modifiable) { - typedef sparse_sub_vector VECT; - typedef typename linalg_traits::V_reference ref_t; - set_to_end(it.itb, o, typename linalg_traits::pV(), ref_t()); - set_to_end(it.itbe, o, typename linalg_traits::pV(), ref_t()); - it.forward(); - } - template inline - void set_to_end(sparse_sub_vector_iterator &it, - ORG o, const sparse_sub_vector *, - linalg_modifiable) { - typedef sparse_sub_vector VECT; - typedef typename linalg_traits::V_reference ref_t; - set_to_end(it.itb, o, typename linalg_traits::pV(), ref_t()); - set_to_end(it.itbe, o, typename linalg_traits::pV(), ref_t()); - it.forward(); - } - - template - struct linalg_traits > { - typedef sparse_sub_vector this_type; - typedef this_type * pthis_type; - typedef PT pV; - typedef typename std::iterator_traits::value_type V; - typedef typename linalg_and::bool_type, - typename linalg_traits::index_sorted>::bool_type index_sorted; - typedef typename linalg_traits::is_reference V_reference; - typedef typename linalg_traits::origin_type origin_type; - typedef typename select_ref::ref_type porigin_type; - typedef typename which_reference::is_reference is_reference; - typedef abstract_vector linalg_type; - typedef typename linalg_traits::value_type value_type; - typedef typename select_ref::reference, PT>::ref_type reference; - typedef typename select_ref::const_iterator, - typename linalg_traits::iterator, PT>::ref_type pre_iterator; - typedef typename select_ref, - PT>::ref_type iterator; - typedef sparse_sub_vector_iterator - ::const_iterator, pre_iterator, SUBI> const_iterator; - typedef abstract_sparse storage_type; - static size_type size(const this_type &v) { return v.size(); } - static iterator begin(this_type &v) { - iterator it; - it.itb = v.begin_; it.itbe = v.end_; it.si = v.si; - if (!is_const_reference(is_reference())) - set_to_begin(it, v.origin, pthis_type(), is_reference()); - else it.forward(); - return it; - } - static const_iterator begin(const this_type &v) { - const_iterator it; it.itb = v.begin_; it.itbe = v.end_; it.si = v.si; - if (!is_const_reference(is_reference())) - { set_to_begin(it, v.origin, pthis_type(), is_reference()); } - else it.forward(); - return it; - } - static iterator end(this_type &v) { - iterator it; - it.itb = v.end_; it.itbe = v.end_; it.si = v.si; - if (!is_const_reference(is_reference())) - set_to_end(it, v.origin, pthis_type(), is_reference()); - else it.forward(); - return it; - } - static const_iterator end(const this_type &v) { - const_iterator it; it.itb = v.end_; it.itbe = v.end_; it.si = v.si; - if (!is_const_reference(is_reference())) - set_to_end(it, v.origin, pthis_type(), is_reference()); - else it.forward(); - return it; - } - static origin_type* origin(this_type &v) { return v.origin; } - static const origin_type* origin(const this_type &v) { return v.origin; } - static void clear(origin_type* o, const iterator &begin_, - const iterator &end_) { - std::deque ind; - iterator it = begin_; - for (; it != end_; ++it) ind.push_front(it.index()); - for (; !(ind.empty()); ind.pop_back()) - access(o, begin_, end_, ind.back()) = value_type(0); - } - static void do_clear(this_type &v) { clear(v.origin, begin(v), end(v)); } - static value_type access(const origin_type *o, const const_iterator &it, - const const_iterator &ite, size_type i) - { return linalg_traits::access(o, it.itb, ite.itb, it.si.index(i)); } - static reference access(origin_type *o, const iterator &it, - const iterator &ite, size_type i) - { return linalg_traits::access(o, it.itb, ite.itb, it.si.index(i)); } - }; - - template std::ostream &operator << - (std::ostream &o, const sparse_sub_vector& m) - { gmm::write(o,m); return o; } - - /* ********************************************************************* */ - /* skyline sub-vectors */ - /* ********************************************************************* */ - - template - struct skyline_sub_vector_iterator { - - IT itb; - SUBI si; - - typedef std::iterator_traits traits_type; - typedef typename traits_type::value_type value_type; - typedef typename traits_type::pointer pointer; - typedef typename traits_type::reference reference; - typedef typename traits_type::difference_type difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - typedef size_t size_type; - typedef skyline_sub_vector_iterator iterator; - - size_type index(void) const - { return (itb.index() - si.min + si.step() - 1) / si.step(); } - void backward(void); - iterator &operator ++() - { itb += si.step(); return *this; } - iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; } - iterator &operator --() - { itb -= si.step(); return *this; } - iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; } - - iterator &operator +=(difference_type i) - { itb += si.step() * i; return *this; } - iterator &operator -=(difference_type i) - { itb -= si.step() * i; return *this; } - iterator operator +(difference_type i) const - { iterator ii = *this; return (ii += i); } - iterator operator -(difference_type i) const - { iterator ii = *this; return (ii -= i); } - difference_type operator -(const iterator &i) const - { return (itb - i.itb) / si.step(); } - - reference operator *() const { return *itb; } - reference operator [](int ii) { return *(itb + ii * si.step()); } - - bool operator ==(const iterator &i) const { return index() == i.index();} - bool operator !=(const iterator &i) const { return !(i == *this); } - bool operator < (const iterator &i) const { return index() < i.index();} - - skyline_sub_vector_iterator(void) {} - skyline_sub_vector_iterator(const IT &it, const SUBI &s) - : itb(it), si(s) {} - skyline_sub_vector_iterator(const skyline_sub_vector_iterator &it) : itb(it.itb), si(it.si) {} - }; - - template - void update_for_sub_skyline(IT &it, IT &ite, const SUBI &si) { - if (it.index() >= si.max || ite.index() <= si.min) { it = ite; return; } - ptrdiff_t dec1 = si.min - it.index(), dec2 = ite.index() - si.max; - it += (dec1 < 0) ? ((si.step()-((-dec1) % si.step())) % si.step()) : dec1; - ite -= (dec2 < 0) ? -((-dec2) % si.step()) : dec2; - } - - template struct skyline_sub_vector { - typedef skyline_sub_vector this_type; - typedef typename std::iterator_traits::value_type V; - typedef V * pV; - typedef typename select_ref::const_iterator, - typename linalg_traits::iterator, PT>::ref_type iterator; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::porigin_type porigin_type; - - iterator begin_, end_; - porigin_type origin; - SUBI si; - - size_type size(void) const { return si.size(); } - - reference operator[](size_type i) const - { return linalg_traits::access(origin, begin_, end_, si.index(i)); } - - skyline_sub_vector(V &v, const SUBI &s) : begin_(vect_begin(v)), - end_(vect_end(v)), origin(linalg_origin(v)), si(s) { - update_for_sub_skyline(begin_, end_, si); - } - skyline_sub_vector(const V &v, const SUBI &s) - : begin_(vect_begin(const_cast(v))), - end_(vect_end(const_cast(v))), - origin(linalg_origin(const_cast(v))), si(s) { - update_for_sub_skyline(begin_, end_, si); - } - skyline_sub_vector() {} - skyline_sub_vector(const skyline_sub_vector &cr) - : begin_(cr.begin_),end_(cr.end_),origin(cr.origin), si(cr.si) {} - }; - - template inline - void set_to_begin(skyline_sub_vector_iterator &it, - ORG o, skyline_sub_vector *, - linalg_modifiable) { - typedef skyline_sub_vector VECT; - typedef typename linalg_traits::V_reference ref_t; - IT itbe = it.itb; - set_to_begin(it.itb, o, typename linalg_traits::pV(), ref_t()); - set_to_end(itbe, o, typename linalg_traits::pV(), ref_t()); - update_for_sub_skyline(it.itb, itbe, it.si); - } - template inline - void set_to_begin(skyline_sub_vector_iterator &it, - ORG o, const skyline_sub_vector *, - linalg_modifiable) { - typedef skyline_sub_vector VECT; - typedef typename linalg_traits::V_reference ref_t; - IT itbe = it.itb; - set_to_begin(it.itb, o, typename linalg_traits::pV(), ref_t()); - set_to_end(itbe, o, typename linalg_traits::pV(), ref_t()); - update_for_sub_skyline(it.itb, itbe, it.si); - } - - template inline - void set_to_end(skyline_sub_vector_iterator &it, - ORG o, skyline_sub_vector *, - linalg_modifiable) { - typedef skyline_sub_vector VECT; - typedef typename linalg_traits::V_reference ref_t; - IT itb = it.itb; - set_to_begin(itb, o, typename linalg_traits::pV(), ref_t()); - set_to_end(it.itb, o, typename linalg_traits::pV(), ref_t()); - update_for_sub_skyline(itb, it.itb, it.si); - } - template inline - void set_to_end(skyline_sub_vector_iterator &it, - ORG o, const skyline_sub_vector *, - linalg_modifiable) { - typedef skyline_sub_vector VECT; - typedef typename linalg_traits::V_reference ref_t; - IT itb = it.itb; - set_to_begin(itb, o, typename linalg_traits::pV(), ref_t()); - set_to_end(it.itb, o, typename linalg_traits::pV(), ref_t()); - update_for_sub_skyline(itb, it.itb, it.si); - } - - - template - struct linalg_traits > { - typedef skyline_sub_vector this_type; - typedef this_type *pthis_type; - typedef typename std::iterator_traits::value_type V; - typedef typename linalg_traits::is_reference V_reference; - typedef typename linalg_traits::origin_type origin_type; - typedef typename select_ref::ref_type porigin_type; - typedef V * pV; - typedef typename which_reference::is_reference is_reference; - typedef abstract_vector linalg_type; - typedef typename linalg_traits::value_type value_type; - typedef typename select_ref::reference, PT>::ref_type reference; - typedef typename linalg_traits::const_iterator const_V_iterator; - typedef typename linalg_traits::iterator V_iterator; - typedef typename select_ref::ref_type pre_iterator; - typedef typename select_ref, - PT>::ref_type iterator; - typedef skyline_sub_vector_iterator - const_iterator; - typedef abstract_skyline storage_type; - typedef linalg_true index_sorted; - static size_type size(const this_type &v) { return v.size(); } - static iterator begin(this_type &v) { - iterator it; - it.itb = v.begin_; it.si = v.si; - if (!is_const_reference(is_reference())) - set_to_begin(it, v.origin, pthis_type(), is_reference()); - return it; - } - static const_iterator begin(const this_type &v) { - const_iterator it; it.itb = v.begin_; it.si = v.si; - if (!is_const_reference(is_reference())) - { set_to_begin(it, v.origin, pthis_type(), is_reference()); } - return it; - } - static iterator end(this_type &v) { - iterator it; - it.itb = v.end_; it.si = v.si; - if (!is_const_reference(is_reference())) - set_to_end(it, v.origin, pthis_type(), is_reference()); - return it; - } - static const_iterator end(const this_type &v) { - const_iterator it; it.itb = v.end_; it.si = v.si; - if (!is_const_reference(is_reference())) - set_to_end(it, v.origin, pthis_type(), is_reference()); - return it; - } - static origin_type* origin(this_type &v) { return v.origin; } - static const origin_type* origin(const this_type &v) { return v.origin; } - static void clear(origin_type*, const iterator &it, const iterator &ite) - { std::fill(it, ite, value_type(0)); } - static void do_clear(this_type &v) { clear(v.origin, begin(v), end(v)); } - static value_type access(const origin_type *o, const const_iterator &it, - const const_iterator &ite, size_type i) - { return linalg_traits::access(o, it.itb, ite.itb, it.si.index(i)); } - static reference access(origin_type *o, const iterator &it, - const iterator &ite, size_type i) - { return linalg_traits::access(o, it.itb, ite.itb, it.si.index(i)); } - }; - - template std::ostream &operator << - (std::ostream &o, const skyline_sub_vector& m) - { gmm::write(o,m); return o; } - - /* ******************************************************************** */ - /* sub vector. */ - /* ******************************************************************** */ - /* sub_vector_type::vector_type is the sub vector type */ - /* returned by sub_vector(v, sub_index) */ - /************************************************************************/ - - template struct svrt_ir { - typedef abstract_null_type vector_type; - }; - - template - struct svrt_ir { - typedef typename std::iterator_traits::value_type V; - typedef typename vect_ref_type::iterator iterator; - typedef tab_ref_index_ref_with_origin vector_type; - }; - - template - struct svrt_ir { - typedef typename std::iterator_traits::value_type V; - typedef typename vect_ref_type::iterator iterator; - typedef tab_ref_index_ref_with_origin vector_type; - }; - - template - struct svrt_ir { - typedef typename std::iterator_traits::value_type V; - typedef typename vect_ref_type::iterator iterator; - typedef tab_ref_with_origin vector_type; - }; - - template - struct svrt_ir { - typedef typename std::iterator_traits::value_type V; - typedef typename vect_ref_type::iterator iterator; - typedef tab_ref_reg_spaced_with_origin vector_type; - }; - - template - struct svrt_ir { - typedef skyline_sub_vector vector_type; - }; - - template - struct svrt_ir { - typedef sparse_sub_vector vector_type; - }; - - template - struct svrt_ir { - typedef sparse_sub_vector vector_type; - }; - - - template - struct svrt_ir { - typedef sparse_sub_vector vector_type; - }; - - template - struct sub_vector_type { - typedef typename std::iterator_traits::value_type V; - typedef typename svrt_ir::storage_type>::vector_type vector_type; - }; - - template - typename select_return< - typename sub_vector_type::vector_type, - typename sub_vector_type::vector_type, const V *>::return_type - sub_vector(const V &v, const SUBI &si) { - GMM_ASSERT2(si.last() <= vect_size(v), - "sub vector too large, " << si.last() << " > " << vect_size(v)); - return typename select_return< - typename sub_vector_type::vector_type, - typename sub_vector_type::vector_type, const V *>::return_type - (linalg_cast(v), si); - } - - template - typename select_return< - typename sub_vector_type::vector_type, - typename sub_vector_type::vector_type, V *>::return_type - sub_vector(V &v, const SUBI &si) { - GMM_ASSERT2(si.last() <= vect_size(v), - "sub vector too large, " << si.last() << " > " << vect_size(v)); - return typename select_return< - typename sub_vector_type::vector_type, - typename sub_vector_type::vector_type, V *>::return_type - (linalg_cast(v), si); - } - -} - -#endif // GMM_SUB_VECTOR_H__ diff --git a/gmm/gmm_superlu_interface.h b/gmm/gmm_superlu_interface.h deleted file mode 100644 index b732445e7..000000000 --- a/gmm/gmm_superlu_interface.h +++ /dev/null @@ -1,410 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_superlu_interface.h - @author Yves Renard - @date October 17, 2003. - @brief Interface with SuperLU (LU direct solver for sparse matrices). -*/ -#if defined(GMM_USES_SUPERLU) && !defined(GETFEM_VERSION) - -#ifndef GMM_SUPERLU_INTERFACE_H -#define GMM_SUPERLU_INTERFACE_H - -#include "gmm_kernel.h" - -typedef int int_t; - -/* because SRC/util.h defines TRUE and FALSE ... */ -#ifdef TRUE -# undef TRUE -#endif -#ifdef FALSE -# undef FALSE -#endif - -#include "superlu/slu_Cnames.h" -#include "superlu/supermatrix.h" -#include "superlu/slu_util.h" - -namespace SuperLU_S { -#include "superlu/slu_sdefs.h" -} -namespace SuperLU_D { -#include "superlu/slu_ddefs.h" -} -namespace SuperLU_C { -#include "superlu/slu_cdefs.h" -} -namespace SuperLU_Z { -#include "superlu/slu_zdefs.h" -} - - - -namespace gmm { - - /* interface for Create_CompCol_Matrix */ - - inline void Create_CompCol_Matrix(SuperMatrix *A, int m, int n, int nnz, - float *a, int *ir, int *jc) { - SuperLU_S::sCreate_CompCol_Matrix(A, m, n, nnz, a, ir, jc, - SLU_NC, SLU_S, SLU_GE); - } - - inline void Create_CompCol_Matrix(SuperMatrix *A, int m, int n, int nnz, - double *a, int *ir, int *jc) { - SuperLU_D::dCreate_CompCol_Matrix(A, m, n, nnz, a, ir, jc, - SLU_NC, SLU_D, SLU_GE); - } - - inline void Create_CompCol_Matrix(SuperMatrix *A, int m, int n, int nnz, - std::complex *a, int *ir, int *jc) { - SuperLU_C::cCreate_CompCol_Matrix(A, m, n, nnz, (SuperLU_C::complex *)(a), - ir, jc, SLU_NC, SLU_C, SLU_GE); - } - - inline void Create_CompCol_Matrix(SuperMatrix *A, int m, int n, int nnz, - std::complex *a, int *ir, int *jc) { - SuperLU_Z::zCreate_CompCol_Matrix(A, m, n, nnz, - (SuperLU_Z::doublecomplex *)(a), ir, jc, - SLU_NC, SLU_Z, SLU_GE); - } - - /* interface for Create_Dense_Matrix */ - - inline void Create_Dense_Matrix(SuperMatrix *A, int m, int n, float *a, int k) - { SuperLU_S::sCreate_Dense_Matrix(A, m, n, a, k, SLU_DN, SLU_S, SLU_GE); } - inline void Create_Dense_Matrix(SuperMatrix *A, int m, int n, double *a, int k) - { SuperLU_D::dCreate_Dense_Matrix(A, m, n, a, k, SLU_DN, SLU_D, SLU_GE); } - inline void Create_Dense_Matrix(SuperMatrix *A, int m, int n, - std::complex *a, int k) { - SuperLU_C::cCreate_Dense_Matrix(A, m, n, (SuperLU_C::complex *)(a), - k, SLU_DN, SLU_C, SLU_GE); - } - inline void Create_Dense_Matrix(SuperMatrix *A, int m, int n, - std::complex *a, int k) { - SuperLU_Z::zCreate_Dense_Matrix(A, m, n, (SuperLU_Z::doublecomplex *)(a), - k, SLU_DN, SLU_Z, SLU_GE); - } - - /* interface for gssv */ - -#define DECL_GSSV(NAMESPACE,FNAME,FLOATTYPE,KEYTYPE) \ - inline void SuperLU_gssv(superlu_options_t *options, SuperMatrix *A, int *p, \ - int *q, SuperMatrix *L, SuperMatrix *U, SuperMatrix *B, \ - SuperLUStat_t *stats, int *info, KEYTYPE) { \ - NAMESPACE::FNAME(options, A, p, q, L, U, B, stats, info); \ - } - - DECL_GSSV(SuperLU_S,sgssv,float,float) - DECL_GSSV(SuperLU_C,cgssv,float,std::complex) - DECL_GSSV(SuperLU_D,dgssv,double,double) - DECL_GSSV(SuperLU_Z,zgssv,double,std::complex) - - /* interface for gssvx */ - -#define DECL_GSSVX(NAMESPACE,FNAME,FLOATTYPE,KEYTYPE) \ - inline float SuperLU_gssvx(superlu_options_t *options, SuperMatrix *A, \ - int *perm_c, int *perm_r, int *etree, char *equed, \ - FLOATTYPE *R, FLOATTYPE *C, SuperMatrix *L, \ - SuperMatrix *U, void *work, int lwork, \ - SuperMatrix *B, SuperMatrix *X, \ - FLOATTYPE *recip_pivot_growth, \ - FLOATTYPE *rcond, FLOATTYPE *ferr, FLOATTYPE *berr, \ - SuperLUStat_t *stats, int *info, KEYTYPE) { \ - NAMESPACE::mem_usage_t mem_usage; \ - NAMESPACE::FNAME(options, A, perm_c, perm_r, etree, equed, R, C, L, \ - U, work, lwork, B, X, recip_pivot_growth, rcond, \ - ferr, berr, &mem_usage, stats, info); \ - return mem_usage.for_lu; /* bytes used by the factor storage */ \ - } - - DECL_GSSVX(SuperLU_S,sgssvx,float,float) - DECL_GSSVX(SuperLU_C,cgssvx,float,std::complex) - DECL_GSSVX(SuperLU_D,dgssvx,double,double) - DECL_GSSVX(SuperLU_Z,zgssvx,double,std::complex) - - /* ********************************************************************* */ - /* SuperLU solve interface */ - /* ********************************************************************* */ - - template - int SuperLU_solve(const MAT &A, const VECTX &X_, const VECTB &B, - double& rcond_, int permc_spec = 3) { - VECTX &X = const_cast(X_); - /* - * Get column permutation vector perm_c[], according to permc_spec: - * permc_spec = 0: use the natural ordering - * permc_spec = 1: use minimum degree ordering on structure of A'*A - * permc_spec = 2: use minimum degree ordering on structure of A'+A - * permc_spec = 3: use approximate minimum degree column ordering - */ - typedef typename linalg_traits::value_type T; - typedef typename number_traits::magnitude_type R; - - int m = mat_nrows(A), n = mat_ncols(A), nrhs = 1, info = 0; - - csc_matrix csc_A(m, n); gmm::copy(A, csc_A); - std::vector rhs(m), sol(m); - gmm::copy(B, rhs); - - int nz = nnz(csc_A); - if ((2 * nz / n) >= m) - GMM_WARNING2("CAUTION : it seems that SuperLU has a problem" - " for nearly dense sparse matrices"); - - superlu_options_t options; - set_default_options(&options); - options.ColPerm = NATURAL; - options.PrintStat = NO; - options.ConditionNumber = YES; - switch (permc_spec) { - case 1 : options.ColPerm = MMD_ATA; break; - case 2 : options.ColPerm = MMD_AT_PLUS_A; break; - case 3 : options.ColPerm = COLAMD; break; - } - SuperLUStat_t stat; - StatInit(&stat); - - SuperMatrix SA, SL, SU, SB, SX; // SuperLU format. - Create_CompCol_Matrix(&SA, m, n, nz, (double *)(&(csc_A.pr[0])), - (int *)(&(csc_A.ir[0])), (int *)(&(csc_A.jc[0]))); - Create_Dense_Matrix(&SB, m, nrhs, &rhs[0], m); - Create_Dense_Matrix(&SX, m, nrhs, &sol[0], m); - memset(&SL,0,sizeof SL); - memset(&SU,0,sizeof SU); - - std::vector etree(n); - char equed[] = "B"; - std::vector Rscale(m),Cscale(n); // row scale factors - std::vector ferr(nrhs), berr(nrhs); - R recip_pivot_gross, rcond; - std::vector perm_r(m), perm_c(n); - - SuperLU_gssvx(&options, &SA, &perm_c[0], &perm_r[0], - &etree[0] /* output */, equed /* output */, - &Rscale[0] /* row scale factors (output) */, - &Cscale[0] /* col scale factors (output) */, - &SL /* fact L (output)*/, &SU /* fact U (output)*/, - NULL /* work */, - 0 /* lwork: superlu auto allocates (input) */, - &SB /* rhs */, &SX /* solution */, - &recip_pivot_gross /* reciprocal pivot growth */ - /* factor max_j( norm(A_j)/norm(U_j) ). */, - &rcond /*estimate of the reciprocal condition */ - /* number of the matrix A after equilibration */, - &ferr[0] /* estimated forward error */, - &berr[0] /* relative backward error */, - &stat, &info, T()); - rcond_ = rcond; - Destroy_SuperMatrix_Store(&SB); - Destroy_SuperMatrix_Store(&SX); - Destroy_SuperMatrix_Store(&SA); - Destroy_SuperNode_Matrix(&SL); - Destroy_CompCol_Matrix(&SU); - StatFree(&stat); - GMM_ASSERT1(info >= 0, "SuperLU solve failed: info =" << info); - if (info > 0) GMM_WARNING1("SuperLU solve failed: info =" << info); - gmm::copy(sol, X); - return info; - } - - template class SuperLU_factor { - typedef typename number_traits::magnitude_type R; - - csc_matrix csc_A; - mutable SuperMatrix SA, SL, SB, SU, SX; - mutable SuperLUStat_t stat; - mutable superlu_options_t options; - float memory_used; - mutable std::vector etree, perm_r, perm_c; - mutable std::vector Rscale, Cscale; - mutable std::vector ferr, berr; - mutable std::vector rhs; - mutable std::vector sol; - mutable bool is_init; - mutable char equed; - - public : - enum { LU_NOTRANSP, LU_TRANSP, LU_CONJUGATED }; - void free_supermatrix(void); - template void build_with(const MAT &A, int permc_spec = 3); - template - /* transp = LU_NOTRANSP -> solves Ax = B - transp = LU_TRANSP -> solves A'x = B - transp = LU_CONJUGATED -> solves conj(A)X = B */ - void solve(const VECTX &X_, const VECTB &B, int transp=LU_NOTRANSP) const; - SuperLU_factor(void) { is_init = false; } - SuperLU_factor(const SuperLU_factor& other) { - GMM_ASSERT2(!(other.is_init), - "copy of initialized SuperLU_factor is forbidden"); - is_init = false; - } - SuperLU_factor& operator=(const SuperLU_factor& other) { - GMM_ASSERT2(!(other.is_init) && !is_init, - "assignment of initialized SuperLU_factor is forbidden"); - return *this; - } - ~SuperLU_factor() { free_supermatrix(); } - float memsize() { return memory_used; } - }; - - - template void SuperLU_factor::free_supermatrix(void) { - if (is_init) { - if (SB.Store) Destroy_SuperMatrix_Store(&SB); - if (SX.Store) Destroy_SuperMatrix_Store(&SX); - if (SA.Store) Destroy_SuperMatrix_Store(&SA); - if (SL.Store) Destroy_SuperNode_Matrix(&SL); - if (SU.Store) Destroy_CompCol_Matrix(&SU); - } - } - - - template template - void SuperLU_factor::build_with(const MAT &A, int permc_spec) { - /* - * Get column permutation vector perm_c[], according to permc_spec: - * permc_spec = 0: use the natural ordering - * permc_spec = 1: use minimum degree ordering on structure of A'*A - * permc_spec = 2: use minimum degree ordering on structure of A'+A - * permc_spec = 3: use approximate minimum degree column ordering - */ - free_supermatrix(); - int n = mat_nrows(A), m = mat_ncols(A), info = 0; - csc_A.init_with(A); - - rhs.resize(m); sol.resize(m); - gmm::clear(rhs); - int nz = nnz(csc_A); - - set_default_options(&options); - options.ColPerm = NATURAL; - options.PrintStat = NO; - options.ConditionNumber = NO; - switch (permc_spec) { - case 1 : options.ColPerm = MMD_ATA; break; - case 2 : options.ColPerm = MMD_AT_PLUS_A; break; - case 3 : options.ColPerm = COLAMD; break; - } - StatInit(&stat); - - Create_CompCol_Matrix(&SA, m, n, nz, (double *)(&(csc_A.pr[0])), - (int *)(&(csc_A.ir[0])), (int *)(&(csc_A.jc[0]))); - - Create_Dense_Matrix(&SB, m, 0, &rhs[0], m); - Create_Dense_Matrix(&SX, m, 0, &sol[0], m); - memset(&SL,0,sizeof SL); - memset(&SU,0,sizeof SU); - equed = 'B'; - Rscale.resize(m); Cscale.resize(n); etree.resize(n); - ferr.resize(1); berr.resize(1); - R recip_pivot_gross, rcond; - perm_r.resize(m); perm_c.resize(n); - memory_used = SuperLU_gssvx(&options, &SA, &perm_c[0], &perm_r[0], - &etree[0] /* output */, &equed /* output */, - &Rscale[0] /* row scale factors (output) */, - &Cscale[0] /* col scale factors (output) */, - &SL /* fact L (output)*/, &SU /* fact U (output)*/, - NULL /* work */, - 0 /* lwork: superlu auto allocates (input) */, - &SB /* rhs */, &SX /* solution */, - &recip_pivot_gross /* reciprocal pivot growth */ - /* factor max_j( norm(A_j)/norm(U_j) ). */, - &rcond /*estimate of the reciprocal condition */ - /* number of the matrix A after equilibration */, - &ferr[0] /* estimated forward error */, - &berr[0] /* relative backward error */, - &stat, &info, T()); - - Destroy_SuperMatrix_Store(&SB); - Destroy_SuperMatrix_Store(&SX); - Create_Dense_Matrix(&SB, m, 1, &rhs[0], m); - Create_Dense_Matrix(&SX, m, 1, &sol[0], m); - StatFree(&stat); - - GMM_ASSERT1(info == 0, "SuperLU solve failed: info=" << info); - is_init = true; - } - - template template - void SuperLU_factor::solve(const VECTX &X_, const VECTB &B, - int transp) const { - VECTX &X = const_cast(X_); - gmm::copy(B, rhs); - options.Fact = FACTORED; - options.IterRefine = NOREFINE; - switch (transp) { - case LU_NOTRANSP: options.Trans = NOTRANS; break; - case LU_TRANSP: options.Trans = TRANS; break; - case LU_CONJUGATED: options.Trans = CONJ; break; - default: GMM_ASSERT1(false, "invalid value for transposition option"); - } - StatInit(&stat); - int info = 0; - R recip_pivot_gross, rcond; - SuperLU_gssvx(&options, &SA, &perm_c[0], &perm_r[0], - &etree[0] /* output */, &equed /* output */, - &Rscale[0] /* row scale factors (output) */, - &Cscale[0] /* col scale factors (output) */, - &SL /* fact L (output)*/, &SU /* fact U (output)*/, - NULL /* work */, - 0 /* lwork: superlu auto allocates (input) */, - &SB /* rhs */, &SX /* solution */, - &recip_pivot_gross /* reciprocal pivot growth */ - /* factor max_j( norm(A_j)/norm(U_j) ). */, - &rcond /*estimate of the reciprocal condition */ - /* number of the matrix A after equilibration */, - &ferr[0] /* estimated forward error */, - &berr[0] /* relative backward error */, - &stat, &info, T()); - StatFree(&stat); - GMM_ASSERT1(info == 0, "SuperLU solve failed: info=" << info); - gmm::copy(sol, X); - } - - template inline - void mult(const SuperLU_factor& P, const V1 &v1, const V2 &v2) { - P.solve(v2,v1); - } - - template inline - void transposed_mult(const SuperLU_factor& P,const V1 &v1,const V2 &v2) { - P.solve(v2, v1, SuperLU_factor::LU_TRANSP); - } - -} - - -#endif // GMM_SUPERLU_INTERFACE_H - -#endif // GMM_USES_SUPERLU diff --git a/gmm/gmm_transposed.h b/gmm/gmm_transposed.h deleted file mode 100644 index d9b6a8182..000000000 --- a/gmm/gmm_transposed.h +++ /dev/null @@ -1,244 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_transposed.h - @author Yves Renard - @date November 10, 2002. - @brief Generic transposed matrices -*/ -#ifndef GMM_TRANSPOSED_H__ -#define GMM_TRANSPOSED_H__ - -#include "gmm_def.h" - -namespace gmm { - - /* ********************************************************************* */ - /* transposed reference */ - /* ********************************************************************* */ - - template struct transposed_row_ref { - - typedef transposed_row_ref this_type; - typedef typename std::iterator_traits::value_type M; - typedef M * CPT; - typedef typename std::iterator_traits::reference ref_M; - typedef typename select_ref - ::const_col_iterator, typename linalg_traits - ::col_iterator, PT>::ref_type iterator; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::porigin_type porigin_type; - - iterator begin_, end_; - porigin_type origin; - size_type nr, nc; - - transposed_row_ref(ref_M m) - : begin_(mat_row_begin(m)), end_(mat_row_end(m)), - origin(linalg_origin(m)), nr(mat_ncols(m)), nc(mat_nrows(m)) {} - - transposed_row_ref(const transposed_row_ref &cr) : - begin_(cr.begin_),end_(cr.end_), origin(cr.origin),nr(cr.nr),nc(cr.nc) {} - - reference operator()(size_type i, size_type j) const - { return linalg_traits::access(begin_+j, i); } - }; - - template struct linalg_traits > { - typedef transposed_row_ref this_type; - typedef typename std::iterator_traits::value_type M; - typedef typename linalg_traits::origin_type origin_type; - typedef typename select_ref::ref_type porigin_type; - typedef typename which_reference::is_reference is_reference; - typedef abstract_matrix linalg_type; - typedef typename linalg_traits::value_type value_type; - typedef typename select_ref::reference, PT>::ref_type reference; - typedef typename linalg_traits::storage_type storage_type; - typedef abstract_null_type sub_row_type; - typedef abstract_null_type const_sub_row_type; - typedef abstract_null_type row_iterator; - typedef abstract_null_type const_row_iterator; - typedef typename linalg_traits::const_sub_row_type const_sub_col_type; - typedef typename select_ref::sub_row_type, PT>::ref_type sub_col_type; - typedef typename linalg_traits::const_row_iterator const_col_iterator; - typedef typename select_ref::row_iterator, PT>::ref_type col_iterator; - typedef col_major sub_orientation; - typedef typename linalg_traits::index_sorted index_sorted; - static size_type ncols(const this_type &v) { return v.nc; } - static size_type nrows(const this_type &v) { return v.nr; } - static const_sub_col_type col(const const_col_iterator &it) - { return linalg_traits::row(it); } - static sub_col_type col(const col_iterator &it) - { return linalg_traits::row(it); } - static col_iterator col_begin(this_type &m) { return m.begin_; } - static col_iterator col_end(this_type &m) { return m.end_; } - static const_col_iterator col_begin(const this_type &m) - { return m.begin_; } - static const_col_iterator col_end(const this_type &m) { return m.end_; } - static origin_type* origin(this_type &v) { return v.origin; } - static const origin_type* origin(const this_type &v) { return v.origin; } - static void do_clear(this_type &v); - static value_type access(const const_col_iterator &itcol, size_type i) - { return linalg_traits::access(itcol, i); } - static reference access(const col_iterator &itcol, size_type i) - { return linalg_traits::access(itcol, i); } - }; - - template - void linalg_traits >::do_clear(this_type &v) { - col_iterator it = mat_col_begin(v), ite = mat_col_end(v); - for (; it != ite; ++it) clear(col(it)); - } - - template std::ostream &operator << - (std::ostream &o, const transposed_row_ref& m) - { gmm::write(o,m); return o; } - - template struct transposed_col_ref { - - typedef transposed_col_ref this_type; - typedef typename std::iterator_traits::value_type M; - typedef M * CPT; - typedef typename std::iterator_traits::reference ref_M; - typedef typename select_ref - ::const_row_iterator, typename linalg_traits - ::row_iterator, PT>::ref_type iterator; - typedef typename linalg_traits::reference reference; - typedef typename linalg_traits::porigin_type porigin_type; - - iterator begin_, end_; - porigin_type origin; - size_type nr, nc; - - transposed_col_ref(ref_M m) - : begin_(mat_col_begin(m)), end_(mat_col_end(m)), - origin(linalg_origin(m)), nr(mat_ncols(m)), nc(mat_nrows(m)) {} - - transposed_col_ref(const transposed_col_ref &cr) : - begin_(cr.begin_),end_(cr.end_), origin(cr.origin),nr(cr.nr),nc(cr.nc) {} - - reference operator()(size_type i, size_type j) const - { return linalg_traits::access(begin_+i, j); } - }; - - template struct linalg_traits > { - typedef transposed_col_ref this_type; - typedef typename std::iterator_traits::value_type M; - typedef typename linalg_traits::origin_type origin_type; - typedef typename select_ref::ref_type porigin_type; - typedef typename which_reference::is_reference is_reference; - typedef abstract_matrix linalg_type; - typedef typename linalg_traits::value_type value_type; - typedef typename select_ref::reference, PT>::ref_type reference; - typedef typename linalg_traits::storage_type storage_type; - typedef abstract_null_type sub_col_type; - typedef abstract_null_type const_sub_col_type; - typedef abstract_null_type col_iterator; - typedef abstract_null_type const_col_iterator; - typedef typename linalg_traits::const_sub_col_type const_sub_row_type; - typedef typename select_ref::sub_col_type, PT>::ref_type sub_row_type; - typedef typename linalg_traits::const_col_iterator const_row_iterator; - typedef typename select_ref::col_iterator, PT>::ref_type row_iterator; - typedef row_major sub_orientation; - typedef typename linalg_traits::index_sorted index_sorted; - static size_type nrows(const this_type &v) - { return v.nr; } - static size_type ncols(const this_type &v) - { return v.nc; } - static const_sub_row_type row(const const_row_iterator &it) - { return linalg_traits::col(it); } - static sub_row_type row(const row_iterator &it) - { return linalg_traits::col(it); } - static row_iterator row_begin(this_type &m) { return m.begin_; } - static row_iterator row_end(this_type &m) { return m.end_; } - static const_row_iterator row_begin(const this_type &m) - { return m.begin_; } - static const_row_iterator row_end(const this_type &m) { return m.end_; } - static origin_type* origin(this_type &v) { return v.origin; } - static const origin_type* origin(const this_type &v) { return v.origin; } - static void do_clear(this_type &m); - static value_type access(const const_row_iterator &itrow, size_type i) - { return linalg_traits::access(itrow, i); } - static reference access(const row_iterator &itrow, size_type i) - { return linalg_traits::access(itrow, i); } - }; - - template - void linalg_traits >::do_clear(this_type &v) { - row_iterator it = mat_row_begin(v), ite = mat_row_end(v); - for (; it != ite; ++it) clear(row(it)); - } - - template std::ostream &operator << - (std::ostream &o, const transposed_col_ref& m) - { gmm::write(o,m); return o; } - - template struct transposed_return_ { - typedef abstract_null_type return_type; - }; - template struct transposed_return_ { - typedef typename std::iterator_traits::value_type L; - typedef typename select_return, - transposed_row_ref< L *>, PT>::return_type return_type; - }; - template struct transposed_return_ { - typedef typename std::iterator_traits::value_type L; - typedef typename select_return, - transposed_col_ref< L *>, PT>::return_type return_type; - }; - template struct transposed_return { - typedef typename std::iterator_traits::value_type L; - typedef typename transposed_return_::sub_orientation>::potype, - PT>::return_type return_type; - }; - - template inline - typename transposed_return::return_type transposed(const L &l) { - return typename transposed_return::return_type - (linalg_cast(const_cast(l))); - } - - template inline - typename transposed_return::return_type transposed(L &l) - { return typename transposed_return::return_type(linalg_cast(l)); } - -} - -#endif // GMM_TRANSPOSED_H__ diff --git a/gmm/gmm_tri_solve.h b/gmm/gmm_tri_solve.h deleted file mode 100644 index d05520eb3..000000000 --- a/gmm/gmm_tri_solve.h +++ /dev/null @@ -1,222 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_tri_solve.h - @author Yves Renard - @date October 13, 2002. - @brief Solve triangular linear system for dense matrices. -*/ - -#ifndef GMM_TRI_SOLVE_H__ -#define GMM_TRI_SOLVE_H__ - -#include "gmm_interface.h" - -namespace gmm { - - template - void upper_tri_solve__(const TriMatrix& T, VecX& x, size_t k, - col_major, abstract_sparse, bool is_unit) { - typename linalg_traits::value_type x_j; - for (int j = int(k) - 1; j >= 0; --j) { - typedef typename linalg_traits::const_sub_col_type COL; - COL c = mat_const_col(T, j); - typename linalg_traits::t>::const_iterator - it = vect_const_begin(c), ite = vect_const_end(c); - if (!is_unit) x[j] /= c[j]; - for (x_j = x[j]; it != ite ; ++it) - if (int(it.index()) < j) x[it.index()] -= x_j * (*it); - } - } - - template - void upper_tri_solve__(const TriMatrix& T, VecX& x, size_t k, - col_major, abstract_dense, bool is_unit) { - typename linalg_traits::value_type x_j; - for (int j = int(k) - 1; j >= 0; --j) { - typedef typename linalg_traits::const_sub_col_type COL; - COL c = mat_const_col(T, j); - typename linalg_traits::t>::const_iterator - it = vect_const_begin(c), ite = it + j; - typename linalg_traits::iterator itx = vect_begin(x); - if (!is_unit) x[j] /= c[j]; - for (x_j = x[j]; it != ite ; ++it, ++itx) *itx -= x_j * (*it); - } - } - - template - void lower_tri_solve__(const TriMatrix& T, VecX& x, size_t k, - col_major, abstract_sparse, bool is_unit) { - typename linalg_traits::value_type x_j; - // cout << "(lower col)The Tri Matrix = " << T << endl; - // cout << "k = " << endl; - for (int j = 0; j < int(k); ++j) { - typedef typename linalg_traits::const_sub_col_type COL; - COL c = mat_const_col(T, j); - typename linalg_traits::t>::const_iterator - it = vect_const_begin(c), ite = vect_const_end(c); - if (!is_unit) x[j] /= c[j]; - for (x_j = x[j]; it != ite ; ++it) - if (int(it.index()) > j && it.index() < k) x[it.index()] -= x_j*(*it); - } - } - - template - void lower_tri_solve__(const TriMatrix& T, VecX& x, size_t k, - col_major, abstract_dense, bool is_unit) { - typename linalg_traits::value_type x_j; - for (int j = 0; j < int(k); ++j) { - typedef typename linalg_traits::const_sub_col_type COL; - COL c = mat_const_col(T, j); - typename linalg_traits::t>::const_iterator - it = vect_const_begin(c) + (j+1), ite = vect_const_begin(c) + k; - typename linalg_traits::iterator itx = vect_begin(x) + (j+1); - if (!is_unit) x[j] /= c[j]; - for (x_j = x[j]; it != ite ; ++it, ++itx) *itx -= x_j * (*it); - } - } - - - template - void upper_tri_solve__(const TriMatrix& T, VecX& x, size_t k, - row_major, abstract_sparse, bool is_unit) { - typedef typename linalg_traits::const_sub_row_type ROW; - typename linalg_traits::value_type t; - typename linalg_traits::const_row_iterator - itr = mat_row_const_end(T); - for (int i = int(k) - 1; i >= 0; --i) { - --itr; - ROW c = linalg_traits::row(itr); - typename linalg_traits::t>::const_iterator - it = vect_const_begin(c), ite = vect_const_end(c); - for (t = x[i]; it != ite; ++it) - if (int(it.index()) > i && it.index() < k) t -= (*it) * x[it.index()]; - if (!is_unit) x[i] = t / c[i]; else x[i] = t; - } - } - - template - void upper_tri_solve__(const TriMatrix& T, VecX& x, size_t k, - row_major, abstract_dense, bool is_unit) { - typename linalg_traits::value_type t; - - for (int i = int(k) - 1; i >= 0; --i) { - typedef typename linalg_traits::const_sub_row_type ROW; - ROW c = mat_const_row(T, i); - typename linalg_traits::t>::const_iterator - it = vect_const_begin(c) + (i + 1), ite = vect_const_begin(c) + k; - typename linalg_traits::iterator itx = vect_begin(x) + (i+1); - - for (t = x[i]; it != ite; ++it, ++itx) t -= (*it) * (*itx); - if (!is_unit) x[i] = t / c[i]; else x[i] = t; - } - } - - template - void lower_tri_solve__(const TriMatrix& T, VecX& x, size_t k, - row_major, abstract_sparse, bool is_unit) { - typename linalg_traits::value_type t; - - for (int i = 0; i < int(k); ++i) { - typedef typename linalg_traits::const_sub_row_type ROW; - ROW c = mat_const_row(T, i); - typename linalg_traits::t>::const_iterator - it = vect_const_begin(c), ite = vect_const_end(c); - - for (t = x[i]; it != ite; ++it) - if (int(it.index()) < i) t -= (*it) * x[it.index()]; - if (!is_unit) x[i] = t / c[i]; else x[i] = t; - } - } - - template - void lower_tri_solve__(const TriMatrix& T, VecX& x, size_t k, - row_major, abstract_dense, bool is_unit) { - typename linalg_traits::value_type t; - - for (int i = 0; i < int(k); ++i) { - typedef typename linalg_traits::const_sub_row_type ROW; - ROW c = mat_const_row(T, i); - typename linalg_traits::t>::const_iterator - it = vect_const_begin(c), ite = it + i; - typename linalg_traits::iterator itx = vect_begin(x); - - for (t = x[i]; it != ite; ++it, ++itx) t -= (*it) * (*itx); - if (!is_unit) x[i] = t / c[i]; else x[i] = t; - } - } - - -// Triangular Solve: x <-- T^{-1} * x - - template inline - void upper_tri_solve(const TriMatrix& T, VecX &x_, bool is_unit = false) - { upper_tri_solve(T, x_, mat_nrows(T), is_unit); } - - template inline - void lower_tri_solve(const TriMatrix& T, VecX &x_, bool is_unit = false) - { lower_tri_solve(T, x_, mat_nrows(T), is_unit); } - - template inline - void upper_tri_solve(const TriMatrix& T, VecX &x_, size_t k, - bool is_unit) { - VecX& x = const_cast(x_); - GMM_ASSERT2(mat_nrows(T) >= k && vect_size(x) >= k - && mat_ncols(T) >= k && !is_sparse(x_), "dimensions mismatch"); - upper_tri_solve__(T, x, k, - typename principal_orientation_type::sub_orientation>::potype(), - typename linalg_traits::storage_type(), - is_unit); - } - - template inline - void lower_tri_solve(const TriMatrix& T, VecX &x_, size_t k, - bool is_unit) { - VecX& x = const_cast(x_); - GMM_ASSERT2(mat_nrows(T) >= k && vect_size(x) >= k - && mat_ncols(T) >= k && !is_sparse(x_), "dimensions mismatch"); - lower_tri_solve__(T, x, k, - typename principal_orientation_type::sub_orientation>::potype(), - typename linalg_traits::storage_type(), - is_unit); - } - - - - - - -} - - -#endif // GMM_TRI_SOLVE_H__ diff --git a/gmm/gmm_vector.h b/gmm/gmm_vector.h deleted file mode 100644 index e69931dbe..000000000 --- a/gmm/gmm_vector.h +++ /dev/null @@ -1,1571 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2002-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ -/**@file gmm_vector.h - @author Yves Renard - @date October 13, 2002. - @brief Declaration of the vector types (gmm::rsvector, gmm::wsvector, - gmm::slvector ,..) -*/ -#ifndef GMM_VECTOR_H__ -#define GMM_VECTOR_H__ - -#include -#include "gmm_interface.h" - -namespace gmm { - - /*************************************************************************/ - /* */ - /* Class ref_elt_vector: reference on a vector component. */ - /* */ - /*************************************************************************/ - - - template class ref_elt_vector { - - V *pm; - size_type l; - - public : - - operator T() const { return pm->r(l); } - ref_elt_vector(V *p, size_type ll) : pm(p), l(ll) {} - inline bool operator ==(T v) const { return ((*pm).r(l) == v); } - inline bool operator !=(T v) const { return ((*pm).r(l) != v); } - inline bool operator ==(std::complex v) const - { return ((*pm).r(l) == v); } - inline bool operator !=(std::complex v) const - { return ((*pm).r(l) != v); } - inline ref_elt_vector &operator +=(T v) - { (*pm).wa(l, v); return *this; } - inline ref_elt_vector &operator -=(T v) - { (*pm).wa(l, -v); return *this; } - inline ref_elt_vector &operator /=(T v) - { (*pm).w(l,(*pm).r(l) / v); return *this; } - inline ref_elt_vector &operator *=(T v) - { (*pm).w(l,(*pm).r(l) * v); return *this; } - inline ref_elt_vector &operator =(const ref_elt_vector &re) - { *this = T(re); return *this; } - inline ref_elt_vector &operator =(T v) - { (*pm).w(l,v); return *this; } - T operator +() { return T(*this); } - T operator -() { return -T(*this); } - T operator +(T v) { return T(*this)+ v; } - T operator -(T v) { return T(*this)- v; } - T operator *(T v) { return T(*this)* v; } - T operator /(T v) { return T(*this)/ v; } - std::complex operator +(std::complex v) { return T(*this)+ v; } - std::complex operator -(std::complex v) { return T(*this)- v; } - std::complex operator *(std::complex v) { return T(*this)* v; } - std::complex operator /(std::complex v) { return T(*this)/ v; } - }; - - template class ref_elt_vector,V> { - - V *pm; - size_type l; - - public : - - operator std::complex() const { return pm->r(l); } - ref_elt_vector(V *p, size_type ll) : pm(p), l(ll) {} - inline bool operator ==(std::complex v) const - { return ((*pm).r(l) == v); } - inline bool operator !=(std::complex v) const - { return ((*pm).r(l) != v); } - inline bool operator ==(T v) const { return ((*pm).r(l) == v); } - inline bool operator !=(T v) const { return ((*pm).r(l) != v); } - inline ref_elt_vector &operator +=(std::complex v) - { (*pm).w(l,(*pm).r(l) + v); return *this; } - inline ref_elt_vector &operator -=(std::complex v) - { (*pm).w(l,(*pm).r(l) - v); return *this; } - inline ref_elt_vector &operator /=(std::complex v) - { (*pm).w(l,(*pm).r(l) / v); return *this; } - inline ref_elt_vector &operator *=(std::complex v) - { (*pm).w(l,(*pm).r(l) * v); return *this; } - inline ref_elt_vector &operator =(const ref_elt_vector &re) - { *this = T(re); return *this; } - inline ref_elt_vector &operator =(std::complex v) - { (*pm).w(l,v); return *this; } - inline ref_elt_vector &operator =(T v) - { (*pm).w(l,std::complex(v)); return *this; } - inline ref_elt_vector &operator +=(T v) - { (*pm).w(l,(*pm).r(l) + v); return *this; } - inline ref_elt_vector &operator -=(T v) - { (*pm).w(l,(*pm).r(l) - v); return *this; } - inline ref_elt_vector &operator /=(T v) - { (*pm).w(l,(*pm).r(l) / v); return *this; } - inline ref_elt_vector &operator *=(T v) - { (*pm).w(l,(*pm).r(l) * v); return *this; } - std::complex operator +() { return std::complex(*this); } - std::complex operator -() { return -std::complex(*this); } - std::complex operator +(T v) { return std::complex(*this)+ v; } - std::complex operator -(T v) { return std::complex(*this)- v; } - std::complex operator *(T v) { return std::complex(*this)* v; } - std::complex operator /(T v) { return std::complex(*this)/ v; } - std::complex operator +(std::complex v) - { return std::complex(*this)+ v; } - std::complex operator -(std::complex v) - { return std::complex(*this)- v; } - std::complex operator *(std::complex v) - { return std::complex(*this)* v; } - std::complex operator /(std::complex v) - { return std::complex(*this)/ v; } - }; - - - template inline - bool operator ==(T v, const ref_elt_vector &re) { return (v==T(re)); } - template inline - bool operator !=(T v, const ref_elt_vector &re) { return (v!=T(re)); } - template inline - T &operator +=(T &v, const ref_elt_vector &re) - { v += T(re); return v; } - template inline - T &operator -=(T &v, const ref_elt_vector &re) - { v -= T(re); return v; } - template inline - T &operator *=(T &v, const ref_elt_vector &re) - { v *= T(re); return v; } - template inline - T &operator /=(T &v, const ref_elt_vector &re) - { v /= T(re); return v; } - template inline - T operator +(T v, const ref_elt_vector &re) { return v+ T(re); } - template inline - T operator -(T v, const ref_elt_vector &re) { return v- T(re); } - template inline - T operator *(T v, const ref_elt_vector &re) { return v* T(re); } - template inline - T operator /(T v, const ref_elt_vector &re) { return v/ T(re); } - template inline - std::complex operator +(std::complex v, const ref_elt_vector &re) - { return v+ T(re); } - template inline - std::complex operator -(std::complex v, const ref_elt_vector &re) - { return v- T(re); } - template inline - std::complex operator *(std::complex v, const ref_elt_vector &re) - { return v* T(re); } - template inline - std::complex operator /(std::complex v, const ref_elt_vector &re) - { return v/ T(re); } - template inline - std::complex operator +(T v, const ref_elt_vector, V> &re) - { return v+ std::complex(re); } - template inline - std::complex operator -(T v, const ref_elt_vector, V> &re) - { return v- std::complex(re); } - template inline - std::complex operator *(T v, const ref_elt_vector, V> &re) - { return v* std::complex(re); } - template inline - std::complex operator /(T v, const ref_elt_vector, V> &re) - { return v/ std::complex(re); } - template inline - typename number_traits::magnitude_type - abs(const ref_elt_vector &re) { return gmm::abs(T(re)); } - template inline - T sqr(const ref_elt_vector &re) { return gmm::sqr(T(re)); } - template inline - typename number_traits::magnitude_type - abs_sqr(const ref_elt_vector &re) { return gmm::abs_sqr(T(re)); } - template inline - T conj(const ref_elt_vector &re) { return gmm::conj(T(re)); } - template std::ostream &operator << - (std::ostream &o, const ref_elt_vector &re) { o << T(re); return o; } - template inline - typename number_traits::magnitude_type - real(const ref_elt_vector &re) { return gmm::real(T(re)); } - template inline - typename number_traits::magnitude_type - imag(const ref_elt_vector &re) { return gmm::imag(T(re)); } - - /*************************************************************************/ - /* */ - /* Class dsvector: sparse vector optimized for random write operations */ - /* with constant complexity for read and write operations. */ - /* Based on distribution sort principle. */ - /* Cheap for densely populated vectors. */ - /* */ - /*************************************************************************/ - - template class dsvector; - - template struct dsvector_iterator { - size_type i; // Current index. - T* p; // Pointer to the current position. - dsvector *v; // Pointer to the vector. - - typedef T value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - // typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - typedef dsvector_iterator iterator; - - reference operator *() const { return *p; } - pointer operator->() const { return &(operator*()); } - - iterator &operator ++() { - for (size_type k = (i & 15); k < 15; ++k) - { ++p; ++i; if (*p != T(0)) return *this; } - v->next_pos(*(const_cast(&(p))), i); - return *this; - } - iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; } - iterator &operator --() { - for (size_type k = (i & 15); k > 0; --k) - { --p; --i; if (*p != T(0)) return *this; } - v->previous_pos(p, i); - return *this; - } - iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; } - - bool operator ==(const iterator &it) const - { return (i == it.i && p == it.p && v == it.v); } - bool operator !=(const iterator &it) const - { return !(it == *this); } - - size_type index(void) const { return i; } - - dsvector_iterator(void) : i(size_type(-1)), p(0), v(0) {} - dsvector_iterator(dsvector &w) : i(size_type(-1)), p(0), v(&w) {}; - }; - - - template struct dsvector_const_iterator { - size_type i; // Current index. - const T* p; // Pointer to the current position. - const dsvector *v; // Pointer to the vector. - - typedef T value_type; - typedef const value_type* pointer; - typedef const value_type& reference; - // typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - typedef dsvector_const_iterator iterator; - - reference operator *() const { return *p; } - pointer operator->() const { return &(operator*()); } - iterator &operator ++() { - for (size_type k = (i & 15); k < 15; ++k) - { ++p; ++i; if (*p != T(0)) return *this; } - v->next_pos(p, i); - return *this; - } - iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; } - iterator &operator --() { - for (size_type k = (i & 15); k > 0; --k) - { --p; --i; if (*p != T(0)) return *this; } - v->previous_pos(p, i); - return *this; - } - iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; } - - bool operator ==(const iterator &it) const - { return (i == it.i && p == it.p && v == it.v); } - bool operator !=(const iterator &it) const - { return !(it == *this); } - - size_type index(void) const { return i; } - - dsvector_const_iterator(void) : i(size_type(-1)), p(0) {} - dsvector_const_iterator(const dsvector_iterator &it) - : i(it.i), p(it.p), v(it.v) {} - dsvector_const_iterator(const dsvector &w) - : i(size_type(-1)), p(0), v(&w) {}; - }; - - - /** - Sparse vector built on distribution sort principle. - Read and write access have a constant complexity depending only on the - vector size. - */ - template class dsvector { - - typedef dsvector_iterator iterator; - typedef dsvector_const_iterator const_iterator; - typedef dsvector this_type; - typedef T * pointer; - typedef const T * const_pointer; - typedef void * void_pointer; - typedef const void * const_void_pointer; - - protected: - size_type n; // Potential vector size - size_type depth; // Number of row of pointer arrays - size_type mask; // Mask for the first pointer array - size_type shift; // Shift for the first pointer array - void_pointer root_ptr; // Root pointer - - const T *read_access(size_type i) const { - GMM_ASSERT1(i < n, "index out of range"); - size_type my_mask = mask, my_shift = shift; - void_pointer p = root_ptr; - if (!p) return 0; - for (size_type k = 0; k < depth; ++k) { - p = ((void **)(p))[(i & my_mask) >> my_shift]; - if (!p) return 0; - my_mask = (my_mask >> 4); - my_shift -= 4; - } - GMM_ASSERT1(my_shift == 0, "internal error"); - GMM_ASSERT1(my_mask == 15, "internal error"); - return &(((const T *)(p))[i & 15]); - } - - T *write_access(size_type i) { - GMM_ASSERT1(i < n, "index " << i << " out of range (size " << n << ")"); - size_type my_mask = mask, my_shift = shift; - if (!root_ptr) { - if (depth) { - root_ptr = new void_pointer[16]; - std::memset(root_ptr, 0, 16*sizeof(void_pointer)); - } else { - root_ptr = new T[16]; - for (size_type l = 0; l < 16; ++l) ((T *)(root_ptr))[l] = T(0); - } - } - - void_pointer p = root_ptr; - for (size_type k = 0; k < depth; ++k) { - size_type j = (i & my_mask) >> my_shift; - void_pointer q = ((void_pointer *)(p))[j]; - if (!q) { - if (k+1 != depth) { - q = new void_pointer[16]; - std::memset(q, 0, 16*sizeof(void_pointer)); - } else { - q = new T[16]; - for (size_type l = 0; l < 16; ++l) ((T *)(q))[l] = T(0); - } - ((void_pointer *)(p))[j] = q; - } - p = q; - my_mask = (my_mask >> 4); - my_shift -= 4; - } - GMM_ASSERT1(my_shift == 0, "internal error"); - GMM_ASSERT1(my_mask == 15, "internal error " << my_mask); - return &(((T *)(p))[i & 15]); - } - - void init(size_type n_) { - n = n_; depth = 0; shift = 0; mask = 1; if (n_) --n_; - while (n_) { n_ /= 16; ++depth; shift += 4; mask *= 16; } - mask--; if (shift) shift -= 4; if (depth) --depth; - root_ptr = 0; - } - - void rec_del(void_pointer p, size_type my_depth) { - if (my_depth) { - for (size_type k = 0; k < 16; ++k) - if (((void_pointer *)(p))[k]) - rec_del(((void_pointer *)(p))[k], my_depth-1); - delete[] ((void_pointer *)(p)); - } else { - delete[] ((T *)(p)); - } - } - - void rec_clean(void_pointer p, size_type my_depth, double eps) { - if (my_depth) { - for (size_type k = 0; k < 16; ++k) - if (((void_pointer *)(p))[k]) - rec_clean(((void_pointer *)(p))[k], my_depth-1, eps); - } else { - for (size_type k = 0; k < 16; ++k) - if (gmm::abs(((T *)(p))[k]) <= eps) ((T *)(p))[k] = T(0); - } - } - - void rec_clean_i(void_pointer p, size_type my_depth, size_type my_mask, - size_type i, size_type base) { - if (my_depth) { - my_mask = (my_mask >> 4); - for (size_type k = 0; k < 16; ++k) - if (((void_pointer *)(p))[k] && (base + (k+1)*(mask+1)) >= i) - rec_clean_i(((void_pointer *)(p))[k], my_depth-1, my_mask, - i, base + k*(my_mask+1)); - } else { - for (size_type k = 0; k < 16; ++k) - if (base+k > i) ((T *)(p))[k] = T(0); - } - } - - - size_type rec_nnz(void_pointer p, size_type my_depth) const { - size_type nn = 0; - if (my_depth) { - for (size_type k = 0; k < 16; ++k) - if (((void_pointer *)(p))[k]) - nn += rec_nnz(((void_pointer *)(p))[k], my_depth-1); - } else { - for (size_type k = 0; k < 16; ++k) - if (((const T *)(p))[k] != T(0)) nn++; - } - return nn; - } - - void copy_rec(void_pointer &p, const_void_pointer q, size_type my_depth) { - if (my_depth) { - p = new void_pointer[16]; - std::memset(p, 0, 16*sizeof(void_pointer)); - for (size_type l = 0; l < 16; ++l) - if (((const const_void_pointer *)(q))[l]) - copy_rec(((void_pointer *)(p))[l], - ((const const_void_pointer *)(q))[l], my_depth-1); - } else { - p = new T[16]; - for (size_type l = 0; l < 16; ++l) ((T *)(p))[l] = ((const T *)(q))[l]; - } - } - - void copy(const dsvector &v) { - if (root_ptr) rec_del(root_ptr, depth); - root_ptr = 0; - mask = v.mask; depth = v.depth; n = v.n; shift = v.shift; - if (v.root_ptr) copy_rec(root_ptr, v.root_ptr, depth); - } - - void next_pos_rec(void_pointer p, size_type my_depth, size_type my_mask, - const_pointer &pp, size_type &i, size_type base) const { - size_type ii = i; - if (my_depth) { - my_mask = (my_mask >> 4); - for (size_type k = 0; k < 16; ++k) - if (((void_pointer *)(p))[k] && (base + (k+1)*(my_mask+1)) >= i) { - next_pos_rec(((void_pointer *)(p))[k], my_depth-1, my_mask, - pp, i, base + k*(my_mask+1)); - if (i != size_type(-1)) return; else i = ii; - } - i = size_type(-1); pp = 0; - } else { - for (size_type k = 0; k < 16; ++k) - if (base+k > i && ((const_pointer)(p))[k] != T(0)) - { i = base+k; pp = &(((const_pointer)(p))[k]); return; } - i = size_type(-1); pp = 0; - } - } - - void previous_pos_rec(void_pointer p, size_type my_depth, size_type my_mask, - const_pointer &pp, size_type &i, - size_type base) const { - size_type ii = i; - if (my_depth) { - my_mask = (my_mask >> 4); - for (size_type k = 15; k != size_type(-1); --k) - if (((void_pointer *)(p))[k] && ((base + k*(my_mask+1)) < i)) { - previous_pos_rec(((void_pointer *)(p))[k], my_depth-1, - my_mask, pp, i, base + k*(my_mask+1)); - if (i != size_type(-1)) return; else i = ii; - } - i = size_type(-1); pp = 0; - } else { - for (size_type k = 15; k != size_type(-1); --k) - if (base+k < i && ((const_pointer)(p))[k] != T(0)) - { i = base+k; pp = &(((const_pointer)(p))[k]); return; } - i = size_type(-1); pp = 0; - } - } - - - public: - void clean(double eps) { if (root_ptr) rec_clean(root_ptr, depth); } - void resize(size_type n_) { - if (n_ != n) { - n = n_; - if (n_ < n) { // Depth unchanged (a choice) - if (root_ptr) rec_clean_i(root_ptr, depth, mask, n_, 0); - } else { - // may change the depth (add some levels) - size_type my_depth = 0, my_shift = 0, my_mask = 1; if (n_) --n_; - while (n_) { n_ /= 16; ++my_depth; my_shift += 4; my_mask *= 16; } - my_mask--; if (my_shift) my_shift -= 4; if (my_depth) --my_depth; - if (my_depth > depth || depth == 0) { - if (root_ptr) { - for (size_type k = depth; k < my_depth; ++k) { - void_pointer *q = new void_pointer [16]; - std::memset(q, 0, 16*sizeof(void_pointer)); - q[0] = root_ptr; root_ptr = q; - } - } - mask = my_mask; depth = my_depth; shift = my_shift; - } - } - } - } - - void clear(void) { if (root_ptr) rec_del(root_ptr, depth); root_ptr = 0; } - - void next_pos(const_pointer &pp, size_type &i) const { - if (!root_ptr || i >= n) { pp = 0, i = size_type(-1); return; } - next_pos_rec(root_ptr, depth, mask, pp, i, 0); - } - - void previous_pos(const_pointer &pp, size_type &i) const { - if (!root_ptr) { pp = 0, i = size_type(-1); return; } - if (i == size_type(-1)) { i = n; } - previous_pos_rec(root_ptr, depth, mask, pp, i, 0); - } - - iterator begin(void) { - iterator it(*this); - if (n && root_ptr) { - it.i = 0; it.p = const_cast(read_access(0)); - if (!(it.p) || *(it.p) == T(0)) - next_pos(*(const_cast(&(it.p))), it.i); - } - return it; - } - - iterator end(void) { return iterator(*this); } - - const_iterator begin(void) const { - const_iterator it(*this); - if (n && root_ptr) { - it.i = 0; it.p = read_access(0); - if (!(it.p) || *(it.p) == T(0)) next_pos(it.p, it.i); - } - return it; - } - - const_iterator end(void) const { return const_iterator(*this); } - - inline ref_elt_vector > operator [](size_type c) - { return ref_elt_vector >(this, c); } - - inline void w(size_type c, const T &e) { - if (e == T(0)) { if (read_access(c)) *(write_access(c)) = e; } - else *(write_access(c)) = e; - } - - inline void wa(size_type c, const T &e) - { if (e != T(0)) { *(write_access(c)) += e; } } - - inline T r(size_type c) const - { const T *p = read_access(c); if (p) return *p; else return T(0); } - - inline T operator [](size_type c) const { return r(c); } - - size_type nnz(void) const - { if (root_ptr) return rec_nnz(root_ptr, depth); else return 0; } - size_type size(void) const { return n; } - - void swap(dsvector &v) { - std::swap(n, v.n); std::swap(root_ptr, v.root_ptr); - std::swap(depth, v.depth); std::swap(shift, v.shift); - std::swap(mask, v.mask); - } - - /* Constructors */ - dsvector(const dsvector &v) { init(0); copy(v); } - dsvector &operator =(const dsvector &v) { copy(v); return *this; } - explicit dsvector(size_type l){ init(l); } - dsvector(void) { init(0); } - ~dsvector() { if (root_ptr) rec_del(root_ptr, depth); root_ptr = 0; } - }; - - template struct linalg_traits> { - typedef dsvector this_type; - typedef this_type origin_type; - typedef linalg_false is_reference; - typedef abstract_vector linalg_type; - typedef T value_type; - typedef ref_elt_vector > reference; - typedef dsvector_iterator iterator; - typedef dsvector_const_iterator const_iterator; - typedef abstract_sparse storage_type; - typedef linalg_true index_sorted; - static size_type size(const this_type &v) { return v.size(); } - static iterator begin(this_type &v) { return v.begin(); } - static const_iterator begin(const this_type &v) { return v.begin(); } - static iterator end(this_type &v) { return v.end(); } - static const_iterator end(const this_type &v) { return v.end(); } - static origin_type* origin(this_type &v) { return &v; } - static const origin_type* origin(const this_type &v) { return &v; } - static void clear(origin_type* o, const iterator &, const iterator &) - { o->clear(); } - static void do_clear(this_type &v) { v.clear(); } - static value_type access(const origin_type *o, const const_iterator &, - const const_iterator &, size_type i) - { return (*o)[i]; } - static reference access(origin_type *o, const iterator &, const iterator &, - size_type i) - { return (*o)[i]; } - static void resize(this_type &v, size_type n) { v.resize(n); } - }; - - template std::ostream &operator << - (std::ostream &o, const dsvector& v) { gmm::write(o,v); return o; } - - /******* Optimized operations for dsvector ****************************/ - - template inline void copy(const dsvector &v1, - dsvector &v2) { - GMM_ASSERT2(v1.size() == v2.size(), "dimensions mismatch"); - v2 = v1; - } - template inline void copy(const dsvector &v1, - const dsvector &v2) { - GMM_ASSERT2(v1.size() == v2.size(), "dimensions mismatch"); - v2 = const_cast &>(v1); - } - template inline - void copy(const dsvector &v1, const simple_vector_ref *> &v2){ - simple_vector_ref *> - *svr = const_cast *> *>(&v2); - dsvector - *pv = const_cast *>((v2.origin)); - GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch"); - *pv = v1; svr->begin_ = vect_begin(*pv); svr->end_ = vect_end(*pv); - } - template inline - void copy(const simple_vector_ref *> &v1, - dsvector &v2) - { copy(*(v1.origin), v2); } - template inline - void copy(const simple_vector_ref *> &v1, dsvector &v2) - { copy(*(v1.origin), v2); } - template inline - void copy(const simple_vector_ref *> &v1, - const simple_vector_ref *> &v2) - { copy(*(v1.origin), v2); } - template inline - void copy(const simple_vector_ref *> &v1, - const simple_vector_ref *> &v2) - { copy(*(v1.origin), v2); } - - template - inline size_type nnz(const dsvector& l) { return l.nnz(); } - - /*************************************************************************/ - /* */ - /* Class wsvector: sparse vector optimized for random write operations, */ - /* with log(n) complexity for read and write operations. */ - /* Based on std::map */ - /* */ - /*************************************************************************/ - - template struct wsvector_iterator - : public std::map::iterator { - typedef typename std::map::iterator base_it_type; - typedef T value_type; - typedef value_type* pointer; - typedef value_type& reference; - // typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - - reference operator *() const { return (base_it_type::operator*()).second; } - pointer operator->() const { return &(operator*()); } - size_type index(void) const { return (base_it_type::operator*()).first; } - - wsvector_iterator(void) {} - wsvector_iterator(const base_it_type &it) : base_it_type(it) {} - }; - - template struct wsvector_const_iterator - : public std::map::const_iterator { - typedef typename std::map::const_iterator base_it_type; - typedef T value_type; - typedef const value_type* pointer; - typedef const value_type& reference; - // typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - - reference operator *() const { return (base_it_type::operator*()).second; } - pointer operator->() const { return &(operator*()); } - size_type index(void) const { return (base_it_type::operator*()).first; } - - wsvector_const_iterator(void) {} - wsvector_const_iterator(const wsvector_iterator &it) - : base_it_type(it) {} - wsvector_const_iterator(const base_it_type &it) : base_it_type(it) {} - }; - - - /** - sparse vector built upon std::map. - Read and write access are quite fast (log n) - */ - template class wsvector : public std::map { - public: - - typedef typename std::map::size_type size_type; - typedef std::map base_type; - typedef typename base_type::iterator iterator; - typedef typename base_type::const_iterator const_iterator; - - protected: - size_type nbl; - - public: - void clean(double eps); - void resize(size_type); - - inline ref_elt_vector > operator [](size_type c) - { return ref_elt_vector >(this, c); } - - inline void w(size_type c, const T &e) { - GMM_ASSERT2(c < nbl, "out of range"); - if (e == T(0)) { this->erase(c); } - else base_type::operator [](c) = e; - } - - inline void wa(size_type c, const T &e) { - GMM_ASSERT2(c < nbl, "out of range"); - if (e != T(0)) { - iterator it = this->lower_bound(c); - if (it != this->end() && it->first == c) it->second += e; - else base_type::operator [](c) = e; - } - } - - inline T r(size_type c) const { - GMM_ASSERT2(c < nbl, "out of range"); - const_iterator it = this->lower_bound(c); - if (it != this->end() && c == it->first) return it->second; - else return T(0); - } - - inline T operator [](size_type c) const { return r(c); } - - size_type nb_stored(void) const { return base_type::size(); } - size_type size(void) const { return nbl; } - - void swap(wsvector &v) - { std::swap(nbl, v.nbl); std::map::swap(v); } - - - /* Constructors */ - void init(size_type l) { nbl = l; this->clear(); } - explicit wsvector(size_type l){ init(l); } - wsvector(void) { init(0); } - }; - - template void wsvector::clean(double eps) { - iterator it = this->begin(), itf = it, ite = this->end(); - while (it != ite) { - ++itf; if (gmm::abs(it->second) <= eps) this->erase(it); it = itf; - } - } - - template void wsvector::resize(size_type n) { - if (n < nbl) { - iterator it = this->begin(), itf = it, ite = this->end(); - while (it != ite) { ++itf; if (it->first >= n) this->erase(it); it=itf; } - } - nbl = n; - } - - template struct linalg_traits > { - typedef wsvector this_type; - typedef this_type origin_type; - typedef linalg_false is_reference; - typedef abstract_vector linalg_type; - typedef T value_type; - typedef ref_elt_vector > reference; - typedef wsvector_iterator iterator; - typedef wsvector_const_iterator const_iterator; - typedef abstract_sparse storage_type; - typedef linalg_true index_sorted; - static size_type size(const this_type &v) { return v.size(); } - static iterator begin(this_type &v) { return v.begin(); } - static const_iterator begin(const this_type &v) { return v.begin(); } - static iterator end(this_type &v) { return v.end(); } - static const_iterator end(const this_type &v) { return v.end(); } - static origin_type* origin(this_type &v) { return &v; } - static const origin_type* origin(const this_type &v) { return &v; } - static void clear(origin_type* o, const iterator &, const iterator &) - { o->clear(); } - static void do_clear(this_type &v) { v.clear(); } - static value_type access(const origin_type *o, const const_iterator &, - const const_iterator &, size_type i) - { return (*o)[i]; } - static reference access(origin_type *o, const iterator &, const iterator &, - size_type i) - { return (*o)[i]; } - static void resize(this_type &v, size_type n) { v.resize(n); } - }; - - template std::ostream &operator << - (std::ostream &o, const wsvector& v) { gmm::write(o,v); return o; } - - /******* Optimized BLAS for wsvector **********************************/ - - template inline void copy(const wsvector &v1, - wsvector &v2) { - GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch"); - v2 = v1; - } - template inline - void copy(const wsvector &v1, const simple_vector_ref *> &v2){ - simple_vector_ref *> - *svr = const_cast *> *>(&v2); - wsvector - *pv = const_cast *>(v2.origin); - GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch"); - *pv = v1; svr->begin_ = vect_begin(*pv); svr->end_ = vect_end(*pv); - } - template inline - void copy(const simple_vector_ref *> &v1, - wsvector &v2) - { copy(*(v1.origin), v2); } - template inline - void copy(const simple_vector_ref *> &v1, wsvector &v2) - { copy(*(v1.origin), v2); } - - template inline void clean(wsvector &v, double eps) { - typedef typename number_traits::magnitude_type R; - typename wsvector::iterator it = v.begin(), ite = v.end(), itc; - while (it != ite) - if (gmm::abs((*it).second) <= R(eps)) - { itc=it; ++it; v.erase(itc); } else ++it; - } - - template - inline void clean(const simple_vector_ref *> &l, double eps) { - simple_vector_ref *> - *svr = const_cast *> *>(&l); - wsvector - *pv = const_cast *>((l.origin)); - clean(*pv, eps); - svr->begin_ = vect_begin(*pv); svr->end_ = vect_end(*pv); - } - - template - inline size_type nnz(const wsvector& l) { return l.nb_stored(); } - - /*************************************************************************/ - /* */ - /* rsvector: sparse vector optimized for linear algebra operations. */ - /* */ - /*************************************************************************/ - - template struct elt_rsvector_ { - size_type c; T e; - /* e is initialized by default to avoid some false warnings of valgrind. - (from http://valgrind.org/docs/manual/mc-manual.html: - - When memory is read into the CPU's floating point registers, the - relevant V bits are read from memory and they are immediately - checked. If any are invalid, an uninitialised value error is - emitted. This precludes using the floating-point registers to copy - possibly-uninitialised memory, but simplifies Valgrind in that it - does not have to track the validity status of the floating-point - registers. - */ - elt_rsvector_(void) : e(0) {} - elt_rsvector_(size_type cc) : c(cc), e(0) {} - elt_rsvector_(size_type cc, const T &ee) : c(cc), e(ee) {} - bool operator < (const elt_rsvector_ &a) const { return c < a.c; } - bool operator == (const elt_rsvector_ &a) const { return c == a.c; } - bool operator != (const elt_rsvector_ &a) const { return c != a.c; } - }; - - template struct rsvector_iterator { - typedef typename std::vector >::iterator IT; - typedef T value_type; - typedef value_type* pointer; - typedef value_type& reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - typedef rsvector_iterator iterator; - - IT it; - - reference operator *() const { return it->e; } - pointer operator->() const { return &(operator*()); } - - iterator &operator ++() { ++it; return *this; } - iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; } - iterator &operator --() { --it; return *this; } - iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; } - - bool operator ==(const iterator &i) const { return it == i.it; } - bool operator !=(const iterator &i) const { return !(i == *this); } - - size_type index(void) const { return it->c; } - rsvector_iterator(void) {} - rsvector_iterator(const IT &i) : it(i) {} - }; - - template struct rsvector_const_iterator { - typedef typename std::vector >::const_iterator IT; - typedef T value_type; - typedef const value_type* pointer; - typedef const value_type& reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef std::forward_iterator_tag iterator_category; - typedef rsvector_const_iterator iterator; - - IT it; - - reference operator *() const { return it->e; } - pointer operator->() const { return &(operator*()); } - size_type index(void) const { return it->c; } - - iterator &operator ++() { ++it; return *this; } - iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; } - iterator &operator --() { --it; return *this; } - iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; } - - bool operator ==(const iterator &i) const { return it == i.it; } - bool operator !=(const iterator &i) const { return !(i == *this); } - - rsvector_const_iterator(void) {} - rsvector_const_iterator(const rsvector_iterator &i) : it(i.it) {} - rsvector_const_iterator(const IT &i) : it(i) {} - }; - - /** - sparse vector built upon std::vector. Read access is fast, - but insertion is O(n) - */ - template class rsvector : public std::vector > { - public: - - typedef std::vector > base_type_; - typedef typename base_type_::iterator iterator; - typedef typename base_type_::const_iterator const_iterator; - typedef typename base_type_::size_type size_type; - typedef T value_type; - - protected: - size_type nbl; /* size of the vector. */ - - public: - - void sup(size_type j); - void base_resize(size_type n) { base_type_::resize(n); } - void resize(size_type); - - ref_elt_vector > operator [](size_type c) - { return ref_elt_vector >(this, c); } - - void w(size_type c, const T &e); - void wa(size_type c, const T &e); - T r(size_type c) const; - void swap_indices(size_type i, size_type j); - - inline T operator [](size_type c) const { return r(c); } - - size_type nb_stored(void) const { return base_type_::size(); } - size_type size(void) const { return nbl; } - void clear(void) { base_type_::resize(0); } - void swap(rsvector &v) - { std::swap(nbl, v.nbl); std::vector >::swap(v); } - - /* Constructeurs */ - explicit rsvector(size_type l) : nbl(l) { } - rsvector(void) : nbl(0) { } - }; - - template - void rsvector::swap_indices(size_type i, size_type j) { - if (i > j) std::swap(i, j); - if (i != j) { - int situation = 0; - elt_rsvector_ ei(i), ej(j), a; - iterator it, ite, iti, itj; - iti = std::lower_bound(this->begin(), this->end(), ei); - if (iti != this->end() && iti->c == i) situation += 1; - itj = std::lower_bound(this->begin(), this->end(), ej); - if (itj != this->end() && itj->c == j) situation += 2; - - switch (situation) { - case 1 : a = *iti; a.c = j; it = iti; ++it; ite = this->end(); - for (; it != ite && it->c <= j; ++it, ++iti) *iti = *it; - *iti = a; - break; - case 2 : a = *itj; a.c = i; it = itj; ite = this->begin(); - if (it != ite) { - --it; - while (it->c >= i) { *itj = *it; --itj; if (it==ite) break; --it; } - } - *itj = a; - break; - case 3 : std::swap(iti->e, itj->e); - break; - } - } - } - - template void rsvector::sup(size_type j) { - if (nb_stored() != 0) { - elt_rsvector_ ev(j); - iterator it = std::lower_bound(this->begin(), this->end(), ev); - if (it != this->end() && it->c == j) { - for (iterator ite = this->end() - 1; it != ite; ++it) *it = *(it+1); - base_resize(nb_stored()-1); - } - } - } - - template void rsvector::resize(size_type n) { - if (n < nbl) { - for (size_type i = 0; i < nb_stored(); ++i) - if (base_type_::operator[](i).c >= n) { base_resize(i); break; } - } - nbl = n; - } - - template void rsvector::w(size_type c, const T &e) { - GMM_ASSERT2(c < nbl, "out of range"); - if (e == T(0)) sup(c); - else { - elt_rsvector_ ev(c, e); - if (nb_stored() == 0) { - base_type_::push_back(ev); - } - else { - iterator it = std::lower_bound(this->begin(), this->end(), ev); - if (it != this->end() && it->c == c) it->e = e; - else { - size_type ind = it - this->begin(), nb = this->nb_stored(); - if (nb - ind > 1100) - GMM_WARNING2("Inefficient addition of element in rsvector with " - << this->nb_stored() - ind << " non-zero entries"); - base_type_::push_back(ev); - if (ind != nb) { - it = this->begin() + ind; - iterator ite = this->end(); --ite; iterator itee = ite; - for (; ite != it; --ite) { --itee; *ite = *itee; } - *it = ev; - } - } - } - } - } - - template void rsvector::wa(size_type c, const T &e) { - GMM_ASSERT2(c < nbl, "out of range"); - if (e != T(0)) { - elt_rsvector_ ev(c, e); - if (nb_stored() == 0) { - base_type_::push_back(ev); - } - else { - iterator it = std::lower_bound(this->begin(), this->end(), ev); - if (it != this->end() && it->c == c) it->e += e; - else { - size_type ind = it - this->begin(), nb = this->nb_stored(); - if (nb - ind > 1100) - GMM_WARNING2("Inefficient addition of element in rsvector with " - << this->nb_stored() - ind << " non-zero entries"); - base_type_::push_back(ev); - if (ind != nb) { - it = this->begin() + ind; - iterator ite = this->end(); --ite; iterator itee = ite; - for (; ite != it; --ite) { --itee; *ite = *itee; } - *it = ev; - } - } - } - } - } - - template T rsvector::r(size_type c) const { - GMM_ASSERT2(c < nbl, "out of range. Index " << c - << " for a length of " << nbl); - if (nb_stored() != 0) { - elt_rsvector_ ev(c); - const_iterator it = std::lower_bound(this->begin(), this->end(), ev); - if (it != this->end() && it->c == c) return it->e; - } - return T(0); - } - - template struct linalg_traits > { - typedef rsvector this_type; - typedef this_type origin_type; - typedef linalg_false is_reference; - typedef abstract_vector linalg_type; - typedef T value_type; - typedef ref_elt_vector > reference; - typedef rsvector_iterator iterator; - typedef rsvector_const_iterator const_iterator; - typedef abstract_sparse storage_type; - typedef linalg_true index_sorted; - static size_type size(const this_type &v) { return v.size(); } - static iterator begin(this_type &v) { return iterator(v.begin()); } - static const_iterator begin(const this_type &v) - { return const_iterator(v.begin()); } - static iterator end(this_type &v) { return iterator(v.end()); } - static const_iterator end(const this_type &v) - { return const_iterator(v.end()); } - static origin_type* origin(this_type &v) { return &v; } - static const origin_type* origin(const this_type &v) { return &v; } - static void clear(origin_type* o, const iterator &, const iterator &) - { o->clear(); } - static void do_clear(this_type &v) { v.clear(); } - static value_type access(const origin_type *o, const const_iterator &, - const const_iterator &, size_type i) - { return (*o)[i]; } - static reference access(origin_type *o, const iterator &, const iterator &, - size_type i) - { return (*o)[i]; } - static void resize(this_type &v, size_type n) { v.resize(n); } - }; - - template std::ostream &operator << - (std::ostream &o, const rsvector& v) { gmm::write(o,v); return o; } - - /******* Optimized operations for rsvector ****************************/ - - template inline void copy(const rsvector &v1, - rsvector &v2) { - GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch"); - v2 = v1; - } - template inline - void copy(const rsvector &v1, const simple_vector_ref *> &v2){ - simple_vector_ref *> - *svr = const_cast *> *>(&v2); - rsvector - *pv = const_cast *>((v2.origin)); - GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch"); - *pv = v1; svr->begin_ = vect_begin(*pv); svr->end_ = vect_end(*pv); - } - template inline - void copy(const simple_vector_ref *> &v1, - rsvector &v2) - { copy(*(v1.origin), v2); } - template inline - void copy(const simple_vector_ref *> &v1, rsvector &v2) - { copy(*(v1.origin), v2); } - - template inline void add(const V &v1, - rsvector &v2) { - if ((const void *)(&v1) != (const void *)(&v2)) { - GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch"); - add_rsvector(v1, v2, typename linalg_traits::storage_type()); - } - } - - template - inline void add_rsvector(const V &v1, rsvector &v2, abstract_dense) - { add(v1, v2, abstract_dense(), abstract_sparse()); } - - template - inline void add_rsvector(const V &v1, rsvector &v2, abstract_skyline) - { add(v1, v2, abstract_skyline(), abstract_sparse()); } - - template - void add_rsvector(const V &v1, rsvector &v2, abstract_sparse) { - add_rsvector(v1, v2, typename linalg_traits::index_sorted()); - } - - template - void add_rsvector(const V &v1, rsvector &v2, linalg_false) { - add(v1, v2, abstract_sparse(), abstract_sparse()); - } - - template - void add_rsvector(const V &v1, rsvector &v2, linalg_true) { - typename linalg_traits::const_iterator it1 = vect_const_begin(v1), - ite1 = vect_const_end(v1); - typename rsvector::iterator it2 = v2.begin(), ite2 = v2.end(), it3; - size_type nbc = 0, old_nbc = v2.nb_stored(); - for (; it1 != ite1 && it2 != ite2 ; ++nbc) - if (it1.index() == it2->c) { ++it1; ++it2; } - else if (it1.index() < it2->c) ++it1; else ++it2; - for (; it1 != ite1; ++it1) ++nbc; - for (; it2 != ite2; ++it2) ++nbc; - - v2.base_resize(nbc); - it3 = v2.begin() + old_nbc; - it2 = v2.end(); ite2 = v2.begin(); - it1 = vect_end(v1); ite1 = vect_const_begin(v1); - while (it1 != ite1 && it3 != ite2) { - --it3; --it1; --it2; - if (it3->c > it1.index()) { *it2 = *it3; ++it1; } - else if (it3->c == it1.index()) { *it2=*it3; it2->e+=*it1; } - else { it2->c = it1.index(); it2->e = *it1; ++it3; } - } - while (it1 != ite1) { --it1; --it2; it2->c = it1.index(); it2->e = *it1; } - } - - template void copy(const V &v1, rsvector &v2) { - if ((const void *)(&v1) != (const void *)(&v2)) { - GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch"); - if (same_origin(v1, v2)) - GMM_WARNING2("a conflict is possible in vector copy\n"); - copy_rsvector(v1, v2, typename linalg_traits::storage_type()); - } - } - - template - void copy_rsvector(const V &v1, rsvector &v2, abstract_dense) - { copy_vect(v1, v2, abstract_dense(), abstract_sparse()); } - - template - void copy_rsvector(const V &v1, rsvector &v2, abstract_skyline) - { copy_vect(v1, v2, abstract_skyline(), abstract_sparse()); } - - template - void copy_rsvector(const V &v1, rsvector &v2, abstract_sparse) { - copy_rsvector(v1, v2, typename linalg_traits::index_sorted()); - } - - template - void copy_rsvector(const V &v1, rsvector &v2, linalg_true) { - typedef typename linalg_traits::value_type T1; - typename linalg_traits::const_iterator it = vect_const_begin(v1), - ite = vect_const_end(v1); - v2.base_resize(nnz(v1)); - typename rsvector::iterator it2 = v2.begin(); - size_type nn = 0; - for (; it != ite; ++it) - if ((*it) != T1(0)) { it2->c = it.index(); it2->e = *it; ++it2; ++nn; } - v2.base_resize(nn); - } - - template - void copy_rsvector(const V &v1, rsvector &v2, linalg_false) { - typedef typename linalg_traits::value_type T1; - typename linalg_traits::const_iterator it = vect_const_begin(v1), - ite = vect_const_end(v1); - v2.base_resize(nnz(v1)); - typename rsvector::iterator it2 = v2.begin(); - size_type nn = 0; - for (; it != ite; ++it) - if ((*it) != T1(0)) { it2->c = it.index(); it2->e = *it; ++it2; ++nn; } - v2.base_resize(nn); - std::sort(v2.begin(), v2.end()); - } - - template inline void clean(rsvector &v, double eps) { - typedef typename number_traits::magnitude_type R; - typename rsvector::iterator it = v.begin(), ite = v.end(); - for (; it != ite; ++it) if (gmm::abs((*it).e) <= eps) break; - if (it != ite) { - typename rsvector::iterator itc = it; - size_type erased = 1; - for (++it; it != ite; ++it) - { *itc = *it; if (gmm::abs((*it).e) <= R(eps)) ++erased; else ++itc; } - v.base_resize(v.nb_stored() - erased); - } - } - - template - inline void clean(const simple_vector_ref *> &l, double eps) { - simple_vector_ref *> - *svr = const_cast *> *>(&l); - rsvector - *pv = const_cast *>((l.origin)); - clean(*pv, eps); - svr->begin_ = vect_begin(*pv); svr->end_ = vect_end(*pv); - } - - template - inline size_type nnz(const rsvector& l) { return l.nb_stored(); } - - /*************************************************************************/ - /* */ - /* Class slvector: 'sky-line' vector. */ - /* */ - /*************************************************************************/ - - template struct slvector_iterator { - typedef T value_type; - typedef T *pointer; - typedef T &reference; - typedef ptrdiff_t difference_type; - typedef std::random_access_iterator_tag iterator_category; - typedef size_t size_type; - typedef slvector_iterator iterator; - typedef typename std::vector::iterator base_iterator; - - base_iterator it; - size_type shift; - - - iterator &operator ++() - { ++it; ++shift; return *this; } - iterator &operator --() - { --it; --shift; return *this; } - iterator operator ++(int) - { iterator tmp = *this; ++(*(this)); return tmp; } - iterator operator --(int) - { iterator tmp = *this; --(*(this)); return tmp; } - iterator &operator +=(difference_type i) - { it += i; shift += i; return *this; } - iterator &operator -=(difference_type i) - { it -= i; shift -= i; return *this; } - iterator operator +(difference_type i) const - { iterator tmp = *this; return (tmp += i); } - iterator operator -(difference_type i) const - { iterator tmp = *this; return (tmp -= i); } - difference_type operator -(const iterator &i) const - { return it - i.it; } - - reference operator *() const - { return *it; } - reference operator [](int ii) - { return *(it + ii); } - - bool operator ==(const iterator &i) const - { return it == i.it; } - bool operator !=(const iterator &i) const - { return !(i == *this); } - bool operator < (const iterator &i) const - { return it < i.it; } - size_type index(void) const { return shift; } - - slvector_iterator(void) {} - slvector_iterator(const base_iterator &iter, size_type s) - : it(iter), shift(s) {} - }; - - template struct slvector_const_iterator { - typedef T value_type; - typedef const T *pointer; - typedef value_type reference; - typedef ptrdiff_t difference_type; - typedef std::random_access_iterator_tag iterator_category; - typedef size_t size_type; - typedef slvector_const_iterator iterator; - typedef typename std::vector::const_iterator base_iterator; - - base_iterator it; - size_type shift; - - - iterator &operator ++() - { ++it; ++shift; return *this; } - iterator &operator --() - { --it; --shift; return *this; } - iterator operator ++(int) - { iterator tmp = *this; ++(*(this)); return tmp; } - iterator operator --(int) - { iterator tmp = *this; --(*(this)); return tmp; } - iterator &operator +=(difference_type i) - { it += i; shift += i; return *this; } - iterator &operator -=(difference_type i) - { it -= i; shift -= i; return *this; } - iterator operator +(difference_type i) const - { iterator tmp = *this; return (tmp += i); } - iterator operator -(difference_type i) const - { iterator tmp = *this; return (tmp -= i); } - difference_type operator -(const iterator &i) const - { return it - i.it; } - - value_type operator *() const - { return *it; } - value_type operator [](int ii) - { return *(it + ii); } - - bool operator ==(const iterator &i) const - { return it == i.it; } - bool operator !=(const iterator &i) const - { return !(i == *this); } - bool operator < (const iterator &i) const - { return it < i.it; } - size_type index(void) const { return shift; } - - slvector_const_iterator(void) {} - slvector_const_iterator(const slvector_iterator& iter) - : it(iter.it), shift(iter.shift) {} - slvector_const_iterator(const base_iterator &iter, size_type s) - : it(iter), shift(s) {} - }; - - - /** skyline vector. - */ - template class slvector { - - public : - typedef slvector_iterator iterators; - typedef slvector_const_iterator const_iterators; - typedef typename std::vector::size_type size_type; - typedef T value_type; - - protected : - std::vector data; - size_type shift; - size_type size_; - - - public : - - size_type size(void) const { return size_; } - size_type first(void) const { return shift; } - size_type last(void) const { return shift + data.size(); } - ref_elt_vector > operator [](size_type c) - { return ref_elt_vector >(this, c); } - - typename std::vector::iterator data_begin(void) { return data.begin(); } - typename std::vector::iterator data_end(void) { return data.end(); } - typename std::vector::const_iterator data_begin(void) const - { return data.begin(); } - typename std::vector::const_iterator data_end(void) const - { return data.end(); } - - void w(size_type c, const T &e); - void wa(size_type c, const T &e); - T r(size_type c) const { - GMM_ASSERT2(c < size_, "out of range"); - if (c < shift || c >= shift + data.size()) return T(0); - return data[c - shift]; - } - - inline T operator [](size_type c) const { return r(c); } - void resize(size_type); - void clear(void) { data.resize(0); shift = 0; } - void swap(slvector &v) { - std::swap(data, v.data); - std::swap(shift, v.shift); - std::swap(size_, v.size_); - } - - - slvector(void) : data(0), shift(0), size_(0) {} - explicit slvector(size_type l) : data(0), shift(0), size_(l) {} - slvector(size_type l, size_type d, size_type s) - : data(d), shift(s), size_(l) {} - - }; - - template void slvector::resize(size_type n) { - if (n < last()) { - if (shift >= n) clear(); else { data.resize(n-shift); } - } - size_ = n; - } - - template void slvector::w(size_type c, const T &e) { - GMM_ASSERT2(c < size_, "out of range"); - size_type s = data.size(); - if (!s) { data.resize(1); shift = c; } - else if (c < shift) { - data.resize(s + shift - c); - typename std::vector::iterator it = data.begin(),it2=data.end()-1; - typename std::vector::iterator it3 = it2 - shift + c; - for (; it3 >= it; --it3, --it2) *it2 = *it3; - std::fill(it, it + shift - c, T(0)); - shift = c; - } - else if (c >= shift + s) { - data.resize(c - shift + 1, T(0)); - // std::fill(data.begin() + s, data.end(), T(0)); - } - data[c - shift] = e; - } - - template void slvector::wa(size_type c, const T &e) { - GMM_ASSERT2(c < size_, "out of range"); - size_type s = data.size(); - if (!s) { data.resize(1, e); shift = c; return; } - else if (c < shift) { - data.resize(s + shift - c); - typename std::vector::iterator it = data.begin(),it2=data.end()-1; - typename std::vector::iterator it3 = it2 - shift + c; - for (; it3 >= it; --it3, --it2) *it2 = *it3; - std::fill(it, it + shift - c, T(0)); - shift = c; - data[c - shift] = e; - return; - } - else if (c >= shift + s) { - data.resize(c - shift + 1, T(0)); - data[c - shift] = e; - return; - // std::fill(data.begin() + s, data.end(), T(0)); - } - data[c - shift] += e; - } - - - template struct linalg_traits > { - typedef slvector this_type; - typedef this_type origin_type; - typedef linalg_false is_reference; - typedef abstract_vector linalg_type; - typedef T value_type; - typedef ref_elt_vector > reference; - typedef slvector_iterator iterator; - typedef slvector_const_iterator const_iterator; - typedef abstract_skyline storage_type; - typedef linalg_true index_sorted; - static size_type size(const this_type &v) { return v.size(); } - static iterator begin(this_type &v) - { return iterator(v.data_begin(), v.first()); } - static const_iterator begin(const this_type &v) - { return const_iterator(v.data_begin(), v.first()); } - static iterator end(this_type &v) - { return iterator(v.data_end(), v.last()); } - static const_iterator end(const this_type &v) - { return const_iterator(v.data_end(), v.last()); } - static origin_type* origin(this_type &v) { return &v; } - static const origin_type* origin(const this_type &v) { return &v; } - static void clear(origin_type* o, const iterator &, const iterator &) - { o->clear(); } - static void do_clear(this_type &v) { v.clear(); } - static value_type access(const origin_type *o, const const_iterator &, - const const_iterator &, size_type i) - { return (*o)[i]; } - static reference access(origin_type *o, const iterator &, const iterator &, - size_type i) - { return (*o)[i]; } - static void resize(this_type &v, size_type n) { v.resize(n); } - }; - - template std::ostream &operator << - (std::ostream &o, const slvector& v) { gmm::write(o,v); return o; } - - template - inline size_type nnz(const slvector& l) { return l.last() - l.first(); } - -} - -namespace std { - template void swap(gmm::wsvector &v, gmm::wsvector &w) - { v.swap(w);} - template void swap(gmm::rsvector &v, gmm::rsvector &w) - { v.swap(w);} - template void swap(gmm::slvector &v, gmm::slvector &w) - { v.swap(w);} -} - - - -#endif /* GMM_VECTOR_H__ */ diff --git a/gmm/gmm_vector_to_matrix.h b/gmm/gmm_vector_to_matrix.h deleted file mode 100644 index 83fc0c54f..000000000 --- a/gmm/gmm_vector_to_matrix.h +++ /dev/null @@ -1,340 +0,0 @@ -/* -*- c++ -*- (enables emacs c++ mode) */ -/*=========================================================================== - - Copyright (C) 2003-2017 Yves Renard - - This file is a part of GetFEM++ - - GetFEM++ is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 3 of the License, or - (at your option) any later version along with the GCC Runtime Library - Exception either version 3.1 or (at your option) any later version. - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License and GCC Runtime Library Exception for more details. - You should have received a copy of the GNU Lesser General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - - As a special exception, you may use this file as it is a part of a free - software library without restriction. Specifically, if other files - instantiate templates or use macros or inline functions from this file, - or you compile this file and link it with other files to produce an - executable, this file does not by itself cause the resulting executable - to be covered by the GNU Lesser General Public License. This exception - does not however invalidate any other reasons why the executable file - might be covered by the GNU Lesser General Public License. - -===========================================================================*/ - -/**@file gmm_vector_to_matrix.h - @author Yves Renard - @date December 6, 2003. - @brief View vectors as row or column matrices. */ -#ifndef GMM_VECTOR_TO_MATRIX_H__ -#define GMM_VECTOR_TO_MATRIX_H__ - -#include "gmm_interface.h" - -namespace gmm { - - /* ********************************************************************* */ - /* row vector -> transform a vector in a (1, n) matrix. */ - /* ********************************************************************* */ - - template struct gen_row_vector { - typedef gen_row_vector this_type; - typedef typename std::iterator_traits::value_type V; - typedef V * CPT; - typedef typename std::iterator_traits::reference ref_V; - typedef typename linalg_traits::reference reference; - - simple_vector_ref vec; - - reference operator()(size_type, size_type j) const { return vec[j]; } - - size_type nrows(void) const { return 1; } - size_type ncols(void) const { return vect_size(vec); } - - gen_row_vector(ref_V v) : vec(v) {} - gen_row_vector() {} - gen_row_vector(const gen_row_vector &cr) : vec(cr.vec) {} - }; - - template - struct gen_row_vector_iterator { - typedef gen_row_vector this_type; - typedef typename modifiable_pointer::pointer MPT; - typedef typename std::iterator_traits::value_type V; - typedef simple_vector_ref value_type; - typedef const simple_vector_ref *pointer; - typedef const simple_vector_ref &reference; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - typedef std::random_access_iterator_tag iterator_category; - typedef gen_row_vector_iterator iterator; - - simple_vector_ref vec; - bool isend; - - iterator &operator ++() { isend = true; return *this; } - iterator &operator --() { isend = false; return *this; } - iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; } - iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; } - iterator &operator +=(difference_type i) - { if (i) isend = false; return *this; } - iterator &operator -=(difference_type i) - { if (i) isend = true; return *this; } - iterator operator +(difference_type i) const - { iterator itt = *this; return (itt += i); } - iterator operator -(difference_type i) const - { iterator itt = *this; return (itt -= i); } - difference_type operator -(const iterator &i) const { - return (isend == true) ? ((i.isend == true) ? 0 : 1) - : ((i.isend == true) ? -1 : 0); - } - - const simple_vector_ref& operator *() const { return vec; } - const simple_vector_ref& operator [](int i) { return vec; } - - bool operator ==(const iterator &i) const { return (isend == i.isend); } - bool operator !=(const iterator &i) const { return !(i == *this); } - bool operator < (const iterator &i) const { return (*this - i < 0); } - - gen_row_vector_iterator(void) {} - gen_row_vector_iterator(const gen_row_vector_iterator &itm) - : vec(itm.vec), isend(itm.isend) {} - gen_row_vector_iterator(const gen_row_vector &m, bool iis_end) - : vec(m.vec), isend(iis_end) { } - - }; - - template - struct linalg_traits > { - typedef gen_row_vector this_type; - typedef typename std::iterator_traits::value_type V; - typedef typename which_reference::is_reference is_reference; - typedef abstract_matrix linalg_type; - typedef typename linalg_traits::origin_type origin_type; - typedef typename select_ref::ref_type porigin_type; - typedef typename linalg_traits::value_type value_type; - typedef typename select_ref::reference, PT>::ref_type reference; - typedef abstract_null_type sub_col_type; - typedef abstract_null_type col_iterator; - typedef abstract_null_type const_sub_col_type; - typedef abstract_null_type const_col_iterator; - typedef simple_vector_ref const_sub_row_type; - typedef typename select_ref, PT>::ref_type sub_row_type; - typedef gen_row_vector_iterator::pointer> - const_row_iterator; - typedef typename select_ref, PT>::ref_type row_iterator; - typedef typename linalg_traits::storage_type storage_type; - typedef row_major sub_orientation; - typedef typename linalg_traits::index_sorted index_sorted; - static size_type nrows(const this_type &) { return 1; } - static size_type ncols(const this_type &m) { return m.ncols(); } - static const_sub_row_type row(const const_row_iterator &it) { return *it; } - static sub_row_type row(const row_iterator &it) { return *it; } - static const_row_iterator row_begin(const this_type &m) - { return const_row_iterator(m, false); } - static row_iterator row_begin(this_type &m) - { return row_iterator(m, false); } - static const_row_iterator row_end(const this_type &m) - { return const_row_iterator(m, true); } - static row_iterator row_end(this_type &m) - { return row_iterator(m, true); } - static origin_type* origin(this_type &m) { return m.vec.origin; } - static const origin_type* origin(const this_type &m) - { return m.vec.origin; } - static void do_clear(this_type &m) - { clear(row(mat_row_begin(m))); } - static value_type access(const const_row_iterator &itrow, size_type i) - { return itrow.vec[i]; } - static reference access(const row_iterator &itrow, size_type i) - { return itrow.vec[i]; } - }; - - template - std::ostream &operator <<(std::ostream &o, const gen_row_vector& m) - { gmm::write(o,m); return o; } - - /* ********************************************************************* */ - /* col vector -> transform a vector in a (n, 1) matrix. */ - /* ********************************************************************* */ - - template struct gen_col_vector { - typedef gen_col_vector this_type; - typedef typename std::iterator_traits::value_type V; - typedef V * CPT; - typedef typename std::iterator_traits::reference ref_V; - typedef typename linalg_traits::reference reference; - - simple_vector_ref vec; - - reference operator()(size_type i, size_type) const { return vec[i]; } - - size_type ncols(void) const { return 1; } - size_type nrows(void) const { return vect_size(vec); } - - gen_col_vector(ref_V v) : vec(v) {} - gen_col_vector() {} - gen_col_vector(const gen_col_vector &cr) : vec(cr.vec) {} - }; - - template - struct gen_col_vector_iterator { - typedef gen_col_vector this_type; - typedef typename modifiable_pointer::pointer MPT; - typedef typename std::iterator_traits::value_type V; - typedef simple_vector_ref value_type; - typedef const simple_vector_ref *pointer; - typedef const simple_vector_ref &reference; - typedef ptrdiff_t difference_type; - typedef size_t size_type; - typedef std::random_access_iterator_tag iterator_category; - typedef gen_col_vector_iterator iterator; - - simple_vector_ref vec; - bool isend; - - iterator &operator ++() { isend = true; return *this; } - iterator &operator --() { isend = false; return *this; } - iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; } - iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; } - iterator &operator +=(difference_type i) - { if (i) isend = false; return *this; } - iterator &operator -=(difference_type i) - { if (i) isend = true; return *this; } - iterator operator +(difference_type i) const - { iterator itt = *this; return (itt += i); } - iterator operator -(difference_type i) const - { iterator itt = *this; return (itt -= i); } - difference_type operator -(const iterator &i) const { - return (isend == true) ? ((i.isend == true) ? 0 : 1) - : ((i.isend == true) ? -1 : 0); - } - - const simple_vector_ref& operator *() const { return vec; } - const simple_vector_ref& operator [](int i) { return vec; } - - bool operator ==(const iterator &i) const { return (isend == i.isend); } - bool operator !=(const iterator &i) const { return !(i == *this); } - bool operator < (const iterator &i) const { return (*this - i < 0); } - - gen_col_vector_iterator(void) {} - gen_col_vector_iterator(const gen_col_vector_iterator &itm) - : vec(itm.vec), isend(itm.isend) {} - gen_col_vector_iterator(const gen_col_vector &m, bool iis_end) - : vec(m.vec), isend(iis_end) { } - - }; - - template - struct linalg_traits > { - typedef gen_col_vector this_type; - typedef typename std::iterator_traits::value_type V; - typedef typename which_reference::is_reference is_reference; - typedef abstract_matrix linalg_type; - typedef typename linalg_traits::origin_type origin_type; - typedef typename select_ref::ref_type porigin_type; - typedef typename linalg_traits::value_type value_type; - typedef typename select_ref::reference, PT>::ref_type reference; - typedef abstract_null_type sub_row_type; - typedef abstract_null_type row_iterator; - typedef abstract_null_type const_sub_row_type; - typedef abstract_null_type const_row_iterator; - typedef simple_vector_ref const_sub_col_type; - typedef typename select_ref, PT>::ref_type sub_col_type; - typedef gen_col_vector_iterator::pointer> - const_col_iterator; - typedef typename select_ref, PT>::ref_type col_iterator; - typedef typename linalg_traits::storage_type storage_type; - typedef col_major sub_orientation; - typedef typename linalg_traits::index_sorted index_sorted; - static size_type ncols(const this_type &) { return 1; } - static size_type nrows(const this_type &m) { return m.nrows(); } - static const_sub_col_type col(const const_col_iterator &it) { return *it; } - static sub_col_type col(const col_iterator &it) { return *it; } - static const_col_iterator col_begin(const this_type &m) - { return const_col_iterator(m, false); } - static col_iterator col_begin(this_type &m) - { return col_iterator(m, false); } - static const_col_iterator col_end(const this_type &m) - { return const_col_iterator(m, true); } - static col_iterator col_end(this_type &m) - { return col_iterator(m, true); } - static origin_type* origin(this_type &m) { return m.vec.origin; } - static const origin_type* origin(const this_type &m) - { return m.vec.origin; } - static void do_clear(this_type &m) - { clear(col(mat_col_begin(m))); } - static value_type access(const const_col_iterator &itcol, size_type i) - { return itcol.vec[i]; } - static reference access(const col_iterator &itcol, size_type i) - { return itcol.vec[i]; } - }; - - template - std::ostream &operator <<(std::ostream &o, const gen_col_vector& m) - { gmm::write(o,m); return o; } - - /* ******************************************************************** */ - /* col and row vectors */ - /* ******************************************************************** */ - - - template inline - typename select_return< gen_row_vector, gen_row_vector, - const V *>::return_type - row_vector(const V& v) { - return typename select_return< gen_row_vector, - gen_row_vector, const V *>::return_type(linalg_cast(v)); - } - - template inline - typename select_return< gen_row_vector, gen_row_vector, - V *>::return_type - row_vector(V& v) { - return typename select_return< gen_row_vector, - gen_row_vector, V *>::return_type(linalg_cast(v)); - } - - template inline gen_row_vector - const_row_vector(V& v) - { return gen_row_vector(v); } - - - template inline - typename select_return< gen_col_vector, gen_col_vector, - const V *>::return_type - col_vector(const V& v) { - return typename select_return< gen_col_vector, - gen_col_vector, const V *>::return_type(linalg_cast(v)); - } - - template inline - typename select_return< gen_col_vector, gen_col_vector, - V *>::return_type - col_vector(V& v) { - return typename select_return< gen_col_vector, - gen_col_vector, V *>::return_type(linalg_cast(v)); - } - - template inline gen_col_vector - const_col_vector(V& v) - { return gen_col_vector(v); } - - -} - -#endif // GMM_VECTOR_TO_MATRIX_H__ diff --git a/hecl/.gitignore b/hecl/.gitignore deleted file mode 100644 index f7e5c090f..000000000 --- a/hecl/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -DataSpecRegistry.hpp -.DS_Store diff --git a/hecl/ApplicationTools.cmake b/hecl/ApplicationTools.cmake deleted file mode 100644 index 6c9d20d98..000000000 --- a/hecl/ApplicationTools.cmake +++ /dev/null @@ -1,70 +0,0 @@ -include_guard(GLOBAL) - -#file(RELATIVE_PATH REL_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_LIST_DIR}) -#include_directories(${CMAKE_CURRENT_BINARY_DIR}/${REL_PATH}) -# -#unset(HECL_APPLICATION_REPS_TARGETS_LIST CACHE) -#unset(HECL_APPLICATION_REPS_INCLUDES_LIST CACHE) -#unset(HECL_APPLICATION_PIPELINE_REPS_UNIVERSAL CACHE) -#unset(HECL_APPLICATION_PIPELINE_REPS CACHE) -#unset(HECL_APPLICATION_STAGE_REPS CACHE) -# -## add_pipeline_rep(my::fully::qualified::class my_class_header.hpp [UNIVERSAL]) -#function(add_pipeline_rep name header) -# if(IS_ABSOLUTE ${header}) -# set(theHeader ${header}) -# else() -# set(theHeader ${CMAKE_CURRENT_SOURCE_DIR}/${header}) -# endif() -# if (NOT ${theHeader} IN_LIST HECL_APPLICATION_REPS_INCLUDES_LIST) -# set(HECL_APPLICATION_REPS_INCLUDES_LIST "${HECL_APPLICATION_REPS_INCLUDES_LIST};${theHeader}" CACHE INTERNAL "") -# endif() -# if ("${ARGV2}" STREQUAL "UNIVERSAL") -# set(HECL_APPLICATION_PIPELINE_REPS_UNIVERSAL "${HECL_APPLICATION_PIPELINE_REPS_UNIVERSAL};${name}" CACHE INTERNAL "") -# else() -# set(HECL_APPLICATION_PIPELINE_REPS "${HECL_APPLICATION_PIPELINE_REPS};${name}" CACHE INTERNAL "") -# endif() -#endfunction() -# -## add_stage_rep(my::fully::qualified::class my_class_header.hpp) -#function(add_stage_rep name header) -# if(IS_ABSOLUTE ${header}) -# set(theHeader ${header}) -# else() -# set(theHeader ${CMAKE_CURRENT_SOURCE_DIR}/${header}) -# endif() -# if (NOT ${theHeader} IN_LIST HECL_APPLICATION_REPS_INCLUDES_LIST) -# set(HECL_APPLICATION_REPS_INCLUDES_LIST "${HECL_APPLICATION_REPS_INCLUDES_LIST};${theHeader}" CACHE INTERNAL "") -# endif() -# set(HECL_APPLICATION_STAGE_REPS "${HECL_APPLICATION_STAGE_REPS};${name}" CACHE INTERNAL "") -#endfunction() -# -#function(add_shader_target target) -# if (NOT ${target} IN_LIST HECL_APPLICATION_REPS_TARGETS_LIST) -# set(HECL_APPLICATION_REPS_TARGETS_LIST "${HECL_APPLICATION_REPS_TARGETS_LIST};${target}" CACHE INTERNAL "") -# endif() -#endfunction() -# -#function(add_shader file) -# get_filename_component(name ${file} NAME) -# get_filename_component(dir ${file} DIRECTORY) -# shaderc(${CMAKE_CURRENT_BINARY_DIR}/${dir}/shader_${name} ${file}.shader) -# add_stage_rep(shader_${name} ${CMAKE_CURRENT_BINARY_DIR}/${dir}/shader_${name}.hpp) -# add_pipeline_rep(shader_${name} ${CMAKE_CURRENT_BINARY_DIR}/${dir}/shader_${name}.hpp UNIVERSAL) -# add_library(shader_${name} ${CMAKE_CURRENT_BINARY_DIR}/${dir}/shader_${name}.hpp ${CMAKE_CURRENT_BINARY_DIR}/${dir}/shader_${name}.cpp) -# add_shader_target(shader_${name}) -#endfunction() -# -#function(add_special_shader name) -# add_stage_rep(${name} ${name}.hpp) -# add_pipeline_rep(${name} ${name}.hpp UNIVERSAL) -# add_library(${name} ${name}.hpp ${ARGN}) -# add_shader_target(${name}) -#endfunction() - -include(ExternalProject) -ExternalProject_Add(bintoc - SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/bintoc" - CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH= - INSTALL_COMMAND ${CMAKE_COMMAND} --build . --config Release --target install) -include(${CMAKE_CURRENT_LIST_DIR}/bintoc/bintocHelpers.cmake) diff --git a/hecl/CMakeLists.txt b/hecl/CMakeLists.txt deleted file mode 100644 index bcd542638..000000000 --- a/hecl/CMakeLists.txt +++ /dev/null @@ -1,66 +0,0 @@ -if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) -cmake_minimum_required(VERSION 3.10 FATAL_ERROR) # because of c++17 -project(hecl) - -if(MSVC) - add_compile_options( - # Disable exceptions - $<$:/EHsc> - /wd4267 /wd4244 - ) - add_compile_definitions(UNICODE=1 _UNICODE=1 _CRT_SECURE_NO_WARNINGS=1) -else() - set(CMAKE_CXX_STANDARD 20) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - add_compile_options( - # Disable exceptions - $<$:-fno-exceptions> - -Wno-multichar - ) -endif() -endif() - -include(ApplicationTools.cmake) - -configure_file(DataSpecRegistry.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/DataSpecRegistry.hpp @ONLY) - -unset(HECL_APPLICATION_REPS_INCLUDES_LOCAL) -foreach(theHeader ${HECL_APPLICATION_REPS_INCLUDES_LIST}) - set(HECL_APPLICATION_REPS_INCLUDES_LOCAL "${HECL_APPLICATION_REPS_INCLUDES_LOCAL}#include \"${theHeader}\"\n") -endforeach() -unset(HECL_APPLICATION_PIPELINE_REPS_UNIVERSAL_LOCAL) -foreach(name ${HECL_APPLICATION_PIPELINE_REPS_UNIVERSAL}) - set(HECL_APPLICATION_PIPELINE_REPS_UNIVERSAL_LOCAL "${HECL_APPLICATION_PIPELINE_REPS_UNIVERSAL_LOCAL}UNIVERSAL_PIPELINES_${name} \\\n") -endforeach() -unset(HECL_APPLICATION_PIPELINE_REPS_OPENGL_LOCAL) -unset(HECL_APPLICATION_PIPELINE_REPS_VULKAN_LOCAL) -unset(HECL_APPLICATION_PIPELINE_REPS_D3D11_LOCAL) -unset(HECL_APPLICATION_PIPELINE_REPS_METAL_LOCAL) -unset(HECL_APPLICATION_PIPELINE_REPS_NX_LOCAL) -foreach(name ${HECL_APPLICATION_PIPELINE_REPS}) - set(HECL_APPLICATION_PIPELINE_REPS_OPENGL_LOCAL "${HECL_APPLICATION_PIPELINE_REPS_OPENGL_LOCAL}OPENGL_PIPELINES_${name} \\\n") - set(HECL_APPLICATION_PIPELINE_REPS_VULKAN_LOCAL "${HECL_APPLICATION_PIPELINE_REPS_VULKAN_LOCAL}VULKAN_PIPELINES_${name} \\\n") - set(HECL_APPLICATION_PIPELINE_REPS_D3D11_LOCAL "${HECL_APPLICATION_PIPELINE_REPS_D3D11_LOCAL}D3D11_PIPELINES_${name} \\\n") - set(HECL_APPLICATION_PIPELINE_REPS_METAL_LOCAL "${HECL_APPLICATION_PIPELINE_REPS_METAL_LOCAL}METAL_PIPELINES_${name} \\\n") - set(HECL_APPLICATION_PIPELINE_REPS_NX_LOCAL "${HECL_APPLICATION_PIPELINE_REPS_NX_LOCAL}NX_PIPELINES_${name} \\\n") -endforeach() - -unset(HECL_APPLICATION_STAGE_REPS_LOCAL) -foreach(name ${HECL_APPLICATION_STAGE_REPS}) - set(HECL_APPLICATION_STAGE_REPS_LOCAL "${HECL_APPLICATION_STAGE_REPS_LOCAL}STAGES_${name}(P, S) \\\n") -endforeach() - -configure_file(include/hecl/ApplicationReps.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/ApplicationReps.hpp @ONLY) - -if(NOT TARGET atdna) - # Import native atdna if cross-compiling - find_package(atdna REQUIRED) - if(NOT TARGET atdna) - message(FATAL_ERROR "atdna required for building hecl; please verify LLVM installation") - endif() -endif() - -add_subdirectory(lib) -add_subdirectory(blender) -add_subdirectory(driver) -install(DIRECTORY include/hecl DESTINATION include/hecl) diff --git a/hecl/DataSpecRegistry.hpp.in b/hecl/DataSpecRegistry.hpp.in deleted file mode 100644 index 9d485954c..000000000 --- a/hecl/DataSpecRegistry.hpp.in +++ /dev/null @@ -1,21 +0,0 @@ -/* Include this file once in the main translation unit of any executable file - * using HECL's database functionality (see driver/main.cpp) - */ -#ifdef DATA_SPEC_REGISTRY_HPP -#error DataSpecRegistry.hpp may only be included once -#endif -#define DATA_SPEC_REGISTRY_HPP - -#include "hecl/Database.hpp" - -namespace hecl::Database { -/* Centralized registry for DataSpec lookup */ -std::vector DATA_SPEC_REGISTRY; -} - -@HECL_DATASPEC_DECLS@ - -/* Please Call Me! */ -void HECLRegisterDataSpecs() { -@HECL_DATASPEC_PUSHES@ -} diff --git a/hecl/Doxyfile b/hecl/Doxyfile deleted file mode 100644 index edf7d6418..000000000 --- a/hecl/Doxyfile +++ /dev/null @@ -1,2362 +0,0 @@ -# Doxyfile 1.8.9.1 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed in -# front of the TAG it is preceding. -# -# All text after a single hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists, items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all text -# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv -# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv -# for the list of possible encodings. -# The default value is: UTF-8. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by -# double-quotes, unless you are using Doxywizard) that should identify the -# project for which the documentation is generated. This name is used in the -# title of most generated pages and in a few other places. -# The default value is: My Project. - -PROJECT_NAME = "hecl" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. This -# could be handy for archiving the generated documentation or if some version -# control system is used. - -PROJECT_NUMBER = - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer a -# quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = "High-Level Extensible Combiner Language and Resource Database" - -# With the PROJECT_LOGO tag one can specify a logo or an icon that is included -# in the documentation. The maximum height of the logo should not exceed 55 -# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy -# the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = "doc" - -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where -# putting all generated files in the same directory would otherwise causes -# performance problems for the file system. -# The default value is: NO. - -CREATE_SUBDIRS = NO - -# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII -# characters to appear in the names of generated files. If set to NO, non-ASCII -# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode -# U+3044. -# The default value is: NO. - -ALLOW_UNICODE_NAMES = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. -# The default value is: English. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member -# descriptions after the members that are listed in the file and class -# documentation (similar to Javadoc). Set to NO to disable this. -# The default value is: YES. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief -# description of a member or function before the detailed description -# -# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. -# The default value is: YES. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator that is -# used to form the text in various listings. Each string in this list, if found -# as the leading text of the brief description, will be stripped from the text -# and the result, after processing the whole list, is used as the annotated -# text. Otherwise, the brief description is used as-is. If left blank, the -# following values are used ($name is automatically replaced with the name of -# the entity):The $name class, The $name widget, The $name file, is, provides, -# specifies, contains, represents, a, an and the. - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief -# description. -# The default value is: NO. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. -# The default value is: NO. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path -# before files name in the file list and in the header files. If set to NO the -# shortest path that makes the file name unique will be used -# The default value is: YES. - -FULL_PATH_NAMES = YES - -# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. -# Stripping is only done if one of the specified strings matches the left-hand -# part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to -# strip. -# -# Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. -# This tag requires that the tag FULL_PATH_NAMES is set to YES. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the -# path mentioned in the documentation of a class, which tells the reader which -# header file to include in order to use a class. If left blank only the name of -# the header file containing the class definition is used. Otherwise one should -# specify the list of include paths that are normally passed to the compiler -# using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but -# less readable) file names. This can be useful is your file systems doesn't -# support long names like on DOS, Mac, or CD-ROM. -# The default value is: NO. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the -# first line (until the first dot) of a Javadoc-style comment as the brief -# description. If set to NO, the Javadoc-style will behave just like regular Qt- -# style comments (thus requiring an explicit @brief command for a brief -# description.) -# The default value is: NO. - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) -# The default value is: NO. - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a -# multi-line C++ special comment block (i.e. a block of //! or /// comments) as -# a brief description. This used to be the default behavior. The new default is -# to treat a multi-line C++ comment block as a detailed description. Set this -# tag to YES if you prefer the old behavior instead. -# -# Note that setting this tag to YES also means that rational rose comments are -# not recognized any more. -# The default value is: NO. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new -# page for each member. If set to NO, the documentation of a member will be part -# of the file/class/namespace that contains it. -# The default value is: NO. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen -# uses this value to replace tabs by spaces in code fragments. -# Minimum value: 1, maximum value: 16, default value: 4. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that act as commands in -# the documentation. An alias has the form: -# name=value -# For example adding -# "sideeffect=@par Side Effects:\n" -# will allow you to put the command \sideeffect (or @sideeffect) in the -# documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines. - -ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding "class=itcl::class" -# will allow you to use the command class in the itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. For -# instance, some of the names that are used will be different. The list of all -# members will be omitted, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or -# Python sources only. Doxygen will then generate output that is more tailored -# for that language. For instance, namespaces will be presented as packages, -# qualified scopes will look different, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources. Doxygen will then generate output that is tailored for Fortran. -# The default value is: NO. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for VHDL. -# The default value is: NO. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: -# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: -# Fortran. In the later case the parser tries to guess whether the code is fixed -# or free formatted code, this is the default for Fortran type files), VHDL. For -# instance to make doxygen treat .inc files as Fortran files (default is PHP), -# and .f files as C (default is Fortran), use: inc=Fortran f=C. -# -# Note: For files without extension you can use no_extension as a placeholder. -# -# Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. -# The default value is: NO. - -BUILTIN_STL_SUPPORT = YES - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. -# The default value is: NO. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. -# The default value is: NO. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. -# This will only work if the methods are indeed getting or setting a simple -# type. If this is not the case, or you want to show the methods anyway, you -# should set this option to NO. -# The default value is: YES. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. -# The default value is: NO. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES to allow class member groups of the same type -# (for instance a group of public functions) to be put as a subgroup of that -# type (e.g. under the Public Functions section). Set it to NO to prevent -# subgrouping. Alternatively, this can be done per class using the -# \nosubgrouping command. -# The default value is: YES. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions -# are shown inside the group in which they are included (e.g. using \ingroup) -# instead of on a separate page (for HTML and Man pages) or section (for LaTeX -# and RTF). -# -# Note that this feature does not work in combination with -# SEPARATE_MEMBER_PAGES. -# The default value is: NO. - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions -# with only public data fields or simple typedef fields will be shown inline in -# the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO, structs, classes, and unions are shown on a separate page (for HTML and -# Man pages) or section (for LaTeX and RTF). -# The default value is: NO. - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or -# enum is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically be -# useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. -# The default value is: NO. - -TYPEDEF_HIDES_STRUCT = NO - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can be -# an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The -# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range -# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest -# the optimal cache size from a speed point of view. -# Minimum value: 0, maximum value: 9, default value: 0. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will -# be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal -# scope will be included in the documentation. -# The default value is: NO. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO, -# only classes defined in header files are included. Does not have any effect -# for Java sources. -# The default value is: YES. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. If set to YES, local methods, -# which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO, only methods in the interface are -# included. -# The default value is: NO. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base name of -# the file that contains the anonymous namespace. By default anonymous namespace -# are hidden. -# The default value is: NO. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. -# The default value is: NO. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO, these -# blocks will be appended to the function's detailed documentation block. -# The default value is: NO. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation that is typed after a -# \internal command is included. If the tag is set to NO then the documentation -# will be excluded. Set it to YES to include the internal documentation. -# The default value is: NO. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. -# The default value is: system dependent. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES, the -# scope will be hidden. -# The default value is: NO. - -HIDE_SCOPE_NAMES = NO - -# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will -# append additional text to a page's title, such as Class Reference. If set to -# YES the compound reference will be hidden. -# The default value is: NO. - -HIDE_COMPOUND_REFERENCE= NO - -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of -# the files that are included by a file in the documentation of that file. -# The default value is: YES. - -SHOW_INCLUDE_FILES = YES - -# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each -# grouped member an include statement to the documentation, telling the reader -# which file to include in order to use the member. -# The default value is: NO. - -SHOW_GROUPED_MEMB_INC = NO - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include -# files with double quotes in the documentation rather than with sharp brackets. -# The default value is: NO. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the -# documentation for inline members. -# The default value is: YES. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the -# (detailed) documentation of file and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. -# The default value is: YES. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief -# descriptions of file, namespace and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. Note that -# this will also influence the order of the classes in the class list. -# The default value is: NO. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the -# (brief and detailed) documentation of class members so that constructors and -# destructors are listed first. If set to NO the constructors will appear in the -# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. -# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief -# member documentation. -# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting -# detailed member documentation. -# The default value is: NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy -# of group names into alphabetical order. If set to NO the group names will -# appear in their defined order. -# The default value is: NO. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by -# fully-qualified names, including namespaces. If set to NO, the class list will -# be sorted only by class name, not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the alphabetical -# list. -# The default value is: NO. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper -# type resolution of all parameters of a function it will reject a match between -# the prototype and the implementation of a member function even if there is -# only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still -# accept a match between prototype and implementation in such cases. -# The default value is: NO. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo -# list. This list is created by putting \todo commands in the documentation. -# The default value is: YES. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test -# list. This list is created by putting \test commands in the documentation. -# The default value is: YES. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug -# list. This list is created by putting \bug commands in the documentation. -# The default value is: YES. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) -# the deprecated list. This list is created by putting \deprecated commands in -# the documentation. -# The default value is: YES. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional documentation -# sections, marked by \if ... \endif and \cond -# ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the -# initial value of a variable or macro / define can have for it to appear in the -# documentation. If the initializer consists of more lines than specified here -# it will be hidden. Use a value of 0 to hide initializers completely. The -# appearance of the value of individual variables and macros / defines can be -# controlled using \showinitializer or \hideinitializer command in the -# documentation regardless of this setting. -# Minimum value: 0, maximum value: 10000, default value: 30. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES, the -# list will mention the files that were used to generate the documentation. -# The default value is: YES. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This -# will remove the Files entry from the Quick Index and from the Folder Tree View -# (if specified). -# The default value is: YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces -# page. This will remove the Namespaces entry from the Quick Index and from the -# Folder Tree View (if specified). -# The default value is: YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command command input-file, where command is the value of the -# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file -# version. For an example see the documentation. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can -# optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. -# -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE -# tag is left empty. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files containing -# the reference definitions. This must be a list of .bib files. The .bib -# extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. -# For LaTeX the style of the bibliography can be controlled using -# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. See also \cite for info how to create references. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the -# messages are off. -# The default value is: NO. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES -# this implies that the warnings are on. -# -# Tip: Turn warnings on while writing the documentation. -# The default value is: YES. - -WARNINGS = YES - -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate -# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag -# will automatically be disabled. -# The default value is: YES. - -WARN_IF_UNDOCUMENTED = YES - -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. -# The default value is: YES. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that -# are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. -# The default value is: NO. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that doxygen -# can produce. The string should contain the $file, $line, and $text tags, which -# will be replaced by the file and line number from which the warning originated -# and the warning text. Optionally the format may contain $version, which will -# be replaced by the version of the file (if it could be obtained via -# FILE_VERSION_FILTER) -# The default value is: $file:$line: $text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning and error -# messages should be written. If left blank the output is written to standard -# error (stderr). - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. -# Note: If this tag is empty the current directory is searched. - -INPUT = include - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: http://www.gnu.org/software/libiconv) for the list of -# possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank the -# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, -# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, -# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, -# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, -# *.qsf, *.as and *.js. - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or directories -# that contain example code fragments that are included (see the \include -# command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank all -# files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude commands -# irrespective of the value of the RECURSIVE tag. -# The default value is: NO. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or directories -# that contain images that are to be included in the documentation (see the -# \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command: -# -# -# -# where is the value of the INPUT_FILTER tag, and is the -# name of an input file. Doxygen will then use the output that the filter -# program writes to standard output. If FILTER_PATTERNS is specified, this tag -# will be ignored. -# -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: pattern=filter -# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how -# filters are used. If the FILTER_PATTERNS tag is empty or if none of the -# patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will also be used to filter the input files that are used for -# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). -# The default value is: NO. - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and -# it is also possible to disable source filtering for a specific pattern using -# *.ext= (so without naming a filter). -# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = - -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will be -# generated. Documented entities will be cross-referenced with these sources. -# -# Note: To get rid of all source code in the generated output, make sure that -# also VERBATIM_HEADERS is set to NO. -# The default value is: NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. -# The default value is: NO. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any -# special comment blocks from generated source code fragments. Normal C, C++ and -# Fortran comments will always remain visible. -# The default value is: YES. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# function all documented functions referencing it will be listed. -# The default value is: NO. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES then for each documented function -# all documented entities called/used by that function will be listed. -# The default value is: NO. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES then the hyperlinks from functions in REFERENCES_RELATION and -# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will -# link to the documentation. -# The default value is: YES. - -REFERENCES_LINK_SOURCE = YES - -# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the -# source code will show a tooltip with additional information such as prototype, -# brief description and links to the definition and documentation. Since this -# will make the HTML file larger and loading of large files a bit slower, you -# can opt to disable this feature. -# The default value is: YES. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -SOURCE_TOOLTIPS = YES - -# If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in -# source browser. The htags tool is part of GNU's global source tagging system -# (see http://www.gnu.org/software/global/global.html). You will need version -# 4.8.6 or higher. -# -# To use it do the following: -# - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the config file -# - Make sure the INPUT points to the root of the source tree -# - Run doxygen as normal -# -# Doxygen will invoke htags (and that will in turn invoke gtags), so these -# tools must be available from the command line (i.e. in the search path). -# -# The result: instead of the source browser generated by doxygen, the links to -# source code will now point to the output of htags. -# The default value is: NO. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a -# verbatim copy of the header file for each class for which an include is -# specified. Set to NO to disable this. -# See also: Section \class. -# The default value is: YES. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all -# compounds will be generated. Enable this if the project contains a lot of -# classes, structs, unions or interfaces. -# The default value is: YES. - -ALPHABETICAL_INDEX = YES - -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each -# generated HTML page (for example: .htm, .php, .asp). -# The default value is: .html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a -# standard header. -# -# To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. -# the setting GENERATE_TREEVIEW). It is highly recommended to start with a -# default header using -# doxygen -w html new_header.html new_footer.html new_stylesheet.css -# YourConfigFile -# and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally -# uses. -# Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description -# of the possible markers and block names see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard -# footer. See HTML_HEADER for more information on how to generate a default -# footer and what special commands can be used inside the footer. See also -# section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style -# sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. -# See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. -# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as -# it is more robust and this tag (HTML_STYLESHEET) will in the future become -# obsolete. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. -# This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefore more robust against future updates. -# Doxygen will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that the -# files will be copied as-is; there are no commands or markers available. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# http://en.wikipedia.org/wiki/Hue for more information. For instance the value -# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 -# purple, and 360 is red again. -# Minimum value: 0, maximum value: 359, default value: 220. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A -# value of 255 will produce the most vivid colors. -# Minimum value: 0, maximum value: 255, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the -# luminance component of the colors in the HTML output. Values below 100 -# gradually make the output lighter, whereas values above 100 make the output -# darker. The value divided by 100 is the actual gamma applied, so 80 represents -# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not -# change the gamma. -# Minimum value: 40, maximum value: 240, default value: 80. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries -# shown in the various tree structured indices initially; the user can expand -# and collapse entries dynamically later on. Doxygen will expand the tree to -# such a level that at most the specified number of entries are visible (unless -# a fully collapsed tree already exceeds this amount). So setting the number of -# entries 1 will produce a full collapsed tree by default. 0 is a special value -# representing an infinite number of entries and will result in a full expanded -# tree by default. -# Minimum value: 0, maximum value: 9999, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files will be -# generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: http://developer.apple.com/tools/xcode/), introduced with -# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_DOCSET = NO - -# This tag determines the name of the docset feed. A documentation feed provides -# an umbrella under which multiple documentation sets from a single provider -# (such as a company or product suite) can be grouped. -# The default value is: Doxygen generated docs. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# This tag specifies a string that should uniquely identify the documentation -# set bundle. This should be a reverse domain-name style string, e.g. -# com.mycompany.MyDocSet. Doxygen will append .docset to the name. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. -# The default value is: org.doxygen.Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. -# The default value is: Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three -# additional HTML index files: index.hhp, index.hhc, and index.hhk. The -# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. -# -# The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML -# files are now used as the Windows 98 help format, and will replace the old -# Windows help format (.hlp) on all Windows platforms in the future. Compressed -# HTML files also contain an index, a table of contents, and you can search for -# words in the documentation. The HTML workshop also contains a viewer for -# compressed HTML files. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_HTMLHELP = NO - -# The CHM_FILE tag can be used to specify the file name of the resulting .chm -# file. You can add a path in front of the file if the result should not be -# written to the html output directory. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_FILE = - -# The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler (hhc.exe). If non-empty, -# doxygen will try to run the HTML help compiler on the generated index.hhp. -# The file has to be specified with full path. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -HHC_LOCATION = - -# The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -GENERATE_CHI = NO - -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) -# and project file content. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_INDEX_ENCODING = - -# The BINARY_TOC flag controls whether a binary table of contents is generated -# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it -# enables the Previous and Next buttons. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members to -# the table of contents of the HTML help documentation and to the tree view. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that -# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help -# (.qch) of the generated HTML documentation. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify -# the file name of the resulting .qch file. The path specified is relative to -# the HTML output folder. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help -# Project output. For more information please see Qt Help Project / Namespace -# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt -# Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- -# folders). -# The default value is: doc. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_VIRTUAL_FOLDER = doc - -# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom -# filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_SECT_FILTER_ATTRS = - -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be -# generated, together with the HTML files, they form an Eclipse help plugin. To -# install this plugin and make it available under the help contents menu in -# Eclipse, the contents of the directory containing the HTML and XML files needs -# to be copied into the plugins directory of eclipse. The name of the directory -# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. -# After copying Eclipse needs to be restarted before the help appears. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the Eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have this -# name. Each documentation set should have its own identifier. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# If you want full control over the layout of the generated HTML pages it might -# be necessary to disable the index and replace it with your own. The -# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top -# of each HTML page. A value of NO enables the index and the value YES disables -# it. Since the tabs in the index contain the same information as the navigation -# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. If the tag -# value is set to YES, a side panel will be generated containing a tree-like -# index structure (just like the one that is generated for HTML Help). For this -# to work a browser that supports JavaScript, DHTML, CSS and frames is required -# (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_TREEVIEW = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. -# -# Note that a value of 0 will completely suppress the enum values from appearing -# in the overview section. -# Minimum value: 0, maximum value: 20, default value: 4. -# This tag requires that the tag GENERATE_HTML is set to YES. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used -# to set the initial width (in pixels) of the frame in which the tree is shown. -# Minimum value: 0, maximum value: 1500, default value: 250. -# This tag requires that the tag GENERATE_HTML is set to YES. - -TREEVIEW_WIDTH = 250 - -# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to -# external symbols imported via tag files in a separate window. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of LaTeX formulas included as images in -# the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML -# output directory to force them to be regenerated. -# Minimum value: 8, maximum value: 50, default value: 10. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# http://www.mathjax.org) which uses client side Javascript for the rendering -# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX -# installed or if you want to formulas look prettier in the HTML output. When -# enabled you may also need to install MathJax separately and configure the path -# to it using the MATHJAX_RELPATH option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. -# Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. -# The default value is: HTML-CSS. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the HTML -# output directory using the MATHJAX_RELPATH option. The destination directory -# should contain the MathJax.js script. For instance, if the mathjax directory -# is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax -# Content Delivery Network so you can quickly see the result without installing -# MathJax. However, it is strongly recommended to install a local copy of -# MathJax from http://www.mathjax.org before deployment. -# The default value is: http://cdn.mathjax.org/mathjax/latest. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax -# extension names that should be enabled during MathJax rendering. For example -# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces -# of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an -# example see the documentation. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and -# should work on any modern browser. Note that when using HTML help -# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) -# there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then -# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to -# search using the keyboard; to jump to the search box use + S -# (what the is depends on the OS and browser, but it is typically -# , /%QDir::AllDirs|%QDir::NoDotAndDotDot when searching for dirs - * and with QDir::Files when searching for files. - * - * @param fileCompressed path to the resulting archive - * @param dir path to the directory being compressed - * @param recursive if true, then the subdirectories are packed as well - * @param filters what to pack, filters are applied both when searching - * for subdirs (if packing recursively) and when looking for files to pack - * @return true on success, false otherwise - */ - static bool compressDir(QString fileCompressed, QString dir, - bool recursive, QDir::Filters filters); - -public: - /// Extract a single file. - /** - \param fileCompressed The name of the archive. - \param fileName The file to extract. - \param fileDest The destination file, assumed to be identical to - \a file if left empty. - \return The list of the full paths of the files extracted, empty on failure. - */ - static QString extractFile(QString fileCompressed, QString fileName, QString fileDest = QString()); - /// Extract a list of files. - /** - \param fileCompressed The name of the archive. - \param files The file list to extract. - \param dir The directory to put the files to, the current - directory if left empty. - \return The list of the full paths of the files extracted, empty on failure. - */ - static QStringList extractFiles(QString fileCompressed, QStringList files, QString dir = QString()); - /// Extract a whole archive. - /** - \param fileCompressed The name of the archive. - \param dir The directory to extract to, the current directory if - left empty. - \return The list of the full paths of the files extracted, empty on failure. - */ - static QStringList extractDir(QString fileCompressed, QString dir = QString()); - /// Extract a whole archive. - /** - \param fileCompressed The name of the archive. - \param fileNameCodec The codec to use for file names. - \param dir The directory to extract to, the current directory if - left empty. - \return The list of the full paths of the files extracted, empty on failure. - */ - static QStringList extractDir(QString fileCompressed, QTextCodec* fileNameCodec, QString dir = QString()); - /// Get the file list. - /** - \return The list of the files in the archive, or, more precisely, the - list of the entries, including both files and directories if they - are present separately. - */ - static QStringList getFileList(QString fileCompressed); - /// Extract a single file. - /** - \param ioDevice pointer to device with compressed data. - \param fileName The file to extract. - \param fileDest The destination file, assumed to be identical to - \a file if left empty. - \return The list of the full paths of the files extracted, empty on failure. - */ - static QString extractFile(QIODevice *ioDevice, QString fileName, QString fileDest = QString()); - /// Extract a list of files. - /** - \param ioDevice pointer to device with compressed data. - \param files The file list to extract. - \param dir The directory to put the files to, the current - directory if left empty. - \return The list of the full paths of the files extracted, empty on failure. - */ - static QStringList extractFiles(QIODevice *ioDevice, QStringList files, QString dir = QString()); - /// Extract a whole archive. - /** - \param ioDevice pointer to device with compressed data. - \param dir The directory to extract to, the current directory if - left empty. - \return The list of the full paths of the files extracted, empty on failure. - */ - static QStringList extractDir(QIODevice *ioDevice, QString dir = QString()); - /// Extract a whole archive. - /** - \param ioDevice pointer to device with compressed data. - \param fileNameCodec The codec to use for file names. - \param dir The directory to extract to, the current directory if - left empty. - \return The list of the full paths of the files extracted, empty on failure. - */ - static QStringList extractDir(QIODevice* ioDevice, QTextCodec* fileNameCodec, QString dir = QString()); - /// Get the file list. - /** - \return The list of the files in the archive, or, more precisely, the - list of the entries, including both files and directories if they - are present separately. - */ - static QStringList getFileList(QIODevice *ioDevice); -}; - -#endif /* JLCOMPRESSFOLDER_H_ */ diff --git a/metaforce-gui/quazip/quazip/QuaZipConfig.cmake.in b/metaforce-gui/quazip/quazip/QuaZipConfig.cmake.in deleted file mode 100644 index 1988b4d9e..000000000 --- a/metaforce-gui/quazip/quazip/QuaZipConfig.cmake.in +++ /dev/null @@ -1,20 +0,0 @@ -@PACKAGE_INIT@ - -include(CMakeFindDependencyMacro) - -find_dependency(ZLIB REQUIRED) - -include("${CMAKE_CURRENT_LIST_DIR}/@QUAZIP_EXPORT_SET@.cmake") - -if(@QUAZIP_QT_MAJOR_VERSION@ EQUAL 6) - find_dependency(Qt6 REQUIRED COMPONENTS Core Core5Compat) -elseif(@QUAZIP_QT_MAJOR_VERSION@ EQUAL 5) - find_dependency(Qt5 REQUIRED COMPONENTS Core) -elseif(@QUAZIP_QT_MAJOR_VERSION@ EQUAL 4) - find_dependency(Qt4 4.5.0 REQUIRED COMPONENTS QtCore) -else() - message(FATAL_ERROR "Qt version QUAZIP_QT_MAJOR_VERSION=@QUAZIP_QT_MAJOR_VERSION@ is unsupported") -endif() -set_target_properties(QuaZip::QuaZip PROPERTIES IMPORTED_GLOBAL TRUE) - -check_required_components(@QUAZIP_PACKAGE_NAME@) diff --git a/metaforce-gui/quazip/quazip/doc/faq.dox b/metaforce-gui/quazip/quazip/doc/faq.dox deleted file mode 100644 index 484104763..000000000 --- a/metaforce-gui/quazip/quazip/doc/faq.dox +++ /dev/null @@ -1,93 +0,0 @@ -/** -\page faq %QuaZip FAQ - - - -\anchor faq-QuaZip-name Q. QuaZIP, %QuaZip, Quazip, quazip... what's with these names? - -In QuaZIP 0.x, there was this rule that QuaZIP is the library name, while %QuaZip is -a class in this library. Since %QuaZip 1.0, it's now obsolete, and both are %QuaZip -now to avoid confusion. The lowercase version is used in places where lowercase -is the convention, such as some file names. Quazip is not used anywhere except maybe -by mistake. - -One reason using QuaZIP actually made some sense is that Doxygen (used to generate -this documentation) is very insistent on linking every mention of a class name -to its documentation, meaning every %QuaZip became QuaZip (linked to the QuaZip class docs). -This can be avoided by proper escaping, but it's pretty annoying to do it every time. -Too bad I realized it \em after I'd renamed QuaZIP to %QuaZip, so if you see -too many links to the QuaZip class in places where they don't belong, well... you now -know the reason. - -\anchor faq-non-QIODevice Q. Is there any way to use QuaZipFile in Qt -where you are supposed to use normal (non-zipped) file, but not -through QIODevice API? - -A. Usually not. For example, if you are passing file name to some -database driver (like SQLite), Qt usually just passes this name down -to the 3rd-party library, which is usually does not know anything -about QIODevice and therefore there is no way to pass QuaZipFile as -a normal file. However, if we are talking about some place where you -pass file name, and then internally use QFile to open it, then it is -a good idea to make an overloaded method, which accepts a QIODevice -pointer. Then you would be able to pass QuaZipFile as well as many -other nice things such as QBuffer or QProcess. Of course, that's only -possible if you have control over the sources of the particular class. - -\anchor faq-zip64 Q. Can %QuaZip handle files larger than 4GB? What -about zip64 standard? - -A. Starting with version 0.6, %QuaZip uses Minizip 1.1 with zip64 -support which should handle large files perfectly. The zip64 support -in Minizip looks like it's not 100% conforming to the standard, but -3rd party tools seem to have no problem with the resulting archives. - -\anchor faq-seekable Q. Can %QuaZip write archives to a sequential QIODevice like QTcpSocket? - -A. Writing is possible since %QuaZip v0.7. It's only possible in -mdCreate mode, no mdAppend support. Reading is not supported either. - -\anchor faq-Minizip-update Q. Can I use another version of Minizip in %QuaZip, not the bundled one? - -A. No, unfortunately not. To support reading/writing ZIP archives from/to QIODevice objects, -some modifications were needed to Minizip. Now that there is a Minizip fork on GitHub, it is -theoretically possible to backport these modifications into Minizip in a backward-compatible -manner to ensure seamless integration with %QuaZip, but it hasn't been done yet, and there -are no short-term plans, only a long-term goal. - -\anchor faq-thread-safe Q. Is %QuaZip thread safe? Reentrant? - -A. This is actually two questions: is Minizip thread safe or reentrant, and is %QuaZip thread safe or reentrant? - -The answer is that Minizip and %QuaZip are mostly just regular I/O libraries using some data structures to -store the current I/O state. This means that most of the library is reentrant, but not thread-safe, -as is the usual case with most regular libraries. That is, using different unrelated instances of the same class -is mostly safe. “Unrelated†means that QuaZip / QuaZipFile pairs should be treated as single objects -as they are tightly coupled together (and should have been a single class in the first place). - -Since it's an I/O library, to achieve reentrancy it is required to avoid OS-level conflicts. This -means that concurrent writing to the same ZIP file is impossible, no matter how careful you are -with class instances. Concurrent reading using different instances is possible. - -An attentive reader would probably notice by this point all these “mostly safeâ€, “mostly regular librariesâ€. -This is, of course, about static (global) variables. %QuaZip has just a few, and they are only available -through obviously named static setters, like QuaZip::setDefaultOsCode() and QuaZip::setDefaultFileNameCodec(). -If you need to use these, be sure to call them before starting any other threads. - -As far as Minizip goes, it is mostly safe I/O library, but the crypting part contains some code -that is definitely not thread safe, namely srand() and rand() (not even rand_r()) calls. -This code is used for encryption only, so decryption is safe. - -*/ diff --git a/metaforce-gui/quazip/quazip/doc/index.dox b/metaforce-gui/quazip/quazip/doc/index.dox deleted file mode 100644 index cbbd55ff9..000000000 --- a/metaforce-gui/quazip/quazip/doc/index.dox +++ /dev/null @@ -1,201 +0,0 @@ -/** -\mainpage %QuaZip - %Qt/C++ wrapper for Minizip - -\section overview Overview - -Minizip, or -Gilles Vollant's ZIP/UNZIP package is a simple C library -for creating, appending and reading ZIP archives. - -%Qt is a very powerful cross-platform C++ -library with a lot of useful modules and classes. With %Qt, you can -create rich GUIs, perform networking activities, accessing databases -and much much more. If Java is “write once, run everywhereâ€, %Qt -is “write once, compile everywhere†which is not that bad either. - -One thing %Qt can't do out-of-the-box is write and read ZIP archives. -Of course, you can do it with Minizip, but Minizip has its own -interface which isn't exactly compatible with %Qt. Namely, in %Qt -there is an abstract class called QIODevice, which -is %Qt-speak for “input/output streamâ€. There are a lot of classes -that accept QIODevice to write some useful things to it—you could -serialize XML to a QIODevice, for example. Therefore, wouldn't it -be useful if you could open a QIODevice that would write directly -to a file in a ZIP archive? Or read from one? That's exactly where -%QuaZip comes into the picture. - -Technically speaking, %QuaZip is a simple C++ wrapper around Minizip. -Or you could call it an implementation of the Adapter pattern. With -%QuaZip, both ZIP files and files inside ZIP archives can be accessed -with QIODevice API. You can even write ZIP files to a sequential devices -like TCP sockets, although some limitations apply in this case. - -\section download Download QuaZip - -The latest downloads are available from the -GitHub page. -Downloads are in source format. The documentation you're reading -right now can be build with the “doxygen†tool if you have one -installed. Just run it from the project directory and it will -create the “doc†directory for you. If you don't have Doxygen -installed, you can still read offline docs in the “quazip/doc†-subdir and in the header files. Don't confuse those dirs: - -- “doc†in the project's root is where Doxygen \em output is. -- “quazip/doc†is where Doxygen \em input is, the part of it that - doesn't belong to any particular header files. - -Older downloads are available from -%QuaZip project's page at SourceForge.net. - -\section platforms Platforms supported - -%QuaZip 1.1 was tested on: -- %Qt 5.15.0 MinGW 8.1 x32 -- %Qt 5.12.9 MinGW 7.3 x32 -- %Qt 5.9.7 CentOS 7 x64 -- %Qt 4.8.7 CentOS 7 x64 -- %Qt 5.11.0 Astra Linux CE 1.6 x64 - -It should work fine on any platform supported by %Qt 4.8.7 or later. -In theory, even versions as old as %Qt 4.6.2 might work as well, but -aren't guaranteed to. - -Preliminary %Qt 6 support is available as well, but not tested at all. - -\section whats-new What is new in this version of QuaZip? - -See the NEWS.txt file supplied with the distribution. - -\section Dependencies - -Just zlib and %Qt 4/5/6. Sometimes -you can get away with using zlib library bundled into %Qt, but -usually you need at least its headers. - -CMake-wise, you need \c ZLIB::ZLIB and one of the following: -\li \c Qt5::Core -\li \c Qt6::Core and \c Qt6::Core5Compat -\li \c Qt4::QtCore - -To build and run tests, the appropriate Test and Network submodules are needed as well. - -Make sure that you have %Qt installed with all required headers and -utilities (that is, including the 'dev' or 'devel' package on some Linux distros). - -\section building Building, testing and installing - -%QuaZip uses CMake since 1.0. If you used qmake to build it, -you'll have to switch to CMake now, and it's a good thing because -two build systems made everything confusing and inconsistent. CMake -may be confusing, badly designed and lack good tutorials, but -it's \em the build system at the time of the writing. Some Linux -distros are shipped with incredibly outdated CMake versions, -but the good news is, there are official self-contained binary -distributions, so just grab the newest version, unpack it -somewhere, set up PATH (or symlinks) and you're all set. -CMake minimum version 3.15 is required to build %QuaZip 1.0. - -\note Instructions given in this section assume that you are -using some UNIX dialect, but the build process should be very similar -on MinGW x32 too. On other platforms it's essentially the -same process, maybe with some CMake adjustments not specific to -%QuaZip itself. - -To build the library, run: -\verbatim -$ cd /wherever/quazip/source/is/quazip-x.y.z -$ cmake -S . -B wherever/you/want/your/build/to/be -D QUAZIP_QT_MAJOR_VERSION=4, 5 or 6 -$ cmake --build wherever/you/want/your/build/to/be -\endverbatim - -\c QUAZIP_QT_MAJOR_VERSION is just one number, and it defaults to 5, so if building with %Qt 5, it is optional. - -On Windows, it may be required to use -G "MinGW Makefiles" or something like that to convince -CMake that you really want to use, say, MinGW and not Visual Studio, for example. - -To install, run -\verbatim -$ cmake --build wherever/you/want/your/build/to/be --target install -D CMAKE_INSTALL_PREFIX=/wherever/you/want/to/install -\endverbatim - -%QuaZip installs as CMake package QuaZip-QtX, where X is the major -version of %Qt. For example, QuaZip-Qt5. Different major versions of -%QuaZip have different binary names (libquazip1-qt5, for example), -which allows to install them in parallel. - -To reconfigure (for another %Qt version or release/debug, or anything else), just nuke the whole build directory -and repeat everything. - -By default, %QuaZip compiles as a DLL/SO, but respects the standard BUILD_SHARED_LIBS CMake option, adjusting -its imports/exports accordingly. - -Binary compatibility is guaranteed between minor releases starting -with version 1.0, thanks to the Pimpl idiom. That is, the next binary -incompatible version will be 2.x in the worst case. - -\section test Testing - -To test, run: -\verbatim -$ cmake --build wherever/you/want/your/build/to/be --target check -\endverbatim - -Note that tests are not included in the \c all target, so if you want -to build and test with %Qt Creator, add another build step and select -the \c qztest target. Then set up run configuration to launch -the qztest binary. - -On Windows, you need to set its working directory -to the \c quazip subdirectory of the build tree. The default -is the \c qztest directory, which lead to mysterious crashes -because qztest can't find the %QuaZip DLL there. - -On some systems you may need to set PATH, LD_LIBRARY_PATH or -SHLIB_PATH to get “qztest†to actually run and to use the version of %QuaZip you've just built, -especially if you already have some version of %QuaZip installed somewhere. - -If everything went fine, the test suite should report a lot of PASS -messages and the “All tests executed successfully†message. -If something goes wrong, it will provide details and a -warning that some tests failed. - -\section using Using - -See the \ref usage "Usage Page". - -\section contacts Authors and contacts - -This wrapper has been written by Sergei Tachenov. -This is my first open source project, and it's pretty old, but it -works and many people are happily using it, including myself. - -If you have anything to say to me about %QuaZip library, feel free to -do so (read the \ref faq first, though). I can not promise, -though, that I fix all the bugs you report in, add any features you -want, or respond to your critics, or respond to your feedback at all. -I may be busy, I may be tired of working on %QuaZip, I may be even -dead already (you never know...). - -To report bugs or to post ideas about what should be done, use -GitHub. It's an -awesome site, where you can report bugs or register yourself an -account, fork %QuaZip (don't hesitate to do so), create a new branch, -make some changes and issue a -pull -request, which is GitHub's way of offering patches. See CONTRIBUTING.md -file for details. - -Do not use e-mail to report bugs, please. Reporting bugs and problems -with GitHub has that advantage that -it is visible to public, and I can always search for open tickets -that were created long ago. It is highly unlikely that I will search -my mail for that kind of stuff, so if a bug reported by mail isn't -fixed immediately, it will likely be forgotten forever. - -Old bugs may still be available at -SourceForge -for reference. - -Copyright (C) 2005-2020 Sergei Tachenov and contributors -*/ diff --git a/metaforce-gui/quazip/quazip/doc/usage.dox b/metaforce-gui/quazip/quazip/doc/usage.dox deleted file mode 100644 index 8552af70c..000000000 --- a/metaforce-gui/quazip/quazip/doc/usage.dox +++ /dev/null @@ -1,182 +0,0 @@ -/** \page usage Usage - -This page provides general information on %QuaZip usage. See classes -QuaZip and QuaZipFile for the detailed documentation on what can -%QuaZip do and what it can't do. Also, reading comments in the zip.h and -unzip.h files (taken from the original ZIP/UNZIP package) is always a -good idea too. After all, %QuaZip is just a wrapper with a few -convenience extensions and reimplementations. - -\section CMake - -To get started, as it is usual with modern CMake, you just need -something like this in your CMakeLists.txt: - -\verbatim -find_package(QuaZip-Qt5) -target_link_libraries(whatever-your-target-is QuaZip::QuaZip) -\endverbatim - -Or, if you prefer to add %QuaZip sources directly to your project -(e. g. as a Git submodule): -\verbatim -add_subdirectory(quazip) -target_link_libraries(whatever-your-target-is QuaZip::QuaZip) -\endverbatim - -In the latter case, you may want to set BUILD_SHARED_LIBS to NO -to link statically. - -In all cases, if %QuaZip is linked statically, it automatically -defines QUAZIP_STATIC whenever your link to it, which disables -dllimports that would lead to confusing errors (at least on Windows) -otherwise. - -If, for some weird reason, you decide to add %QuaZip sources to your -project directly (skipping CMake), or link it statically and then -link it to your project without CMake, you may need to define -QUAZIP_STATIC manually to avoid problems with dllimports. - -%QuaZip uses SameMajorVersion compatibility mode, so you can have, -say, %QuaZip 1.x and %QuaZip 2.x (in some future, when there is such a thing) -installed in parallel, and then pass the required version to -\c find_package. As long as the major version matches, it will be found. - -\section Flatpak - -%Quazip can be used in Flatpak YAML manifests as such: - -\verbatim -modules: - - name: quazip - buildsystem: cmake-ninja - builddir: true - config-opts: - - -DCMAKE_BUILD_TYPE=MinSizeRel - sources: - - type: archive - url: https://github.com/stachenov/quazip/archive/v1.1.tar.gz - sha256: 54edce9c11371762bd4f0003c2937b5d8806a2752dd9c0fd9085e90792612ad0 - - type: shell - commands: - - sed -i 's|${CMAKE_ROOT}/Modules|share/cmake|' CMakeLists.txt -\endverbatim - -or on older JSON manifests: -\verbatim -"modules": [ - { - "name": "quazip", - "buildsystem": "cmake-ninja", - "builddir": true, - "config-opts": [ - "-DCMAKE_BUILD_TYPE=MinSizeRel" - ], - "sources": [ - { - "type": "archive", - "url": "https://github.com/stachenov/quazip/archive/v1.1.tar.gz", - "sha256": "54edce9c11371762bd4f0003c2937b5d8806a2752dd9c0fd9085e90792612ad0" - }, - { - "type": "shell", - "commands": [ - "sed -i 's|${CMAKE_ROOT}/Modules|share/cmake|' CMakeLists.txt" - ] - } - ] - } - ] -\endverbatim - -\section terminology Terminology - -“%QuaZip†means the whole library or the \c QuaZip class, depending -on the context. - -“ZIP/UNZIP API†or “Minizip†means the original API of the Gilles -Vollant's ZIP/UNZIP package. It was slightly modified to better -integrate with Qt. These modifications are not source or binary -compatible with the official Minizip release, which means you can't -just drop the newer Minizip version into %QuaZip sources and make it -work. - -“ZIPâ€, “ZIP archive†or “ZIP file†means any ZIP archive. Typically -this is a plain file with “.zip†(or “.ZIPâ€) file name suffix, but it -can also be any seekable QIODevice (say, QBuffer, but not -QTcpSocket). - -“A file inside archiveâ€, “a file inside ZIP†or something like that -means file either being read or written from/to some ZIP archive. - -\section API - -The main classes are QuaZip and QuaZipFile, and there's JlCompress -that contains a lot of high-level utility methods (think of it -as the Facade Pattern for the most common uses). - -QuaZip is a class representing ZIP archive, QuaZipFile represents a -file inside archive and subclasses QIODevice as well. One limitation -is that there can be only one instance of QuaZipFile per QuaZip -instance, which kind of makes it confusing why there are two classes -instead of one. This is actually no more than an API design mistake -kept for backwards compatibility. - -\section general-usage General usage - -In general, the process looks like this: - --# Open or create an archive with a QuaZip instance. --# Open or create a file in the archive with a QuaZipFile instance. --# Perform reading or writing. --# Close the QuaZipFile instance. --# Repeat steps 2–4 for other files if needed. --# Close the QuaZip instance. - -See the “qztest†subdirectory for examples. TestQuaZipFile::zipUnzip() -is a good place to start. - -\section error-handling Error handling - -Almost any call to ZIP/UNZIP API return some error code. Most of the -original API's error checking could be done in this wrapper as well, -but it would cause unnecessary code bloating without any benefit. So, -%QuaZip only checks for situations that ZIP/UNZIP API can not check -for. For example, ZIP/UNZIP API has no “ZIP open mode†concept -because read and write modes are completely separated. On the other -hand, to avoid creating classes like “QuaZipReaderâ€, “QuaZipWriter†-or something like that, %QuaZip introduces “ZIP open mode†concept -instead, thus making it possible to use one class (QuaZip) for both -reading and writing. But this leads to additional open mode checks -which are not done in ZIP/UNZIP package. - -Therefore, error checking is two-level (%QuaZip's level and ZIP/UNZIP -API level), which sometimes can be confusing, so here are some -advices on how the error checking should be properly done: - -- Both QuaZip and QuaZipFile have getZipError() function, which return - error code of the last ZIP/UNZIP API call. Most function calls - reset error code to UNZ_OK on success and set error code on - failure. Some functions do not reset error code. Most of them are - \c const and do not access ZIP archive in any way. Some, on the - other hand, \em do access ZIP archive, but do not reset or set - error code. For example, QuaZipFile::pos() function. Such functions - are explicitly marked in the documentation. -- Most functions have their own way to report errors, by returning a - null string, negative value or \c false. If such a function returns - error value, call getZipError() to get more information about - error. See “zip.h†and “unzip.h†of the ZIP/UNZIP package for error - codes. -- If the function returns error-stating value (like \c false), but - getZipError() returns UNZ_OK, it means that you did something - obviously wrong. For example, tried to write in the archive open - for reading or not open at all. You better just not do that! - Most functions also issue a warning using qWarning() function in - such cases. See documentation for a specific function for details - on when it should not be called. - -I know that this is somewhat messy, but I could not find a better way -to do all the error handling back in 2005, and it's too late to change -anything now. A major API redesign is needed, but not planned in any -foreseeable future yet. -*/ diff --git a/metaforce-gui/quazip/quazip/ioapi.h b/metaforce-gui/quazip/quazip/ioapi.h deleted file mode 100644 index 75d0aa693..000000000 --- a/metaforce-gui/quazip/quazip/ioapi.h +++ /dev/null @@ -1,207 +0,0 @@ -/* ioapi.h -- IO base function header for compress/uncompress .zip - part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) - - Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) - - Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) - - Modified by Sergey A. Tachenov to allow QIODevice API usage. - - For more info read MiniZip_info.txt - - Changes - - Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) - Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. - More if/def section may be needed to support other platforms - Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. - (but you should use iowin32.c for windows instead) - -*/ - -#ifndef _ZLIBIOAPI64_H -#define _ZLIBIOAPI64_H - -#if (!defined(_WIN32)) && (!defined(WIN32)) - - // Linux needs this to support file operation on files larger then 4+GB - // But might need better if/def to select just the platforms that needs them. - - #ifndef __USE_FILE_OFFSET64 - #define __USE_FILE_OFFSET64 - #endif - #ifndef __USE_LARGEFILE64 - #define __USE_LARGEFILE64 - #endif - #ifndef _LARGEFILE64_SOURCE - #define _LARGEFILE64_SOURCE - #endif - #ifndef _FILE_OFFSET_BIT - #define _FILE_OFFSET_BIT 64 - #endif -#endif - -#include -#include -#include - -#if defined(USE_FILE32API) -#define fopen64 fopen -#define ftello64 ftell -#define fseeko64 fseek -#else -#ifdef _MSC_VER - #define fopen64 fopen - #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) - #define ftello64 _ftelli64 - #define fseeko64 _fseeki64 - #else // old MSC - #define ftello64 ftell - #define fseeko64 fseek - #endif -#endif -#endif - -/* -#ifndef ZPOS64_T - #ifdef _WIN32 - #define ZPOS64_T fpos_t - #else - #include - #define ZPOS64_T uint64_t - #endif -#endif -*/ - -#ifdef HAVE_MINIZIP64_CONF_H -#include "mz64conf.h" -#endif - -/* a type choosen by DEFINE */ -#ifdef HAVE_64BIT_INT_CUSTOM -typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; -#else -#ifdef HAS_STDINT_H -#include "stdint.h" -typedef uint64_t ZPOS64_T; -#else - - -#if defined(_MSC_VER) || defined(__BORLANDC__) -typedef unsigned __int64 ZPOS64_T; -#else -typedef unsigned long long int ZPOS64_T; -#endif -#endif -#endif - - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef OF -#define OF _Z_OF -#endif - -#define ZLIB_FILEFUNC_SEEK_CUR (1) -#define ZLIB_FILEFUNC_SEEK_END (2) -#define ZLIB_FILEFUNC_SEEK_SET (0) - -#define ZLIB_FILEFUNC_MODE_READ (1) -#define ZLIB_FILEFUNC_MODE_WRITE (2) -#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) - -#define ZLIB_FILEFUNC_MODE_EXISTING (4) -#define ZLIB_FILEFUNC_MODE_CREATE (8) - - -#ifndef ZCALLBACK - #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) - #define ZCALLBACK CALLBACK - #else - #define ZCALLBACK - #endif -#endif - - - - -typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, voidpf file, int mode)); -typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); -typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); -typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); -typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); - -typedef uLong (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); -typedef int (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); - - -/* here is the "old" 32 bits structure structure */ -typedef struct zlib_filefunc_def_s -{ - open_file_func zopen_file; - read_file_func zread_file; - write_file_func zwrite_file; - tell_file_func ztell_file; - seek_file_func zseek_file; - close_file_func zclose_file; - testerror_file_func zerror_file; - voidpf opaque; -} zlib_filefunc_def; - -typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); -typedef int (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); -typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, voidpf file, int mode)); - -typedef struct zlib_filefunc64_def_s -{ - open64_file_func zopen64_file; - read_file_func zread_file; - write_file_func zwrite_file; - tell64_file_func ztell64_file; - seek64_file_func zseek64_file; - close_file_func zclose_file; - testerror_file_func zerror_file; - voidpf opaque; - close_file_func zfakeclose_file; // for no-auto-close flag -} zlib_filefunc64_def; - -void fill_qiodevice64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); -void fill_qiodevice_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); - -/* now internal definition, only for zip.c and unzip.h */ -typedef struct zlib_filefunc64_32_def_s -{ - zlib_filefunc64_def zfile_func64; - open_file_func zopen32_file; - tell_file_func ztell32_file; - seek_file_func zseek32_file; -} zlib_filefunc64_32_def; - - -#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) -#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) -//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) -//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) -#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) -#define ZFAKECLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zfakeclose_file)) ((filefunc).zfile_func64.opaque,filestream)) -#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) - -voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf file,int mode)); -int call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); -ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); - -void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); - -#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) -#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) -#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/metaforce-gui/quazip/quazip/minizip_crypt.h b/metaforce-gui/quazip/quazip/minizip_crypt.h deleted file mode 100644 index 2e833f7f3..000000000 --- a/metaforce-gui/quazip/quazip/minizip_crypt.h +++ /dev/null @@ -1,135 +0,0 @@ -/* crypt.h -- base code for crypt/uncrypt ZIPfile - - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This code is a modified version of crypting code in Infozip distribution - - The encryption/decryption parts of this source code (as opposed to the - non-echoing password parts) were originally written in Europe. The - whole source package can be freely distributed, including from the USA. - (Prior to January 2000, re-export from the US was a violation of US law.) - - This encryption code is a direct transcription of the algorithm from - Roger Schlafly, described by Phil Katz in the file appnote.txt. This - file (appnote.txt) is distributed with the PKZIP program (even in the - version without encryption capabilities). - - If you don't need crypting in your application, just define symbols - NOCRYPT and NOUNCRYPT. - - This code support the "Traditional PKWARE Encryption". - - The new AES encryption added on Zip format by Winzip (see the page - http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong - Encryption is not supported. -*/ - -#include "quazip_global.h" - -#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) - -/*********************************************************************** - * Return the next byte in the pseudo-random sequence - */ -static int decrypt_byte(unsigned long* pkeys, const z_crc_t FAR * pcrc_32_tab QUAZIP_UNUSED) -{ - //(void) pcrc_32_tab; /* avoid "unused parameter" warning */ - unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an - * unpredictable manner on 16-bit systems; not a problem - * with any known compiler so far, though */ - - temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; - return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); -} - -/*********************************************************************** - * Update the encryption keys with the next byte of plain text - */ -static int update_keys(unsigned long* pkeys,const z_crc_t FAR * pcrc_32_tab,int c) -{ - (*(pkeys+0)) = CRC32((*(pkeys+0)), c); - (*(pkeys+1)) += (*(pkeys+0)) & 0xff; - (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; - { - register int keyshift = (int)((*(pkeys+1)) >> 24); - (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); - } - return c; -} - - -/*********************************************************************** - * Initialize the encryption keys and the random header according to - * the given password. - */ -static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t FAR * pcrc_32_tab) -{ - *(pkeys+0) = 305419896L; - *(pkeys+1) = 591751049L; - *(pkeys+2) = 878082192L; - while (*passwd != '\0') { - update_keys(pkeys,pcrc_32_tab,(int)*passwd); - passwd++; - } -} - -#define zdecode(pkeys,pcrc_32_tab,c) \ - (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) - -#define zencode(pkeys,pcrc_32_tab,c,t) \ - (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) - -#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED - -#define RAND_HEAD_LEN 12 - /* "last resort" source for second part of crypt seed pattern */ -# ifndef ZCR_SEED2 -# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ -# endif - -static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) - const char *passwd; /* password string */ - unsigned char *buf; /* where to write header */ - int bufSize; - unsigned long* pkeys; - const z_crc_t FAR * pcrc_32_tab; - unsigned long crcForCrypting; -{ - int n; /* index in random header */ - int t; /* temporary */ - int c; /* random byte */ - unsigned char header[RAND_HEAD_LEN-2]; /* random header */ - static unsigned calls = 0; /* ensure different random header each time */ - - if (bufSize> 7) & 0xff; - header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); - } - /* Encrypt random header (last two bytes is high word of crc) */ - init_keys(passwd, pkeys, pcrc_32_tab); - for (n = 0; n < RAND_HEAD_LEN-2; n++) - { - buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); - } - buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); - buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); - return n; -} - -#endif diff --git a/metaforce-gui/quazip/quazip/qioapi.cpp b/metaforce-gui/quazip/quazip/qioapi.cpp deleted file mode 100644 index 60f101d7e..000000000 --- a/metaforce-gui/quazip/quazip/qioapi.cpp +++ /dev/null @@ -1,348 +0,0 @@ -/* ioapi.c -- IO base function header for compress/uncompress .zip - files using zlib + zip or unzip API - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - Modified by Sergey A. Tachenov to integrate with Qt. -*/ - -#include -#include -#include -#include - -#include "ioapi.h" -#include "quazip_global.h" -#include -#include "quazip_qt_compat.h" - -/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ - -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif - -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - -voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,voidpf file,int mode) -{ - if (pfilefunc->zfile_func64.zopen64_file != nullptr) - return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,file,mode); - else - { - return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,file,mode); - } -} - -int call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) -{ - if (pfilefunc->zfile_func64.zseek64_file != nullptr) - return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); - else - { - uLong offsetTruncated = (uLong)offset; - if (offsetTruncated != offset) - return -1; - else - return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); - } -} - -ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) -{ - if (pfilefunc->zfile_func64.zseek64_file != nullptr) - return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); - else - { - uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); - if ((tell_uLong) == ((uLong)-1)) - return (ZPOS64_T)-1; - else - return tell_uLong; - } -} - -/// @cond internal -struct QIODevice_descriptor { - // Position only used for writing to sequential devices. - qint64 pos; - inline QIODevice_descriptor(): - pos(0) - {} -}; -/// @endcond - -voidpf ZCALLBACK qiodevice_open_file_func ( - voidpf opaque, - voidpf file, - int mode) -{ - QIODevice_descriptor *d = reinterpret_cast(opaque); - QIODevice *iodevice = reinterpret_cast(file); - QIODevice::OpenMode desiredMode; - if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) - desiredMode = QIODevice::ReadOnly; - else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) - desiredMode = QIODevice::ReadWrite; - else if (mode & ZLIB_FILEFUNC_MODE_CREATE) - desiredMode = QIODevice::WriteOnly; - if (iodevice->isOpen()) { - if ((iodevice->openMode() & desiredMode) == desiredMode) { - if (desiredMode != QIODevice::WriteOnly - && iodevice->isSequential()) { - // We can use sequential devices only for writing. - delete d; - return nullptr; - } else { - if ((desiredMode & QIODevice::WriteOnly) != 0) { - // open for writing, need to seek existing device - if (!iodevice->isSequential()) { - iodevice->seek(0); - } else { - d->pos = iodevice->pos(); - } - } - } - return iodevice; - } else { - delete d; - return nullptr; - } - } - iodevice->open(desiredMode); - if (iodevice->isOpen()) { - if (desiredMode != QIODevice::WriteOnly && iodevice->isSequential()) { - // We can use sequential devices only for writing. - iodevice->close(); - delete d; - return nullptr; - } else { - return iodevice; - } - } else { - delete d; - return nullptr; - } -} - - -uLong ZCALLBACK qiodevice_read_file_func ( - voidpf opaque, - voidpf stream, - void* buf, - uLong size) -{ - QIODevice_descriptor *d = reinterpret_cast(opaque); - QIODevice *iodevice = reinterpret_cast(stream); - qint64 ret64 = iodevice->read((char*)buf,size); - uLong ret; - ret = (uLong) ret64; - if (ret64 != -1) { - d->pos += ret64; - } - return ret; -} - - -uLong ZCALLBACK qiodevice_write_file_func ( - voidpf opaque, - voidpf stream, - const void* buf, - uLong size) -{ - QIODevice_descriptor *d = reinterpret_cast(opaque); - QIODevice *iodevice = reinterpret_cast(stream); - uLong ret; - qint64 ret64 = iodevice->write((char*)buf,size); - if (ret64 != -1) { - d->pos += ret64; - } - ret = (uLong) ret64; - return ret; -} - -uLong ZCALLBACK qiodevice_tell_file_func ( - voidpf opaque, - voidpf stream) -{ - QIODevice_descriptor *d = reinterpret_cast(opaque); - QIODevice *iodevice = reinterpret_cast(stream); - uLong ret; - qint64 ret64; - if (iodevice->isSequential()) { - ret64 = d->pos; - } else { - ret64 = iodevice->pos(); - } - ret = static_cast(ret64); - return ret; -} - -ZPOS64_T ZCALLBACK qiodevice64_tell_file_func ( - voidpf opaque, - voidpf stream) -{ - QIODevice_descriptor *d = reinterpret_cast(opaque); - QIODevice *iodevice = reinterpret_cast(stream); - qint64 ret; - if (iodevice->isSequential()) { - ret = d->pos; - } else { - ret = iodevice->pos(); - } - return static_cast(ret); -} - -int ZCALLBACK qiodevice_seek_file_func ( - voidpf /*opaque UNUSED*/, - voidpf stream, - uLong offset, - int origin) -{ - QIODevice *iodevice = reinterpret_cast(stream); - if (iodevice->isSequential()) { - if (origin == ZLIB_FILEFUNC_SEEK_END - && offset == 0) { - // sequential devices are always at end (needed in mdAppend) - return 0; - } else { - qWarning("qiodevice_seek_file_func() called for sequential device"); - return -1; - } - } - uLong qiodevice_seek_result=0; - int ret; - switch (origin) - { - case ZLIB_FILEFUNC_SEEK_CUR : - qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset; - break; - case ZLIB_FILEFUNC_SEEK_END : - qiodevice_seek_result = ((QIODevice*)stream)->size() - offset; - break; - case ZLIB_FILEFUNC_SEEK_SET : - qiodevice_seek_result = offset; - break; - default: - return -1; - } - ret = !iodevice->seek(qiodevice_seek_result); - return ret; -} - -int ZCALLBACK qiodevice64_seek_file_func ( - voidpf /*opaque UNUSED*/, - voidpf stream, - ZPOS64_T offset, - int origin) -{ - QIODevice *iodevice = reinterpret_cast(stream); - if (iodevice->isSequential()) { - if (origin == ZLIB_FILEFUNC_SEEK_END - && offset == 0) { - // sequential devices are always at end (needed in mdAppend) - return 0; - } else { - qWarning("qiodevice_seek_file_func() called for sequential device"); - return -1; - } - } - qint64 qiodevice_seek_result=0; - int ret; - switch (origin) - { - case ZLIB_FILEFUNC_SEEK_CUR : - qiodevice_seek_result = ((QIODevice*)stream)->pos() + offset; - break; - case ZLIB_FILEFUNC_SEEK_END : - qiodevice_seek_result = ((QIODevice*)stream)->size() - offset; - break; - case ZLIB_FILEFUNC_SEEK_SET : - qiodevice_seek_result = offset; - break; - default: - return -1; - } - ret = !iodevice->seek(qiodevice_seek_result); - return ret; -} - -int ZCALLBACK qiodevice_close_file_func ( - voidpf opaque, - voidpf stream) -{ - QIODevice_descriptor *d = reinterpret_cast(opaque); - delete d; - QIODevice *device = reinterpret_cast(stream); - return quazip_close(device) ? 0 : -1; -} - -int ZCALLBACK qiodevice_fakeclose_file_func ( - voidpf opaque, - voidpf /*stream*/) -{ - QIODevice_descriptor *d = reinterpret_cast(opaque); - delete d; - return 0; -} - -int ZCALLBACK qiodevice_error_file_func ( - voidpf /*opaque UNUSED*/, - voidpf /*stream UNUSED*/) -{ - // can't check for error due to the QIODevice API limitation - return 0; -} - -void fill_qiodevice_filefunc ( - zlib_filefunc_def* pzlib_filefunc_def) -{ - pzlib_filefunc_def->zopen_file = qiodevice_open_file_func; - pzlib_filefunc_def->zread_file = qiodevice_read_file_func; - pzlib_filefunc_def->zwrite_file = qiodevice_write_file_func; - pzlib_filefunc_def->ztell_file = qiodevice_tell_file_func; - pzlib_filefunc_def->zseek_file = qiodevice_seek_file_func; - pzlib_filefunc_def->zclose_file = qiodevice_close_file_func; - pzlib_filefunc_def->zerror_file = qiodevice_error_file_func; - pzlib_filefunc_def->opaque = new QIODevice_descriptor; -} - -void fill_qiodevice64_filefunc ( - zlib_filefunc64_def* pzlib_filefunc_def) -{ - // Open functions are the same for Qt. - pzlib_filefunc_def->zopen64_file = qiodevice_open_file_func; - pzlib_filefunc_def->zread_file = qiodevice_read_file_func; - pzlib_filefunc_def->zwrite_file = qiodevice_write_file_func; - pzlib_filefunc_def->ztell64_file = qiodevice64_tell_file_func; - pzlib_filefunc_def->zseek64_file = qiodevice64_seek_file_func; - pzlib_filefunc_def->zclose_file = qiodevice_close_file_func; - pzlib_filefunc_def->zerror_file = qiodevice_error_file_func; - pzlib_filefunc_def->opaque = new QIODevice_descriptor; - pzlib_filefunc_def->zfakeclose_file = qiodevice_fakeclose_file_func; -} - -void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) -{ - p_filefunc64_32->zfile_func64.zopen64_file = nullptr; - p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; - p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; - p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; - p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; - p_filefunc64_32->zfile_func64.ztell64_file = nullptr; - p_filefunc64_32->zfile_func64.zseek64_file = nullptr; - p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; - p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; - p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; - p_filefunc64_32->zfile_func64.zfakeclose_file = nullptr; - p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; - p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; -} diff --git a/metaforce-gui/quazip/quazip/quaadler32.cpp b/metaforce-gui/quazip/quazip/quaadler32.cpp deleted file mode 100644 index 4e0118be6..000000000 --- a/metaforce-gui/quazip/quazip/quaadler32.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright (C) 2010 Adam Walczak -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include "quaadler32.h" - -#include - -QuaAdler32::QuaAdler32() -{ - reset(); -} - -quint32 QuaAdler32::calculate(const QByteArray &data) -{ - return adler32( adler32(0L, Z_NULL, 0), (const Bytef*)data.data(), data.size() ); -} - -void QuaAdler32::reset() -{ - checksum = adler32(0L, Z_NULL, 0); -} - -void QuaAdler32::update(const QByteArray &buf) -{ - checksum = adler32( checksum, (const Bytef*)buf.data(), buf.size() ); -} - -quint32 QuaAdler32::value() -{ - return checksum; -} diff --git a/metaforce-gui/quazip/quazip/quaadler32.h b/metaforce-gui/quazip/quazip/quaadler32.h deleted file mode 100644 index 633b175a2..000000000 --- a/metaforce-gui/quazip/quazip/quaadler32.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef QUAADLER32_H -#define QUAADLER32_H - -/* -Copyright (C) 2010 Adam Walczak -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include - -#include "quachecksum32.h" - -/// Adler32 checksum -/** \class QuaAdler32 quaadler32.h - * This class wrappers the adler32 function with the QuaChecksum32 interface. - * See QuaChecksum32 for more info. - */ -class QUAZIP_EXPORT QuaAdler32 : public QuaChecksum32 -{ - -public: - QuaAdler32(); - - quint32 calculate(const QByteArray &data); - - void reset(); - void update(const QByteArray &buf); - quint32 value(); - -private: - quint32 checksum; -}; - -#endif //QUAADLER32_H diff --git a/metaforce-gui/quazip/quazip/quachecksum32.cpp b/metaforce-gui/quazip/quazip/quachecksum32.cpp deleted file mode 100644 index 3625cf1b1..000000000 --- a/metaforce-gui/quazip/quazip/quachecksum32.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "quachecksum32.h" - -QuaChecksum32::~QuaChecksum32() -{ -} diff --git a/metaforce-gui/quazip/quazip/quachecksum32.h b/metaforce-gui/quazip/quazip/quachecksum32.h deleted file mode 100644 index 09471e148..000000000 --- a/metaforce-gui/quazip/quazip/quachecksum32.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef QUACHECKSUM32_H -#define QUACHECKSUM32_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include -#include "quazip_global.h" - -/// Checksum interface. -/** \class QuaChecksum32 quachecksum32.h - * This is an interface for 32 bit checksums. - * Classes implementing this interface can calcunate a certin - * checksum in a single step: - * \code - * QChecksum32 *crc32 = new QuaCrc32(); - * rasoult = crc32->calculate(data); - * \endcode - * or by streaming the data: - * \code - * QChecksum32 *crc32 = new QuaCrc32(); - * while(!fileA.atEnd()) - * crc32->update(fileA.read(bufSize)); - * resoultA = crc32->value(); - * crc32->reset(); - * while(!fileB.atEnd()) - * crc32->update(fileB.read(bufSize)); - * resoultB = crc32->value(); - * \endcode - */ -class QUAZIP_EXPORT QuaChecksum32 -{ - -public: - virtual ~QuaChecksum32(); - ///Calculates the checksum for data. - /** \a data source data - * \return data checksum - * - * This function has no efect on the value returned by value(). - */ - virtual quint32 calculate(const QByteArray &data) = 0; - - ///Resets the calculation on a checksun for a stream. - virtual void reset() = 0; - - ///Updates the calculated checksum for the stream - /** \a buf next portion of data from the stream - */ - virtual void update(const QByteArray &buf) = 0; - - ///Value of the checksum calculated for the stream passed throw update(). - /** \return checksum - */ - virtual quint32 value() = 0; -}; - -#endif //QUACHECKSUM32_H diff --git a/metaforce-gui/quazip/quazip/quacrc32.cpp b/metaforce-gui/quazip/quazip/quacrc32.cpp deleted file mode 100644 index b491dc07c..000000000 --- a/metaforce-gui/quazip/quazip/quacrc32.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include "quacrc32.h" - -#include - -QuaCrc32::QuaCrc32() -{ - reset(); -} - -quint32 QuaCrc32::calculate(const QByteArray &data) -{ - return crc32( crc32(0L, Z_NULL, 0), (const Bytef*)data.data(), data.size() ); -} - -void QuaCrc32::reset() -{ - checksum = crc32(0L, Z_NULL, 0); -} - -void QuaCrc32::update(const QByteArray &buf) -{ - checksum = crc32( checksum, (const Bytef*)buf.data(), buf.size() ); -} - -quint32 QuaCrc32::value() -{ - return checksum; -} diff --git a/metaforce-gui/quazip/quazip/quacrc32.h b/metaforce-gui/quazip/quazip/quacrc32.h deleted file mode 100644 index 49808af16..000000000 --- a/metaforce-gui/quazip/quazip/quacrc32.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef QUACRC32_H -#define QUACRC32_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include "quachecksum32.h" - -///CRC32 checksum -/** \class QuaCrc32 quacrc32.h -* This class wrappers the crc32 function with the QuaChecksum32 interface. -* See QuaChecksum32 for more info. -*/ -class QUAZIP_EXPORT QuaCrc32 : public QuaChecksum32 { - -public: - QuaCrc32(); - - quint32 calculate(const QByteArray &data); - - void reset(); - void update(const QByteArray &buf); - quint32 value(); - -private: - quint32 checksum; -}; - -#endif //QUACRC32_H diff --git a/metaforce-gui/quazip/quazip/quagzipfile.cpp b/metaforce-gui/quazip/quazip/quagzipfile.cpp deleted file mode 100644 index c637aaa5a..000000000 --- a/metaforce-gui/quazip/quazip/quagzipfile.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include - -#include "quagzipfile.h" - -/// \cond internal -class QuaGzipFilePrivate { - friend class QuaGzipFile; - QString fileName; - gzFile gzd; - inline QuaGzipFilePrivate(): gzd(nullptr) {} - inline QuaGzipFilePrivate(const QString &fileName): - fileName(fileName), gzd(nullptr) {} - template bool open(FileId id, - QIODevice::OpenMode mode, QString &error); - gzFile open(int fd, const char *modeString); - gzFile open(const QString &name, const char *modeString); -}; - -gzFile QuaGzipFilePrivate::open(const QString &name, const char *modeString) -{ - return gzopen(QFile::encodeName(name).constData(), modeString); -} - -gzFile QuaGzipFilePrivate::open(int fd, const char *modeString) -{ - return gzdopen(fd, modeString); -} - -template -bool QuaGzipFilePrivate::open(FileId id, QIODevice::OpenMode mode, - QString &error) -{ - char modeString[2]; - modeString[0] = modeString[1] = '\0'; - if ((mode & QIODevice::Append) != 0) { - error = QuaGzipFile::tr("QIODevice::Append is not " - "supported for GZIP"); - return false; - } - if ((mode & QIODevice::ReadOnly) != 0 - && (mode & QIODevice::WriteOnly) != 0) { - error = QuaGzipFile::tr("Opening gzip for both reading" - " and writing is not supported"); - return false; - } else if ((mode & QIODevice::ReadOnly) != 0) { - modeString[0] = 'r'; - } else if ((mode & QIODevice::WriteOnly) != 0) { - modeString[0] = 'w'; - } else { - error = QuaGzipFile::tr("You can open a gzip either for reading" - " or for writing. Which is it?"); - return false; - } - gzd = open(id, modeString); - if (gzd == nullptr) { - error = QuaGzipFile::tr("Could not gzopen() file"); - return false; - } - return true; -} -/// \endcond - -QuaGzipFile::QuaGzipFile(): -d(new QuaGzipFilePrivate()) -{ -} - -QuaGzipFile::QuaGzipFile(QObject *parent): -QIODevice(parent), -d(new QuaGzipFilePrivate()) -{ -} - -QuaGzipFile::QuaGzipFile(const QString &fileName, QObject *parent): - QIODevice(parent), -d(new QuaGzipFilePrivate(fileName)) -{ -} - -QuaGzipFile::~QuaGzipFile() -{ - if (isOpen()) { - close(); - } - delete d; -} - -void QuaGzipFile::setFileName(const QString& fileName) -{ - d->fileName = fileName; -} - -QString QuaGzipFile::getFileName() const -{ - return d->fileName; -} - -bool QuaGzipFile::isSequential() const -{ - return true; -} - -bool QuaGzipFile::open(QIODevice::OpenMode mode) -{ - QString error; - if (!d->open(d->fileName, mode, error)) { - setErrorString(error); - return false; - } - return QIODevice::open(mode); -} - -bool QuaGzipFile::open(int fd, QIODevice::OpenMode mode) -{ - QString error; - if (!d->open(fd, mode, error)) { - setErrorString(error); - return false; - } - return QIODevice::open(mode); -} - -bool QuaGzipFile::flush() -{ - return gzflush(d->gzd, Z_SYNC_FLUSH) == Z_OK; -} - -void QuaGzipFile::close() -{ - QIODevice::close(); - gzclose(d->gzd); -} - -qint64 QuaGzipFile::readData(char *data, qint64 maxSize) -{ - return gzread(d->gzd, (voidp)data, (unsigned)maxSize); -} - -qint64 QuaGzipFile::writeData(const char *data, qint64 maxSize) -{ - if (maxSize == 0) - return 0; - int written = gzwrite(d->gzd, (voidp)data, (unsigned)maxSize); - if (written == 0) - return -1; - else - return written; -} diff --git a/metaforce-gui/quazip/quazip/quagzipfile.h b/metaforce-gui/quazip/quazip/quagzipfile.h deleted file mode 100644 index 77d2459c1..000000000 --- a/metaforce-gui/quazip/quazip/quagzipfile.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef QUAZIP_QUAGZIPFILE_H -#define QUAZIP_QUAGZIPFILE_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include -#include "quazip_global.h" - -#include - -class QuaGzipFilePrivate; - -/// GZIP file -/** - This class is a wrapper around GZIP file access functions in zlib. Unlike QuaZip classes, it doesn't allow reading from a GZIP file opened as QIODevice, for example, if your GZIP file is in QBuffer. It only provides QIODevice access to a GZIP file contents, but the GZIP file itself must be identified by its name on disk or by descriptor id. - */ -class QUAZIP_EXPORT QuaGzipFile: public QIODevice { - Q_OBJECT -public: - /// Empty constructor. - /** - Must call setFileName() before trying to open. - */ - QuaGzipFile(); - /// Empty constructor with a parent. - /** - Must call setFileName() before trying to open. - \param parent The parent object, as per QObject logic. - */ - QuaGzipFile(QObject *parent); - /// Constructor. - /** - \param fileName The name of the GZIP file. - \param parent The parent object, as per QObject logic. - */ - QuaGzipFile(const QString &fileName, QObject *parent = nullptr); - /// Destructor. - virtual ~QuaGzipFile(); - /// Sets the name of the GZIP file to be opened. - void setFileName(const QString& fileName); - /// Returns the name of the GZIP file. - QString getFileName() const; - /// Returns true. - /** - Strictly speaking, zlib supports seeking for GZIP files, but it is - poorly implemented, because there is no way to implement it - properly. For reading, seeking backwards is very slow, and for - writing, it is downright impossible. Therefore, QuaGzipFile does not - support seeking at all. - */ - virtual bool isSequential() const; - /// Opens the file. - /** - \param mode Can be either QIODevice::Write or QIODevice::Read. - ReadWrite and Append aren't supported. - */ - virtual bool open(QIODevice::OpenMode mode); - /// Opens the file. - /** - \overload - \param fd The file descriptor to read/write the GZIP file from/to. - \param mode Can be either QIODevice::Write or QIODevice::Read. - ReadWrite and Append aren't supported. - */ - virtual bool open(int fd, QIODevice::OpenMode mode); - /// Flushes data to file. - /** - The data is written using Z_SYNC_FLUSH mode. Doesn't make any sense - when reading. - */ - virtual bool flush(); - /// Closes the file. - virtual void close(); -protected: - /// Implementation of QIODevice::readData(). - virtual qint64 readData(char *data, qint64 maxSize); - /// Implementation of QIODevice::writeData(). - virtual qint64 writeData(const char *data, qint64 maxSize); -private: - // not implemented by design to disable copy - QuaGzipFile(const QuaGzipFile &that); - QuaGzipFile& operator=(const QuaGzipFile &that); - QuaGzipFilePrivate *d; -}; - -#endif // QUAZIP_QUAGZIPFILE_H diff --git a/metaforce-gui/quazip/quazip/quaziodevice.cpp b/metaforce-gui/quazip/quazip/quaziodevice.cpp deleted file mode 100644 index d3af4f918..000000000 --- a/metaforce-gui/quazip/quazip/quaziodevice.cpp +++ /dev/null @@ -1,349 +0,0 @@ -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include "quaziodevice.h" - -#define QUAZIO_INBUFSIZE 4096 -#define QUAZIO_OUTBUFSIZE 4096 - -/// \cond internal -class QuaZIODevicePrivate { - friend class QuaZIODevice; - QuaZIODevicePrivate(QIODevice *io, QuaZIODevice *q); - ~QuaZIODevicePrivate(); - QIODevice *io; - QuaZIODevice *q; - z_stream zins; - z_stream zouts; - char *inBuf; - int inBufPos; - int inBufSize; - char *outBuf; - int outBufPos; - int outBufSize; - bool zBufError; - bool atEnd; - bool flush(int sync); - int doFlush(QString &error); -}; - -QuaZIODevicePrivate::QuaZIODevicePrivate(QIODevice *io, QuaZIODevice *q): - io(io), - q(q), - inBuf(nullptr), - inBufPos(0), - inBufSize(0), - outBuf(nullptr), - outBufPos(0), - outBufSize(0), - zBufError(false), - atEnd(false) -{ - zins.zalloc = (alloc_func) nullptr; - zins.zfree = (free_func) nullptr; - zins.opaque = nullptr; - zouts.zalloc = (alloc_func) nullptr; - zouts.zfree = (free_func) nullptr; - zouts.opaque = nullptr; - inBuf = new char[QUAZIO_INBUFSIZE]; - outBuf = new char[QUAZIO_OUTBUFSIZE]; -#ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT - debug.setFileName("debug.out"); - debug.open(QIODevice::WriteOnly); -#endif -#ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT - indebug.setFileName("debug.in"); - indebug.open(QIODevice::WriteOnly); -#endif -} - -QuaZIODevicePrivate::~QuaZIODevicePrivate() -{ -#ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT - debug.close(); -#endif -#ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT - indebug.close(); -#endif - if (inBuf != nullptr) - delete[] inBuf; - if (outBuf != nullptr) - delete[] outBuf; -} - -bool QuaZIODevicePrivate::flush(int sync) -{ - QString error; - if (doFlush(error) < 0) { - q->setErrorString(error); - return false; - } - // can't flush buffer, some data is still waiting - if (outBufPos < outBufSize) - return true; - Bytef c = 0; - zouts.next_in = &c; // fake input buffer - zouts.avail_in = 0; // of zero size - do { - zouts.next_out = (Bytef *) outBuf; - zouts.avail_out = QUAZIO_OUTBUFSIZE; - int result = deflate(&zouts, sync); - switch (result) { - case Z_OK: - case Z_STREAM_END: - outBufSize = (char *) zouts.next_out - outBuf; - if (doFlush(error) < 0) { - q->setErrorString(error); - return false; - } - if (outBufPos < outBufSize) - return true; - break; - case Z_BUF_ERROR: // nothing to write? - return true; - default: - q->setErrorString(QString::fromLocal8Bit(zouts.msg)); - return false; - } - } while (zouts.avail_out == 0); - return true; -} - -int QuaZIODevicePrivate::doFlush(QString &error) -{ - int flushed = 0; - while (outBufPos < outBufSize) { - int more = io->write(outBuf + outBufPos, outBufSize - outBufPos); - if (more == -1) { - error = io->errorString(); - return -1; - } - if (more == 0) - break; - outBufPos += more; - flushed += more; - } - if (outBufPos == outBufSize) { - outBufPos = outBufSize = 0; - } - return flushed; -} - -/// \endcond - -// #define QUAZIP_ZIODEVICE_DEBUG_OUTPUT -// #define QUAZIP_ZIODEVICE_DEBUG_INPUT -#ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT -#include -static QFile debug; -#endif -#ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT -#include -static QFile indebug; -#endif - -QuaZIODevice::QuaZIODevice(QIODevice *io, QObject *parent): - QIODevice(parent), - d(new QuaZIODevicePrivate(io, this)) -{ - connect(io, SIGNAL(readyRead()), SIGNAL(readyRead())); -} - -QuaZIODevice::~QuaZIODevice() -{ - if (isOpen()) - close(); - delete d; -} - -QIODevice *QuaZIODevice::getIoDevice() const -{ - return d->io; -} - -bool QuaZIODevice::open(QIODevice::OpenMode mode) -{ - if ((mode & QIODevice::Append) != 0) { - setErrorString(tr("QIODevice::Append is not supported for" - " QuaZIODevice")); - return false; - } - if ((mode & QIODevice::ReadWrite) == QIODevice::ReadWrite) { - setErrorString(tr("QIODevice::ReadWrite is not supported for" - " QuaZIODevice")); - return false; - } - if ((mode & QIODevice::ReadOnly) != 0) { - if (inflateInit(&d->zins) != Z_OK) { - setErrorString(QString::fromLocal8Bit(d->zins.msg)); - return false; - } - } - if ((mode & QIODevice::WriteOnly) != 0) { - if (deflateInit(&d->zouts, Z_DEFAULT_COMPRESSION) != Z_OK) { - setErrorString(QString::fromLocal8Bit(d->zouts.msg)); - return false; - } - } - return QIODevice::open(mode); -} - -void QuaZIODevice::close() -{ - if ((openMode() & QIODevice::ReadOnly) != 0) { - if (inflateEnd(&d->zins) != Z_OK) { - setErrorString(QString::fromLocal8Bit(d->zins.msg)); - } - } - if ((openMode() & QIODevice::WriteOnly) != 0) { - d->flush(Z_FINISH); - if (deflateEnd(&d->zouts) != Z_OK) { - setErrorString(QString::fromLocal8Bit(d->zouts.msg)); - } - } - QIODevice::close(); -} - -qint64 QuaZIODevice::readData(char *data, qint64 maxSize) -{ - int read = 0; - while (read < maxSize) { - if (d->inBufPos == d->inBufSize) { - d->inBufPos = 0; - d->inBufSize = d->io->read(d->inBuf, QUAZIO_INBUFSIZE); - if (d->inBufSize == -1) { - d->inBufSize = 0; - setErrorString(d->io->errorString()); - return -1; - } - if (d->inBufSize == 0) - break; - } - while (read < maxSize && d->inBufPos < d->inBufSize) { - d->zins.next_in = (Bytef *) (d->inBuf + d->inBufPos); - d->zins.avail_in = d->inBufSize - d->inBufPos; - d->zins.next_out = (Bytef *) (data + read); - d->zins.avail_out = (uInt) (maxSize - read); // hope it's less than 2GB - int more = 0; - switch (inflate(&d->zins, Z_SYNC_FLUSH)) { - case Z_OK: - read = (char *) d->zins.next_out - data; - d->inBufPos = (char *) d->zins.next_in - d->inBuf; - break; - case Z_STREAM_END: - read = (char *) d->zins.next_out - data; - d->inBufPos = (char *) d->zins.next_in - d->inBuf; - d->atEnd = true; - return read; - case Z_BUF_ERROR: // this should never happen, but just in case - if (!d->zBufError) { - qWarning("Z_BUF_ERROR detected with %d/%d in/out, weird", - d->zins.avail_in, d->zins.avail_out); - d->zBufError = true; - } - memmove(d->inBuf, d->inBuf + d->inBufPos, d->inBufSize - d->inBufPos); - d->inBufSize -= d->inBufPos; - d->inBufPos = 0; - more = d->io->read(d->inBuf + d->inBufSize, QUAZIO_INBUFSIZE - d->inBufSize); - if (more == -1) { - setErrorString(d->io->errorString()); - return -1; - } - if (more == 0) - return read; - d->inBufSize += more; - break; - default: - setErrorString(QString::fromLocal8Bit(d->zins.msg)); - return -1; - } - } - } -#ifdef QUAZIP_ZIODEVICE_DEBUG_INPUT - indebug.write(data, read); -#endif - return read; -} - -qint64 QuaZIODevice::writeData(const char *data, qint64 maxSize) -{ - int written = 0; - QString error; - if (d->doFlush(error) == -1) { - setErrorString(error); - return -1; - } - while (written < maxSize) { - // there is some data waiting in the output buffer - if (d->outBufPos < d->outBufSize) - return written; - d->zouts.next_in = (Bytef *) (data + written); - d->zouts.avail_in = (uInt) (maxSize - written); // hope it's less than 2GB - d->zouts.next_out = (Bytef *) d->outBuf; - d->zouts.avail_out = QUAZIO_OUTBUFSIZE; - switch (deflate(&d->zouts, Z_NO_FLUSH)) { - case Z_OK: - written = (char *) d->zouts.next_in - data; - d->outBufSize = (char *) d->zouts.next_out - d->outBuf; - break; - default: - setErrorString(QString::fromLocal8Bit(d->zouts.msg)); - return -1; - } - if (d->doFlush(error) == -1) { - setErrorString(error); - return -1; - } - } -#ifdef QUAZIP_ZIODEVICE_DEBUG_OUTPUT - debug.write(data, written); -#endif - return written; -} - -bool QuaZIODevice::flush() -{ - return d->flush(Z_SYNC_FLUSH); -} - -bool QuaZIODevice::isSequential() const -{ - return true; -} - -bool QuaZIODevice::atEnd() const -{ - // Here we MUST check QIODevice::bytesAvailable() because WE - // might have reached the end, but QIODevice didn't-- - // it could have simply pre-buffered all remaining data. - return (openMode() == NotOpen) || (QIODevice::bytesAvailable() == 0 && d->atEnd); -} - -qint64 QuaZIODevice::bytesAvailable() const -{ - // If we haven't recevied Z_STREAM_END, it means that - // we have at least one more input byte available. - // Plus whatever QIODevice has buffered. - return (d->atEnd ? 0 : 1) + QIODevice::bytesAvailable(); -} diff --git a/metaforce-gui/quazip/quazip/quaziodevice.h b/metaforce-gui/quazip/quazip/quaziodevice.h deleted file mode 100644 index 3adb8b92f..000000000 --- a/metaforce-gui/quazip/quazip/quaziodevice.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef QUAZIP_QUAZIODEVICE_H -#define QUAZIP_QUAZIODEVICE_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include -#include "quazip_global.h" - -#include - -class QuaZIODevicePrivate; - -/// A class to compress/decompress QIODevice. -/** - This class can be used to compress any data written to QIODevice or - decompress it back. Compressing data sent over a QTcpSocket is a good - example. - */ -class QUAZIP_EXPORT QuaZIODevice: public QIODevice { - friend class QuaZIODevicePrivate; - Q_OBJECT -public: - /// Constructor. - /** - \param io The QIODevice to read/write. - \param parent The parent object, as per QObject logic. - */ - QuaZIODevice(QIODevice *io, QObject *parent = nullptr); - /// Destructor. - ~QuaZIODevice(); - /// Flushes data waiting to be written. - /** - Unfortunately, as QIODevice doesn't support flush() by itself, the - only thing this method does is write the compressed data into the - device using Z_SYNC_FLUSH mode. If you need the compressed data to - actually be flushed from the buffer of the underlying QIODevice, you - need to call its flush() method as well, providing it supports it - (like QTcpSocket does). Example: - \code - QuaZIODevice dev(&sock); - dev.open(QIODevice::Write); - dev.write(yourDataGoesHere); - dev.flush(); - sock->flush(); // this actually sends data to network - \endcode - - This may change in the future versions of %QuaZip by implementing an - ugly hack: trying to cast the QIODevice using qobject_cast to known - flush()-supporting subclasses, and calling flush if the resulting - pointer is not zero. - */ - virtual bool flush(); - /// Opens the device. - /** - \param mode Neither QIODevice::ReadWrite nor QIODevice::Append are - not supported. - */ - virtual bool open(QIODevice::OpenMode mode); - /// Closes this device, but not the underlying one. - /** - The underlying QIODevice is not closed in case you want to write - something else to it. - */ - virtual void close(); - /// Returns the underlying device. - QIODevice *getIoDevice() const; - /// Returns true. - virtual bool isSequential() const; - /// Returns true iff the end of the compressed stream is reached. - virtual bool atEnd() const; - /// Returns the number of the bytes buffered. - virtual qint64 bytesAvailable() const; -protected: - /// Implementation of QIODevice::readData(). - virtual qint64 readData(char *data, qint64 maxSize); - /// Implementation of QIODevice::writeData(). - virtual qint64 writeData(const char *data, qint64 maxSize); -private: - QuaZIODevicePrivate *d; -}; -#endif // QUAZIP_QUAZIODEVICE_H diff --git a/metaforce-gui/quazip/quazip/quazip.cpp b/metaforce-gui/quazip/quazip/quazip.cpp deleted file mode 100644 index 29a278da2..000000000 --- a/metaforce-gui/quazip/quazip/quazip.cpp +++ /dev/null @@ -1,846 +0,0 @@ -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant, see -quazip/(un)zip.h files for details, basically it's zlib license. - **/ - -#include -#include -#include - -#include "quazip.h" - -#define QUAZIP_OS_UNIX 3u - -/// All the internal stuff for the QuaZip class. -/** - \internal - - This class keeps all the private stuff for the QuaZip class so it can - be changed without breaking binary compatibility, according to the - Pimpl idiom. - */ -class QuaZipPrivate { - friend class QuaZip; - private: - Q_DISABLE_COPY(QuaZipPrivate) - /// The pointer to the corresponding QuaZip instance. - QuaZip *q; - /// The codec for file names (used when UTF-8 is not enabled). - QTextCodec *fileNameCodec; - /// The codec for comments (used when UTF-8 is not enabled). - QTextCodec *commentCodec; - /// The archive file name. - QString zipName; - /// The device to access the archive. - QIODevice *ioDevice; - /// The global comment. - QString comment; - /// The open mode. - QuaZip::Mode mode; - union { - /// The internal handle for UNZIP modes. - unzFile unzFile_f; - /// The internal handle for ZIP modes. - zipFile zipFile_f; - }; - /// Whether a current file is set. - bool hasCurrentFile_f; - /// The last error. - int zipError; - /// Whether \ref QuaZip::setDataDescriptorWritingEnabled() "the data descriptor writing mode" is enabled. - bool dataDescriptorWritingEnabled; - /// The zip64 mode. - bool zip64; - /// The auto-close flag. - bool autoClose; - /// The UTF-8 flag. - bool utf8; - /// The OS code. - uint osCode; - inline QTextCodec *getDefaultFileNameCodec() - { - if (defaultFileNameCodec == nullptr) { - return QTextCodec::codecForLocale(); - } else { - return defaultFileNameCodec; - } - } - /// The constructor for the corresponding QuaZip constructor. - inline QuaZipPrivate(QuaZip *q): - q(q), - fileNameCodec(getDefaultFileNameCodec()), - commentCodec(QTextCodec::codecForLocale()), - ioDevice(nullptr), - mode(QuaZip::mdNotOpen), - hasCurrentFile_f(false), - zipError(UNZ_OK), - dataDescriptorWritingEnabled(true), - zip64(false), - autoClose(true), - utf8(false), - osCode(defaultOsCode) - { - unzFile_f = nullptr; - zipFile_f = nullptr; - lastMappedDirectoryEntry.num_of_file = 0; - lastMappedDirectoryEntry.pos_in_zip_directory = 0; - } - /// The constructor for the corresponding QuaZip constructor. - inline QuaZipPrivate(QuaZip *q, const QString &zipName): - q(q), - fileNameCodec(getDefaultFileNameCodec()), - commentCodec(QTextCodec::codecForLocale()), - zipName(zipName), - ioDevice(nullptr), - mode(QuaZip::mdNotOpen), - hasCurrentFile_f(false), - zipError(UNZ_OK), - dataDescriptorWritingEnabled(true), - zip64(false), - autoClose(true), - utf8(false), - osCode(defaultOsCode) - { - unzFile_f = nullptr; - zipFile_f = nullptr; - lastMappedDirectoryEntry.num_of_file = 0; - lastMappedDirectoryEntry.pos_in_zip_directory = 0; - } - /// The constructor for the corresponding QuaZip constructor. - inline QuaZipPrivate(QuaZip *q, QIODevice *ioDevice): - q(q), - fileNameCodec(getDefaultFileNameCodec()), - commentCodec(QTextCodec::codecForLocale()), - ioDevice(ioDevice), - mode(QuaZip::mdNotOpen), - hasCurrentFile_f(false), - zipError(UNZ_OK), - dataDescriptorWritingEnabled(true), - zip64(false), - autoClose(true), - utf8(false), - osCode(defaultOsCode) - { - unzFile_f = nullptr; - zipFile_f = nullptr; - lastMappedDirectoryEntry.num_of_file = 0; - lastMappedDirectoryEntry.pos_in_zip_directory = 0; - } - /// Returns either a list of file names or a list of QuaZipFileInfo. - template - bool getFileInfoList(QList *result) const; - - /// Stores map of filenames and file locations for unzipping - inline void clearDirectoryMap(); - inline void addCurrentFileToDirectoryMap(const QString &fileName); - bool goToFirstUnmappedFile(); - QHash directoryCaseSensitive; - QHash directoryCaseInsensitive; - unz64_file_pos lastMappedDirectoryEntry; - static QTextCodec *defaultFileNameCodec; - static uint defaultOsCode; -}; - -QTextCodec *QuaZipPrivate::defaultFileNameCodec = nullptr; -uint QuaZipPrivate::defaultOsCode = QUAZIP_OS_UNIX; - -void QuaZipPrivate::clearDirectoryMap() -{ - directoryCaseInsensitive.clear(); - directoryCaseSensitive.clear(); - lastMappedDirectoryEntry.num_of_file = 0; - lastMappedDirectoryEntry.pos_in_zip_directory = 0; -} - -void QuaZipPrivate::addCurrentFileToDirectoryMap(const QString &fileName) -{ - if (!hasCurrentFile_f || fileName.isEmpty()) { - return; - } - // Adds current file to filename map as fileName - unz64_file_pos fileDirectoryPos; - unzGetFilePos64(unzFile_f, &fileDirectoryPos); - directoryCaseSensitive.insert(fileName, fileDirectoryPos); - // Only add lowercase to directory map if not already there - // ensures only map the first one seen - QString lower = fileName.toLower(); - if (!directoryCaseInsensitive.contains(lower)) - directoryCaseInsensitive.insert(lower, fileDirectoryPos); - // Mark last one - if (fileDirectoryPos.pos_in_zip_directory > lastMappedDirectoryEntry.pos_in_zip_directory) - lastMappedDirectoryEntry = fileDirectoryPos; -} - -bool QuaZipPrivate::goToFirstUnmappedFile() -{ - zipError = UNZ_OK; - if (mode != QuaZip::mdUnzip) { - qWarning("QuaZipPrivate::goToNextUnmappedFile(): ZIP is not open in mdUnzip mode"); - return false; - } - // If not mapped anything, go to beginning - if (lastMappedDirectoryEntry.pos_in_zip_directory == 0) { - unzGoToFirstFile(unzFile_f); - } else { - // Goto the last one mapped, plus one - unzGoToFilePos64(unzFile_f, &lastMappedDirectoryEntry); - unzGoToNextFile(unzFile_f); - } - hasCurrentFile_f=zipError==UNZ_OK; - if(zipError==UNZ_END_OF_LIST_OF_FILE) - zipError=UNZ_OK; - return hasCurrentFile_f; -} - -QuaZip::QuaZip(): - p(new QuaZipPrivate(this)) -{ -} - -QuaZip::QuaZip(const QString& zipName): - p(new QuaZipPrivate(this, zipName)) -{ -} - -QuaZip::QuaZip(QIODevice *ioDevice): - p(new QuaZipPrivate(this, ioDevice)) -{ -} - -QuaZip::~QuaZip() -{ - if(isOpen()) - close(); - delete p; -} - -bool QuaZip::open(Mode mode, zlib_filefunc_def* ioApi) -{ - p->zipError=UNZ_OK; - if(isOpen()) { - qWarning("QuaZip::open(): ZIP already opened"); - return false; - } - QIODevice *ioDevice = p->ioDevice; - if (ioDevice == nullptr) { - if (p->zipName.isEmpty()) { - qWarning("QuaZip::open(): set either ZIP file name or IO device first"); - return false; - } else { - ioDevice = new QFile(p->zipName); - } - } - unsigned flags = 0; - switch(mode) { - case mdUnzip: - if (ioApi == nullptr) { - if (p->autoClose) - flags |= UNZ_AUTO_CLOSE; - p->unzFile_f=unzOpenInternal(ioDevice, nullptr, 1, flags); - } else { - // QuaZip pre-zip64 compatibility mode - p->unzFile_f=unzOpen2(ioDevice, ioApi); - if (p->unzFile_f != nullptr) { - if (p->autoClose) { - unzSetFlags(p->unzFile_f, UNZ_AUTO_CLOSE); - } else { - unzClearFlags(p->unzFile_f, UNZ_AUTO_CLOSE); - } - } - } - if(p->unzFile_f!=nullptr) { - if (ioDevice->isSequential()) { - unzClose(p->unzFile_f); - if (!p->zipName.isEmpty()) - delete ioDevice; - qWarning("QuaZip::open(): " - "only mdCreate can be used with " - "sequential devices"); - return false; - } - p->mode=mode; - p->ioDevice = ioDevice; - return true; - } else { - p->zipError=UNZ_OPENERROR; - if (!p->zipName.isEmpty()) - delete ioDevice; - return false; - } - case mdCreate: - case mdAppend: - case mdAdd: - if (ioApi == nullptr) { - if (p->autoClose) - flags |= ZIP_AUTO_CLOSE; - if (p->dataDescriptorWritingEnabled) - flags |= ZIP_WRITE_DATA_DESCRIPTOR; - if (p->utf8) - flags |= ZIP_ENCODING_UTF8; - p->zipFile_f=zipOpen3(ioDevice, - mode==mdCreate?APPEND_STATUS_CREATE: - mode==mdAppend?APPEND_STATUS_CREATEAFTER: - APPEND_STATUS_ADDINZIP, - nullptr, nullptr, flags); - } else { - // QuaZip pre-zip64 compatibility mode - p->zipFile_f=zipOpen2(ioDevice, - mode==mdCreate?APPEND_STATUS_CREATE: - mode==mdAppend?APPEND_STATUS_CREATEAFTER: - APPEND_STATUS_ADDINZIP, - nullptr, - ioApi); - if (p->zipFile_f != nullptr) { - zipSetFlags(p->zipFile_f, flags); - } - } - if(p->zipFile_f!=nullptr) { - if (ioDevice->isSequential()) { - if (mode != mdCreate) { - zipClose(p->zipFile_f, nullptr); - qWarning("QuaZip::open(): " - "only mdCreate can be used with " - "sequential devices"); - if (!p->zipName.isEmpty()) - delete ioDevice; - return false; - } - zipSetFlags(p->zipFile_f, ZIP_SEQUENTIAL); - } - p->mode=mode; - p->ioDevice = ioDevice; - return true; - } else { - p->zipError=UNZ_OPENERROR; - if (!p->zipName.isEmpty()) - delete ioDevice; - return false; - } - default: - qWarning("QuaZip::open(): unknown mode: %d", (int)mode); - if (!p->zipName.isEmpty()) - delete ioDevice; - return false; - break; - } -} - -void QuaZip::close() -{ - p->zipError=UNZ_OK; - switch(p->mode) { - case mdNotOpen: - qWarning("QuaZip::close(): ZIP is not open"); - return; - case mdUnzip: - p->zipError=unzClose(p->unzFile_f); - break; - case mdCreate: - case mdAppend: - case mdAdd: - p->zipError=zipClose(p->zipFile_f, p->comment.isNull() ? nullptr : isUtf8Enabled() - ? p->comment.toUtf8().constData() - : p->commentCodec->fromUnicode(p->comment).constData()); - break; - default: - qWarning("QuaZip::close(): unknown mode: %d", (int)p->mode); - return; - } - // opened by name, need to delete the internal IO device - if (!p->zipName.isEmpty()) { - delete p->ioDevice; - p->ioDevice = nullptr; - } - p->clearDirectoryMap(); - if(p->zipError==UNZ_OK) - p->mode=mdNotOpen; -} - -void QuaZip::setZipName(const QString& zipName) -{ - if(isOpen()) { - qWarning("QuaZip::setZipName(): ZIP is already open!"); - return; - } - p->zipName=zipName; - p->ioDevice = nullptr; -} - -void QuaZip::setIoDevice(QIODevice *ioDevice) -{ - if(isOpen()) { - qWarning("QuaZip::setIoDevice(): ZIP is already open!"); - return; - } - p->ioDevice = ioDevice; - p->zipName = QString(); -} - -int QuaZip::getEntriesCount()const -{ - QuaZip *fakeThis=(QuaZip*)this; // non-const - fakeThis->p->zipError=UNZ_OK; - if(p->mode!=mdUnzip) { - qWarning("QuaZip::getEntriesCount(): ZIP is not open in mdUnzip mode"); - return -1; - } - unz_global_info64 globalInfo; - if((fakeThis->p->zipError=unzGetGlobalInfo64(p->unzFile_f, &globalInfo))!=UNZ_OK) - return p->zipError; - return (int)globalInfo.number_entry; -} - -QString QuaZip::getComment()const -{ - QuaZip *fakeThis=(QuaZip*)this; // non-const - fakeThis->p->zipError=UNZ_OK; - if(p->mode!=mdUnzip) { - qWarning("QuaZip::getComment(): ZIP is not open in mdUnzip mode"); - return QString(); - } - unz_global_info64 globalInfo; - QByteArray comment; - if((fakeThis->p->zipError=unzGetGlobalInfo64(p->unzFile_f, &globalInfo))!=UNZ_OK) - return QString(); - comment.resize(globalInfo.size_comment); - if((fakeThis->p->zipError=unzGetGlobalComment(p->unzFile_f, comment.data(), comment.size())) < 0) - return QString(); - fakeThis->p->zipError = UNZ_OK; - unsigned flags = 0; - return (unzGetFileFlags(p->unzFile_f, &flags) == UNZ_OK) && (flags & UNZ_ENCODING_UTF8) - ? QString::fromUtf8(comment) : p->commentCodec->toUnicode(comment); -} - -bool QuaZip::setCurrentFile(const QString& fileName, CaseSensitivity cs) -{ - p->zipError=UNZ_OK; - if(p->mode!=mdUnzip) { - qWarning("QuaZip::setCurrentFile(): ZIP is not open in mdUnzip mode"); - return false; - } - if(fileName.isEmpty()) { - p->hasCurrentFile_f=false; - return true; - } - // Unicode-aware reimplementation of the unzLocateFile function - if(p->unzFile_f==nullptr) { - p->zipError=UNZ_PARAMERROR; - return false; - } - if(fileName.length()>MAX_FILE_NAME_LENGTH) { - p->zipError=UNZ_PARAMERROR; - return false; - } - // Find the file by name - bool sens = convertCaseSensitivity(cs) == Qt::CaseSensitive; - QString lower, current; - if(!sens) lower=fileName.toLower(); - p->hasCurrentFile_f=false; - - // Check the appropriate Map - unz64_file_pos fileDirPos; - fileDirPos.pos_in_zip_directory = 0; - if (sens) { - if (p->directoryCaseSensitive.contains(fileName)) - fileDirPos = p->directoryCaseSensitive.value(fileName); - } else { - if (p->directoryCaseInsensitive.contains(lower)) - fileDirPos = p->directoryCaseInsensitive.value(lower); - } - - if (fileDirPos.pos_in_zip_directory != 0) { - p->zipError = unzGoToFilePos64(p->unzFile_f, &fileDirPos); - p->hasCurrentFile_f = p->zipError == UNZ_OK; - } - - if (p->hasCurrentFile_f) - return p->hasCurrentFile_f; - - // Not mapped yet, start from where we have got to so far - for(bool more=p->goToFirstUnmappedFile(); more; more=goToNextFile()) { - current=getCurrentFileName(); - if(current.isEmpty()) return false; - if(sens) { - if(current==fileName) break; - } else { - if(current.toLower()==lower) break; - } - } - return p->hasCurrentFile_f; -} - -bool QuaZip::goToFirstFile() -{ - p->zipError=UNZ_OK; - if(p->mode!=mdUnzip) { - qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode"); - return false; - } - p->zipError=unzGoToFirstFile(p->unzFile_f); - p->hasCurrentFile_f=p->zipError==UNZ_OK; - return p->hasCurrentFile_f; -} - -bool QuaZip::goToNextFile() -{ - p->zipError=UNZ_OK; - if(p->mode!=mdUnzip) { - qWarning("QuaZip::goToFirstFile(): ZIP is not open in mdUnzip mode"); - return false; - } - p->zipError=unzGoToNextFile(p->unzFile_f); - p->hasCurrentFile_f=p->zipError==UNZ_OK; - if(p->zipError==UNZ_END_OF_LIST_OF_FILE) - p->zipError=UNZ_OK; - return p->hasCurrentFile_f; -} - -bool QuaZip::getCurrentFileInfo(QuaZipFileInfo *info)const -{ - QuaZipFileInfo64 info64; - if (info == nullptr) { // Very unlikely because of the overloads - return false; - } - if (getCurrentFileInfo(&info64)) { - info64.toQuaZipFileInfo(*info); - return true; - } else { - return false; - } -} - -bool QuaZip::getCurrentFileInfo(QuaZipFileInfo64 *info)const -{ - QuaZip *fakeThis=(QuaZip*)this; // non-const - fakeThis->p->zipError=UNZ_OK; - if(p->mode!=mdUnzip) { - qWarning("QuaZip::getCurrentFileInfo(): ZIP is not open in mdUnzip mode"); - return false; - } - unz_file_info64 info_z; - QByteArray fileName; - QByteArray extra; - QByteArray comment; - if(info==nullptr) return false; - if(!isOpen()||!hasCurrentFile()) return false; - if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, &info_z, nullptr, 0, nullptr, 0, nullptr, 0))!=UNZ_OK) - return false; - fileName.resize(info_z.size_filename); - extra.resize(info_z.size_file_extra); - comment.resize(info_z.size_file_comment); - if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, nullptr, - fileName.data(), fileName.size(), - extra.data(), extra.size(), - comment.data(), comment.size()))!=UNZ_OK) - return false; - info->versionCreated=info_z.version; - info->versionNeeded=info_z.version_needed; - info->flags=info_z.flag; - info->method=info_z.compression_method; - info->crc=info_z.crc; - info->compressedSize=info_z.compressed_size; - info->uncompressedSize=info_z.uncompressed_size; - info->diskNumberStart=info_z.disk_num_start; - info->internalAttr=info_z.internal_fa; - info->externalAttr=info_z.external_fa; - info->name=(info->flags & UNZ_ENCODING_UTF8) ? QString::fromUtf8(fileName) : p->fileNameCodec->toUnicode(fileName); - info->comment=(info->flags & UNZ_ENCODING_UTF8) ? QString::fromUtf8(comment) : p->commentCodec->toUnicode(comment); - info->extra=extra; - info->dateTime=QDateTime( - QDate(info_z.tmu_date.tm_year, info_z.tmu_date.tm_mon+1, info_z.tmu_date.tm_mday), - QTime(info_z.tmu_date.tm_hour, info_z.tmu_date.tm_min, info_z.tmu_date.tm_sec)); - // Add to directory map - p->addCurrentFileToDirectoryMap(info->name); - return true; -} - -QString QuaZip::getCurrentFileName()const -{ - QuaZip *fakeThis=(QuaZip*)this; // non-const - fakeThis->p->zipError=UNZ_OK; - if(p->mode!=mdUnzip) { - qWarning("QuaZip::getCurrentFileName(): ZIP is not open in mdUnzip mode"); - return QString(); - } - if(!isOpen()||!hasCurrentFile()) return QString(); - QByteArray fileName(MAX_FILE_NAME_LENGTH, 0); - unz_file_info64 file_info; - if((fakeThis->p->zipError=unzGetCurrentFileInfo64(p->unzFile_f, &file_info, fileName.data(), fileName.size(), - nullptr, 0, nullptr, 0))!=UNZ_OK) - return QString(); - fileName.resize(file_info.size_filename); - QString result = (file_info.flag & UNZ_ENCODING_UTF8) - ? QString::fromUtf8(fileName) : p->fileNameCodec->toUnicode(fileName); - if (result.isEmpty()) - return result; - // Add to directory map - p->addCurrentFileToDirectoryMap(result); - return result; -} - -void QuaZip::setFileNameCodec(QTextCodec *fileNameCodec) -{ - p->fileNameCodec=fileNameCodec; -} - -void QuaZip::setFileNameCodec(const char *fileNameCodecName) -{ - p->fileNameCodec=QTextCodec::codecForName(fileNameCodecName); -} - -void QuaZip::setOsCode(uint osCode) -{ - p->osCode = osCode; -} - -uint QuaZip::getOsCode() const -{ - return p->osCode; -} - -QTextCodec *QuaZip::getFileNameCodec()const -{ - return p->fileNameCodec; -} - -void QuaZip::setCommentCodec(QTextCodec *commentCodec) -{ - p->commentCodec=commentCodec; -} - -void QuaZip::setCommentCodec(const char *commentCodecName) -{ - p->commentCodec=QTextCodec::codecForName(commentCodecName); -} - -QTextCodec *QuaZip::getCommentCodec()const -{ - return p->commentCodec; -} - -QString QuaZip::getZipName() const -{ - return p->zipName; -} - -QIODevice *QuaZip::getIoDevice() const -{ - if (!p->zipName.isEmpty()) // opened by name, using an internal QIODevice - return nullptr; - return p->ioDevice; -} - -QuaZip::Mode QuaZip::getMode()const -{ - return p->mode; -} - -bool QuaZip::isOpen()const -{ - return p->mode!=mdNotOpen; -} - -int QuaZip::getZipError() const -{ - return p->zipError; -} - -void QuaZip::setComment(const QString& comment) -{ - p->comment=comment; -} - -bool QuaZip::hasCurrentFile()const -{ - return p->hasCurrentFile_f; -} - -unzFile QuaZip::getUnzFile() -{ - return p->unzFile_f; -} - -zipFile QuaZip::getZipFile() -{ - return p->zipFile_f; -} - -void QuaZip::setDataDescriptorWritingEnabled(bool enabled) -{ - p->dataDescriptorWritingEnabled = enabled; -} - -bool QuaZip::isDataDescriptorWritingEnabled() const -{ - return p->dataDescriptorWritingEnabled; -} - -template -TFileInfo QuaZip_getFileInfo(QuaZip *zip, bool *ok); - -template<> -QuaZipFileInfo QuaZip_getFileInfo(QuaZip *zip, bool *ok) -{ - QuaZipFileInfo info; - *ok = zip->getCurrentFileInfo(&info); - return info; -} - -template<> -QuaZipFileInfo64 QuaZip_getFileInfo(QuaZip *zip, bool *ok) -{ - QuaZipFileInfo64 info; - *ok = zip->getCurrentFileInfo(&info); - return info; -} - -template<> -QString QuaZip_getFileInfo(QuaZip *zip, bool *ok) -{ - QString name = zip->getCurrentFileName(); - *ok = !name.isEmpty(); - return name; -} - -template -bool QuaZipPrivate::getFileInfoList(QList *result) const -{ - QuaZipPrivate *fakeThis=const_cast(this); - fakeThis->zipError=UNZ_OK; - if (mode!=QuaZip::mdUnzip) { - qWarning("QuaZip::getFileNameList/getFileInfoList(): " - "ZIP is not open in mdUnzip mode"); - return false; - } - QString currentFile; - if (q->hasCurrentFile()) { - currentFile = q->getCurrentFileName(); - } - if (q->goToFirstFile()) { - do { - bool ok; - result->append(QuaZip_getFileInfo(q, &ok)); - if (!ok) - return false; - } while (q->goToNextFile()); - } - if (zipError != UNZ_OK) - return false; - if (currentFile.isEmpty()) { - if (!q->goToFirstFile()) - return false; - } else { - if (!q->setCurrentFile(currentFile)) - return false; - } - return true; -} - -QStringList QuaZip::getFileNameList() const -{ - QStringList list; - if (p->getFileInfoList(&list)) - return list; - else - return QStringList(); -} - -QList QuaZip::getFileInfoList() const -{ - QList list; - if (p->getFileInfoList(&list)) - return list; - else - return QList(); -} - -QList QuaZip::getFileInfoList64() const -{ - QList list; - if (p->getFileInfoList(&list)) - return list; - else - return QList(); -} - -Qt::CaseSensitivity QuaZip::convertCaseSensitivity(QuaZip::CaseSensitivity cs) -{ - if (cs == csDefault) { -#ifdef Q_OS_WIN - return Qt::CaseInsensitive; -#else - return Qt::CaseSensitive; -#endif - } else { - return cs == csSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive; - } -} - -void QuaZip::setDefaultFileNameCodec(QTextCodec *codec) -{ - QuaZipPrivate::defaultFileNameCodec = codec; -} - -void QuaZip::setDefaultFileNameCodec(const char *codecName) -{ - setDefaultFileNameCodec(QTextCodec::codecForName(codecName)); -} - -void QuaZip::setDefaultOsCode(uint osCode) -{ - QuaZipPrivate::defaultOsCode = osCode; -} - -uint QuaZip::getDefaultOsCode() -{ - return QuaZipPrivate::defaultOsCode; -} - -void QuaZip::setZip64Enabled(bool zip64) -{ - p->zip64 = zip64; -} - -bool QuaZip::isZip64Enabled() const -{ - return p->zip64; -} - -void QuaZip::setUtf8Enabled(bool utf8) -{ - p->utf8 = utf8; -} - -bool QuaZip::isUtf8Enabled() const -{ - return p->utf8; -} - -bool QuaZip::isAutoClose() const -{ - return p->autoClose; -} - -void QuaZip::setAutoClose(bool autoClose) const -{ - p->autoClose = autoClose; -} diff --git a/metaforce-gui/quazip/quazip/quazip.h b/metaforce-gui/quazip/quazip/quazip.h deleted file mode 100644 index 486d5885b..000000000 --- a/metaforce-gui/quazip/quazip/quazip.h +++ /dev/null @@ -1,611 +0,0 @@ -#ifndef QUA_ZIP_H -#define QUA_ZIP_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant, see -quazip/(un)zip.h files for details, basically it's zlib license. - **/ - -#include -#include -#include "quazip_qt_compat.h" - -#include "zip.h" -#include "unzip.h" - -#include "quazip_global.h" -#include "quazipfileinfo.h" - -// just in case it will be defined in the later versions of the ZIP/UNZIP -#ifndef UNZ_OPENERROR -// define additional error code -#define UNZ_OPENERROR -1000 -#endif - -class QuaZipPrivate; - -/// ZIP archive. -/** \class QuaZip quazip.h - * This class implements basic interface to the ZIP archive. It can be - * used to read table contents of the ZIP archive and retreiving - * information about the files inside it. - * - * You can also use this class to open files inside archive by passing - * pointer to the instance of this class to the constructor of the - * QuaZipFile class. But see QuaZipFile::QuaZipFile(QuaZip*, QObject*) - * for the possible pitfalls. - * - * This class is indended to provide interface to the ZIP subpackage of - * the ZIP/UNZIP package as well as to the UNZIP subpackage. But - * currently it supports only UNZIP. - * - * The use of this class is simple - just create instance using - * constructor, then set ZIP archive file name using setFile() function - * (if you did not passed the name to the constructor), then open() and - * then use different functions to work with it! Well, if you are - * paranoid, you may also wish to call close before destructing the - * instance, to check for errors on close. - * - * You may also use getUnzFile() and getZipFile() functions to get the - * ZIP archive handle and use it with ZIP/UNZIP package API directly. - * - * This class supports localized file names inside ZIP archive, but you - * have to set up proper codec with setCodec() function. By default, - * locale codec will be used, which is probably ok for UNIX systems, but - * will almost certainly fail with ZIP archives created in Windows. This - * is because Windows ZIP programs have strange habit of using DOS - * encoding for file names in ZIP archives. For example, ZIP archive - * with cyrillic names created in Windows will have file names in \c - * IBM866 encoding instead of \c WINDOWS-1251. I think that calling one - * function is not much trouble, but for true platform independency it - * would be nice to have some mechanism for file name encoding auto - * detection using locale information. Does anyone know a good way to do - * it? - **/ -class QUAZIP_EXPORT QuaZip { - friend class QuaZipPrivate; - public: - /// Useful constants. - enum Constants { - MAX_FILE_NAME_LENGTH=256 /**< Maximum file name length. Taken from - \c UNZ_MAXFILENAMEINZIP constant in - unzip.c. */ - }; - /// Open mode of the ZIP file. - enum Mode { - mdNotOpen, ///< ZIP file is not open. This is the initial mode. - mdUnzip, ///< ZIP file is open for reading files inside it. - mdCreate, ///< ZIP file was created with open() call. - mdAppend, /**< ZIP file was opened in append mode. This refers to - * \c APPEND_STATUS_CREATEAFTER mode in ZIP/UNZIP package - * and means that zip is appended to some existing file - * what is useful when that file contains - * self-extractor code. This is obviously \em not what - * you whant to use to add files to the existing ZIP - * archive. - **/ - mdAdd ///< ZIP file was opened for adding files in the archive. - }; - /// Case sensitivity for the file names. - /** This is what you specify when accessing files in the archive. - * Works perfectly fine with any characters thanks to Qt's great - * unicode support. This is different from ZIP/UNZIP API, where - * only US-ASCII characters was supported. - **/ - enum CaseSensitivity { - csDefault=0, ///< Default for platform. Case sensitive for UNIX, not for Windows. - csSensitive=1, ///< Case sensitive. - csInsensitive=2 ///< Case insensitive. - }; - /// Returns the actual case sensitivity for the specified QuaZip one. - /** - \param cs The value to convert. - \returns If CaseSensitivity::csDefault, then returns the default - file name case sensitivity for the platform. Otherwise, just - returns the appropriate value from the Qt::CaseSensitivity enum. - */ - static Qt::CaseSensitivity convertCaseSensitivity( - CaseSensitivity cs); - private: - QuaZipPrivate *p; - // not (and will not be) implemented - QuaZip(const QuaZip& that); - // not (and will not be) implemented - QuaZip& operator=(const QuaZip& that); - public: - /// Constructs QuaZip object. - /** Call setName() before opening constructed object. */ - QuaZip(); - /// Constructs QuaZip object associated with ZIP file \a zipName. - QuaZip(const QString& zipName); - /// Constructs QuaZip object associated with ZIP file represented by \a ioDevice. - /** The IO device must be seekable, otherwise an error will occur when opening. */ - QuaZip(QIODevice *ioDevice); - /// Destroys QuaZip object. - /** Calls close() if necessary. */ - ~QuaZip(); - /// Opens ZIP file. - /** - * Argument \a mode specifies open mode of the ZIP archive. See Mode - * for details. Note that there is zipOpen2() function in the - * ZIP/UNZIP API which accepts \a globalcomment argument, but it - * does not use it anywhere, so this open() function does not have this - * argument. See setComment() if you need to set global comment. - * - * If the ZIP file is accessed via explicitly set QIODevice, then - * this device is opened in the necessary mode. If the device was - * already opened by some other means, then QuaZip checks if the - * open mode is compatible to the mode needed for the requested operation. - * If necessary, seeking is performed to position the device properly. - * - * \return \c true if successful, \c false otherwise. - * - * \note ZIP/UNZIP API open calls do not return error code - they - * just return \c null indicating an error. But to make things - * easier, quazip.h header defines additional error code \c - * UNZ_ERROROPEN and getZipError() will return it if the open call - * of the ZIP/UNZIP API returns \c null. - * - * Argument \a ioApi specifies IO function set for ZIP/UNZIP - * package to use. See unzip.h, zip.h and ioapi.h for details. Note - * that IO API for QuaZip is different from the original package. - * The file path argument was changed to be of type \c voidpf, and - * QuaZip passes a QIODevice pointer there. This QIODevice is either - * set explicitly via setIoDevice() or the QuaZip(QIODevice*) - * constructor, or it is created internally when opening the archive - * by its file name. The default API (qioapi.cpp) just delegates - * everything to the QIODevice API. Not only this allows to use a - * QIODevice instead of file name, but also has a nice side effect - * of raising the file size limit from 2G to 4G (in non-zip64 archives). - * - * \note If the zip64 support is needed, the ioApi argument \em must be null - * because due to the backwards compatibility issues it can be used to - * provide a 32-bit API only. - * - * \note If the \ref QuaZip::setAutoClose() "no-auto-close" feature is used, - * then the \a ioApi argument \em should be null because the old API - * doesn't support the 'fake close' operation, causing slight memory leaks - * and other possible troubles (like closing the output device in case - * when an error occurs during opening). - * - * In short: just forget about the \a ioApi argument and you'll be - * fine. - **/ - bool open(Mode mode, zlib_filefunc_def *ioApi =nullptr); - /// Closes ZIP file. - /** Call getZipError() to determine if the close was successful. - * - * If the file was opened by name, then the underlying QIODevice is closed - * and deleted. - * - * If the underlying QIODevice was set explicitly using setIoDevice() or - * the appropriate constructor, then it is closed if the auto-close flag - * is set (which it is by default). Call setAutoClose() to clear the - * auto-close flag if this behavior is undesirable. - * - * Since Qt 5.1, the QSaveFile was introduced. It breaks the QIODevice API - * by making close() private and crashing the application if it is called - * from the base class where it is public. It is an excellent example - * of poor design that illustrates why you should never ever break - * an is-a relationship between the base class and a subclass. QuaZip - * works around this bug by checking if the QIODevice is an instance - * of QSaveFile, using qobject_cast<>, and if it is, calls - * QSaveFile::commit() instead of close(). It is a really ugly hack, - * but at least it makes your programs work instead of crashing. Note that - * if the auto-close flag is cleared, then this is a non-issue, and - * commit() isn't called. - */ - void close(); - /// Sets the codec used to encode/decode file names inside archive. - /** This is necessary to access files in the ZIP archive created - * under Windows with non-latin characters in file names. For - * example, file names with cyrillic letters will be in \c IBM866 - * encoding. - **/ - void setFileNameCodec(QTextCodec *fileNameCodec); - /// Sets the codec used to encode/decode file names inside archive. - /** \overload - * Equivalent to calling setFileNameCodec(QTextCodec::codecForName(codecName)); - **/ - void setFileNameCodec(const char *fileNameCodecName); - /// Sets the OS code (highest 8 bits of the “version made by†field) for new files. - /** There is currently no way to specify this for each file individually, - except by calling this function before opening each file. If this function is not called, - then the default OS code will be used. The default code is set by calling - setDefaultOsCode(). The default value at the moment of QuaZip creation will be used. */ - void setOsCode(uint osCode); - /// Returns the OS code for new files. - uint getOsCode() const; - /// Returns the codec used to encode/decode comments inside archive. - QTextCodec* getFileNameCodec() const; - /// Sets the codec used to encode/decode comments inside archive. - /** This codec defaults to locale codec, which is probably ok. - **/ - void setCommentCodec(QTextCodec *commentCodec); - /// Sets the codec used to encode/decode comments inside archive. - /** \overload - * Equivalent to calling setCommentCodec(QTextCodec::codecForName(codecName)); - **/ - void setCommentCodec(const char *commentCodecName); - /// Returns the codec used to encode/decode comments inside archive. - QTextCodec* getCommentCodec() const; - /// Returns the name of the ZIP file. - /** Returns null string if no ZIP file name has been set, for - * example when the QuaZip instance is set up to use a QIODevice - * instead. - * \sa setZipName(), setIoDevice(), getIoDevice() - **/ - QString getZipName() const; - /// Sets the name of the ZIP file. - /** Does nothing if the ZIP file is open. - * - * Does not reset error code returned by getZipError(). - * \sa setIoDevice(), getIoDevice(), getZipName() - **/ - void setZipName(const QString& zipName); - /// Returns the device representing this ZIP file. - /** Returns null string if no device has been set explicitly, for - * example when opening a ZIP file by name. - * \sa setIoDevice(), getZipName(), setZipName() - **/ - QIODevice *getIoDevice() const; - /// Sets the device representing the ZIP file. - /** Does nothing if the ZIP file is open. - * - * Does not reset error code returned by getZipError(). - * \sa getIoDevice(), getZipName(), setZipName() - **/ - void setIoDevice(QIODevice *ioDevice); - /// Returns the mode in which ZIP file was opened. - Mode getMode() const; - /// Returns \c true if ZIP file is open, \c false otherwise. - bool isOpen() const; - /// Returns the error code of the last operation. - /** Returns \c UNZ_OK if the last operation was successful. - * - * Error code resets to \c UNZ_OK every time you call any function - * that accesses something inside ZIP archive, even if it is \c - * const (like getEntriesCount()). open() and close() calls reset - * error code too. See documentation for the specific functions for - * details on error detection. - **/ - int getZipError() const; - /// Returns number of the entries in the ZIP central directory. - /** Returns negative error code in the case of error. The same error - * code will be returned by subsequent getZipError() call. - **/ - int getEntriesCount() const; - /// Returns global comment in the ZIP file. - QString getComment() const; - /// Sets the global comment in the ZIP file. - /** The comment will be written to the archive on close operation. - * QuaZip makes a distinction between a null QByteArray() comment - * and an empty "" comment in the QuaZip::mdAdd mode. - * A null comment is the default and it means "don't change - * the comment". An empty comment removes the original comment. - * - * \sa open() - **/ - void setComment(const QString& comment); - /// Sets the current file to the first file in the archive. - /** Returns \c true on success, \c false otherwise. Call - * getZipError() to get the error code. - **/ - bool goToFirstFile(); - /// Sets the current file to the next file in the archive. - /** Returns \c true on success, \c false otherwise. Call - * getZipError() to determine if there was an error. - * - * Should be used only in QuaZip::mdUnzip mode. - * - * \note If the end of file was reached, getZipError() will return - * \c UNZ_OK instead of \c UNZ_END_OF_LIST_OF_FILE. This is to make - * things like this easier: - * \code - * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { - * // do something - * } - * if(zip.getZipError()==UNZ_OK) { - * // ok, there was no error - * } - * \endcode - **/ - bool goToNextFile(); - /// Sets current file by its name. - /** Returns \c true if successful, \c false otherwise. Argument \a - * cs specifies case sensitivity of the file name. Call - * getZipError() in the case of a failure to get error code. - * - * This is not a wrapper to unzLocateFile() function. That is - * because I had to implement locale-specific case-insensitive - * comparison. - * - * Here are the differences from the original implementation: - * - * - If the file was not found, error code is \c UNZ_OK, not \c - * UNZ_END_OF_LIST_OF_FILE (see also goToNextFile()). - * - If this function fails, it unsets the current file rather than - * resetting it back to what it was before the call. - * - * If \a fileName is null string then this function unsets the - * current file and return \c true. Note that you should close the - * file first if it is open! See - * QuaZipFile::QuaZipFile(QuaZip*,QObject*) for the details. - * - * Should be used only in QuaZip::mdUnzip mode. - * - * \sa setFileNameCodec(), CaseSensitivity - **/ - bool setCurrentFile(const QString& fileName, CaseSensitivity cs =csDefault); - /// Returns \c true if the current file has been set. - bool hasCurrentFile() const; - /// Retrieves information about the current file. - /** Fills the structure pointed by \a info. Returns \c true on - * success, \c false otherwise. In the latter case structure pointed - * by \a info remains untouched. If there was an error, - * getZipError() returns error code. - * - * Should be used only in QuaZip::mdUnzip mode. - * - * Does nothing and returns \c false in any of the following cases. - * - ZIP is not open; - * - ZIP does not have current file. - * - * In both cases getZipError() returns \c UNZ_OK since there - * is no ZIP/UNZIP API call. - * - * This overload doesn't support zip64, but will work OK on zip64 archives - * except that if one of the sizes (compressed or uncompressed) is greater - * than 0xFFFFFFFFu, it will be set to exactly 0xFFFFFFFFu. - * - * \sa getCurrentFileInfo(QuaZipFileInfo64* info)const - * \sa QuaZipFileInfo64::toQuaZipFileInfo(QuaZipFileInfo&)const - **/ - bool getCurrentFileInfo(QuaZipFileInfo* info)const; - /// Retrieves information about the current file. - /** \overload - * - * This function supports zip64. If the archive doesn't use zip64, it is - * completely equivalent to getCurrentFileInfo(QuaZipFileInfo* info) - * except for the argument type. - * - * \sa - **/ - bool getCurrentFileInfo(QuaZipFileInfo64* info)const; - /// Returns the current file name. - /** Equivalent to calling getCurrentFileInfo() and then getting \c - * name field of the QuaZipFileInfo structure, but faster and more - * convenient. - * - * Should be used only in QuaZip::mdUnzip mode. - **/ - QString getCurrentFileName()const; - /// Returns \c unzFile handle. - /** You can use this handle to directly call UNZIP part of the - * ZIP/UNZIP package functions (see unzip.h). - * - * \warning When using the handle returned by this function, please - * keep in mind that QuaZip class is unable to detect any changes - * you make in the ZIP file state (e. g. changing current file, or - * closing the handle). So please do not do anything with this - * handle that is possible to do with the functions of this class. - * Or at least return the handle in the original state before - * calling some another function of this class (including implicit - * destructor calls and calls from the QuaZipFile objects that refer - * to this QuaZip instance!). So if you have changed the current - * file in the ZIP archive - then change it back or you may - * experience some strange behavior or even crashes. - **/ - unzFile getUnzFile(); - /// Returns \c zipFile handle. - /** You can use this handle to directly call ZIP part of the - * ZIP/UNZIP package functions (see zip.h). Warnings about the - * getUnzFile() function also apply to this function. - **/ - zipFile getZipFile(); - /// Changes the data descriptor writing mode. - /** - According to the ZIP format specification, a file inside archive - may have a data descriptor immediately following the file - data. This is reflected by a special flag in the local file header - and in the central directory. By default, QuaZip sets this flag - and writes the data descriptor unless both method and level were - set to 0, in which case it operates in 1.0-compatible mode and - never writes data descriptors. - - By setting this flag to false, it is possible to disable data - descriptor writing, thus increasing compatibility with archive - readers that don't understand this feature of the ZIP file format. - - Setting this flag affects all the QuaZipFile instances that are - opened after this flag is set. - - The data descriptor writing mode is enabled by default. - - Note that if the ZIP archive is written into a QIODevice for which - QIODevice::isSequential() returns \c true, then the data descriptor - is mandatory and will be written even if this flag is set to false. - - \param enabled If \c true, enable local descriptor writing, - disable it otherwise. - - \sa QuaZipFile::isDataDescriptorWritingEnabled() - */ - void setDataDescriptorWritingEnabled(bool enabled); - /// Returns the data descriptor default writing mode. - /** - \sa setDataDescriptorWritingEnabled() - */ - bool isDataDescriptorWritingEnabled() const; - /// Returns a list of files inside the archive. - /** - \return A list of file names or an empty list if there - was an error or if the archive is empty (call getZipError() to - figure out which). - \sa getFileInfoList() - */ - QStringList getFileNameList() const; - /// Returns information list about all files inside the archive. - /** - \return A list of QuaZipFileInfo objects or an empty list if there - was an error or if the archive is empty (call getZipError() to - figure out which). - - This function doesn't support zip64, but will still work with zip64 - archives, converting results using QuaZipFileInfo64::toQuaZipFileInfo(). - If all file sizes are below 4 GB, it will work just fine. - - \sa getFileNameList() - \sa getFileInfoList64() - */ - QList getFileInfoList() const; - /// Returns information list about all files inside the archive. - /** - \overload - - This function supports zip64. - - \sa getFileNameList() - \sa getFileInfoList() - */ - QList getFileInfoList64() const; - /// Enables the zip64 mode. - /** - * @param zip64 If \c true, the zip64 mode is enabled, disabled otherwise. - * - * Once this is enabled, all new files (until the mode is disabled again) - * will be created in the zip64 mode, thus enabling the ability to write - * files larger than 4 GB. By default, the zip64 mode is off due to - * compatibility reasons. - * - * Note that this does not affect the ability to read zip64 archives in any - * way. - * - * \sa isZip64Enabled() - */ - void setZip64Enabled(bool zip64); - /// Returns whether the zip64 mode is enabled. - /** - * @return \c true if and only if the zip64 mode is enabled. - * - * \sa setZip64Enabled() - */ - bool isZip64Enabled() const; - /// Enables the use of UTF-8 encoding for file names and comments text. - /** - * @param utf8 If \c true, the UTF-8 mode is enabled, disabled otherwise. - * - * Once this is enabled, the names of all new files and comments text (until - * the mode is disabled again) will be encoded in UTF-8 encoding, and the - * version to extract will be set to 6.3 (63) in ZIP header. By default, - * the UTF-8 mode is off due to compatibility reasons. - * - * Note that when extracting ZIP archives, the UTF-8 mode is determined from - * ZIP file header, not from this flag. - * - * \sa isUtf8Enabled() - */ - void setUtf8Enabled(bool utf8); - /// Returns whether the UTF-8 encoding mode is enabled. - /** - * @return \c true if and only if the UTF-8 mode is enabled. - * - * \sa setUtf8Enabled() - */ - bool isUtf8Enabled() const; - /// Returns the auto-close flag. - /** - @sa setAutoClose() - */ - bool isAutoClose() const; - /// Sets or unsets the auto-close flag. - /** - By default, QuaZip opens the underlying QIODevice when open() is called, - and closes it when close() is called. In some cases, when the device - is set explicitly using setIoDevice(), it may be desirable to - leave the device open. If the auto-close flag is unset using this method, - then the device isn't closed automatically if it was set explicitly. - - If it is needed to clear this flag, it is recommended to do so before - opening the archive because otherwise QuaZip may close the device - during the open() call if an error is encountered after the device - is opened. - - If the device was not set explicitly, but rather the setZipName() or - the appropriate constructor was used to set the ZIP file name instead, - then the auto-close flag has no effect, and the internal device - is closed nevertheless because there is no other way to close it. - - @sa isAutoClose() - @sa setIoDevice() - */ - void setAutoClose(bool autoClose) const; - /// Sets the default file name codec to use. - /** - * The default codec is used by the constructors, so calling this function - * won't affect the QuaZip instances already created at that moment. - * - * The codec specified here can be overriden by calling setFileNameCodec(). - * If neither function is called, QTextCodec::codecForLocale() will be used - * to decode or encode file names. Use this function with caution if - * the application uses other libraries that depend on QuaZip. Those - * libraries can either call this function by themselves, thus overriding - * your setting or can rely on the default encoding, thus failing - * mysteriously if you change it. For these reasons, it isn't recommended - * to use this function if you are developing a library, not an application. - * Instead, ask your library users to call it in case they need specific - * encoding. - * - * In most cases, using setFileNameCodec() instead is the right choice. - * However, if you depend on third-party code that uses QuaZip, then the - * reasons stated above can actually become a reason to use this function - * in case the third-party code in question fails because it doesn't - * understand the encoding you need and doesn't provide a way to specify it. - * This applies to the JlCompress class as well, as it was contributed and - * doesn't support explicit encoding parameters. - * - * In short: use setFileNameCodec() when you can, resort to - * setDefaultFileNameCodec() when you don't have access to the QuaZip - * instance. - * - * @param codec The codec to use by default. If null, resets to default. - */ - static void setDefaultFileNameCodec(QTextCodec *codec); - /** - * @overload - * Equivalent to calling - * setDefaultFileNameCodec(QTextCodec::codecForName(codecName)). - */ - static void setDefaultFileNameCodec(const char *codecName); - /// Sets default OS code. - /** - * @sa setOsCode() - */ - static void setDefaultOsCode(uint osCode); - /// Returns default OS code. - /** - * @sa getOsCode() - */ - static uint getDefaultOsCode(); -}; - -#endif diff --git a/metaforce-gui/quazip/quazip/quazip.pc.cmakein b/metaforce-gui/quazip/quazip/quazip.pc.cmakein deleted file mode 100644 index b8456d6e4..000000000 --- a/metaforce-gui/quazip/quazip/quazip.pc.cmakein +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=${prefix} -libdir=${prefix}/lib@LIB_SUFFIX@ -includedir=${prefix}/include - -Name: QuaZip-Qt@QUAZIP_QT_MAJOR_VERSION@ -Description: Minizip wrapper library for Qt @QUAZIP_QT_MAJOR_VERSION@.x -Version: @QUAZIP_LIB_VERSION@ -Libs: -l@QUAZIP_LIB_FILE_NAME@ -lz -Cflags: -I${includedir}/@QUAZIP_DIR_NAME@ -I${includedir}/@QUAZIP_INCLUDE_PATH@ -Requires: @QUAZIP_PKGCONFIG_REQUIRES@ diff --git a/metaforce-gui/quazip/quazip/quazip_global.h b/metaforce-gui/quazip/quazip/quazip_global.h deleted file mode 100644 index a7199012c..000000000 --- a/metaforce-gui/quazip/quazip/quazip_global.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef QUAZIP_GLOBAL_H -#define QUAZIP_GLOBAL_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include - -/** - This is automatically defined when building a static library, but when - including QuaZip sources directly into a project, QUAZIP_STATIC should - be defined explicitly to avoid possible troubles with unnecessary - importing/exporting. - */ -#ifdef QUAZIP_STATIC -#define QUAZIP_EXPORT -#else -/** - * When building a DLL with MSVC, QUAZIP_BUILD must be defined. - * qglobal.h takes care of defining Q_DECL_* correctly for msvc/gcc. - */ -#if defined(QUAZIP_BUILD) - #define QUAZIP_EXPORT Q_DECL_EXPORT -#else - #define QUAZIP_EXPORT Q_DECL_IMPORT -#endif -#endif // QUAZIP_STATIC - -#ifdef __GNUC__ -#define QUAZIP_UNUSED __attribute__((__unused__)) -#else -#define QUAZIP_UNUSED -#endif - -#define QUAZIP_EXTRA_NTFS_MAGIC 0x000Au -#define QUAZIP_EXTRA_NTFS_TIME_MAGIC 0x0001u -#define QUAZIP_EXTRA_EXT_TIME_MAGIC 0x5455u -#define QUAZIP_EXTRA_EXT_MOD_TIME_FLAG 1 -#define QUAZIP_EXTRA_EXT_AC_TIME_FLAG 2 -#define QUAZIP_EXTRA_EXT_CR_TIME_FLAG 4 - -#endif // QUAZIP_GLOBAL_H diff --git a/metaforce-gui/quazip/quazip/quazip_qt_compat.h b/metaforce-gui/quazip/quazip/quazip_qt_compat.h deleted file mode 100644 index 48024be56..000000000 --- a/metaforce-gui/quazip/quazip/quazip_qt_compat.h +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef QUAZIP_QT_COMPAT_H -#define QUAZIP_QT_COMPAT_H - -/* - * For some reason, Qt 5.14 and 5.15 introduced a whole mess of seemingly random - * moves and deprecations. To avoid populating code with #ifs, - * we handle this stuff here, as well as some other compatibility issues. - * - * Some includes are repeated just in case we want to split this file later. - */ - -#include -#include - -// Legacy encodings are still everywhere, but the Qt team decided we -// don't need them anymore and moved them out of Core in Qt 6. -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) -# include -#else -# include -#endif - -// QSaveFile terribly breaks the is-a idiom (Liskov substitution principle): -// QSaveFile is-a QIODevice, but it makes close() private and aborts -// if you call it through the base class. Hence this ugly hack: -#if (QT_VERSION >= 0x050100) -#include -inline bool quazip_close(QIODevice *device) { - QSaveFile *file = qobject_cast(device); - if (file != nullptr) { - // We have to call the ugly commit() instead: - return file->commit(); - } else { - device->close(); - return true; - } -} -#else -inline bool quazip_close(QIODevice *device) { - device->close(); - return true; -} -#endif - -// this is yet another stupid move and deprecation -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) -using Qt::SkipEmptyParts; -#else -#include -const auto SkipEmptyParts = QString::SplitBehavior::SkipEmptyParts; -#endif - -// and yet another... (why didn't they just make qSort delegate to std::sort?) -#include -#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)) -#include -template -inline void quazip_sort(T begin, T end, C comparator) { - std::sort(begin, end, comparator); -} -#else -#include -template -inline void quazip_sort(T begin, T end, C comparator) { - qSort(begin, end, comparator); -} -#endif - -// this is a stupid rename... -#include -#include -#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) -inline QDateTime quazip_ctime(const QFileInfo &fi) { - return fi.birthTime(); -} -#else -inline QDateTime quazip_ctime(const QFileInfo &fi) { - return fi.created(); -} -#endif - -// this is just a slightly better alternative -#include -#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) -inline bool quazip_is_symlink(const QFileInfo &fi) { - return fi.isSymbolicLink(); -} -#else -inline bool quazip_is_symlink(const QFileInfo &fi) { - // also detects *.lnk on Windows, but better than nothing - return fi.isSymLink(); -} -#endif - -// I'm not even sure what this one is, but nevertheless -#include -#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)) -inline QString quazip_symlink_target(const QFileInfo &fi) { - return fi.symLinkTarget(); -} -#else -inline QString quazip_symlink_target(const QFileInfo &fi) { - return fi.readLink(); // What's the difference? I've no idea. -} -#endif - -// this is not a deprecation but an improvement, for a change -#include -#if (QT_VERSION >= 0x040700) -inline quint64 quazip_ntfs_ticks(const QDateTime &time, int fineTicks) { - QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC); - return base.msecsTo(time) * 10000 + fineTicks; -} -#else -inline quint64 quazip_ntfs_ticks(const QDateTime &time, int fineTicks) { - QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC); - QDateTime utc = time.toUTC(); - return (static_cast(base.date().daysTo(utc.date())) - * Q_INT64_C(86400000) - + static_cast(base.time().msecsTo(utc.time()))) - * Q_INT64_C(10000) + fineTicks; -} -#endif - -// yet another improvement... -#include -#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) // Yay! Finally a way to get time as qint64! -inline qint64 quazip_to_time64_t(const QDateTime &time) { - return time.toSecsSinceEpoch(); -} -#else -inline qint64 quazip_to_time64_t(const QDateTime &time) { - return static_cast(time.toTime_t()); // 32 bits only, but better than nothing -} -#endif - -#include -// and another stupid move -#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) -const auto quazip_endl = Qt::endl; -#else -const auto quazip_endl = endl; -#endif - -#endif // QUAZIP_QT_COMPAT_H diff --git a/metaforce-gui/quazip/quazip/quazipdir.cpp b/metaforce-gui/quazip/quazip/quazipdir.cpp deleted file mode 100644 index ac819fe47..000000000 --- a/metaforce-gui/quazip/quazip/quazipdir.cpp +++ /dev/null @@ -1,568 +0,0 @@ -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include "quazipdir.h" -#include "quazip_qt_compat.h" - -#include -#include - -/// \cond internal -class QuaZipDirPrivate: public QSharedData { - friend class QuaZipDir; -private: - QuaZipDirPrivate(QuaZip *zip, const QString &dir = QString()): - zip(zip), dir(dir), caseSensitivity(QuaZip::csDefault), - filter(QDir::NoFilter), sorting(QDir::NoSort) {} - QuaZip *zip; - QString dir; - QuaZip::CaseSensitivity caseSensitivity; - QDir::Filters filter; - QStringList nameFilters; - QDir::SortFlags sorting; - template - bool entryInfoList(QStringList nameFilters, QDir::Filters filter, - QDir::SortFlags sort, TFileInfoList &result) const; - inline QString simplePath() const {return QDir::cleanPath(dir);} -}; -/// \endcond - -QuaZipDir::QuaZipDir(const QuaZipDir &that): - d(that.d) -{ -} - -QuaZipDir::QuaZipDir(QuaZip *zip, const QString &dir): - d(new QuaZipDirPrivate(zip, dir)) -{ - if (d->dir.startsWith(QLatin1String("/"))) - d->dir = d->dir.mid(1); -} - -QuaZipDir::~QuaZipDir() -{ -} - -bool QuaZipDir::operator==(const QuaZipDir &that) -{ - return d->zip == that.d->zip && d->dir == that.d->dir; -} - -QuaZipDir& QuaZipDir::operator=(const QuaZipDir &that) -{ - this->d = that.d; - return *this; -} - -QString QuaZipDir::operator[](int pos) const -{ - return entryList().at(pos); -} - -QuaZip::CaseSensitivity QuaZipDir::caseSensitivity() const -{ - return d->caseSensitivity; -} - -bool QuaZipDir::cd(const QString &directoryName) -{ - if (directoryName == QLatin1String("/")) { - d->dir = QLatin1String(""); - return true; - } - QString dirName = directoryName; - if (dirName.endsWith(QLatin1String("/"))) - dirName.chop(1); - if (dirName.contains(QLatin1String("/"))) { - QuaZipDir dir(*this); - if (dirName.startsWith(QLatin1String("/"))) { -#ifdef QUAZIP_QUAZIPDIR_DEBUG - qDebug("QuaZipDir::cd(%s): going to /", - dirName.toUtf8().constData()); -#endif - if (!dir.cd(QLatin1String("/"))) - return false; - } - QStringList path = dirName.split(QLatin1String("/"), SkipEmptyParts); - for (QStringList::const_iterator i = path.constBegin(); - i != path.constEnd(); - ++i) { - const QString &step = *i; -#ifdef QUAZIP_QUAZIPDIR_DEBUG - qDebug("QuaZipDir::cd(%s): going to %s", - dirName.toUtf8().constData(), - step.toUtf8().constData()); -#endif - if (!dir.cd(step)) - return false; - } - d->dir = dir.path(); - return true; - } else { // no '/' - if (dirName == QLatin1String(".")) { - return true; - } else if (dirName == QLatin1String("..")) { - if (isRoot()) { - return false; - } else { - int slashPos = d->dir.lastIndexOf(QLatin1String("/")); - if (slashPos == -1) { - d->dir = QLatin1String(""); - } else { - d->dir = d->dir.left(slashPos); - } - return true; - } - } else { // a simple subdirectory - if (exists(dirName)) { - if (isRoot()) - d->dir = dirName; - else - d->dir += QLatin1String("/") + dirName; - return true; - } else { - return false; - } - } - } -} - -bool QuaZipDir::cdUp() -{ - return cd(QLatin1String("..")); -} - -uint QuaZipDir::count() const -{ - return entryList().count(); -} - -QString QuaZipDir::dirName() const -{ - return QDir(d->dir).dirName(); -} - -QuaZipFileInfo64 QuaZipDir_getFileInfo(QuaZip *zip, bool *ok, - const QString &relativeName, - bool isReal) -{ - QuaZipFileInfo64 info; - if (isReal) { - *ok = zip->getCurrentFileInfo(&info); - } else { - *ok = true; - info.compressedSize = 0; - info.crc = 0; - info.diskNumberStart = 0; - info.externalAttr = 0; - info.flags = 0; - info.internalAttr = 0; - info.method = 0; - info.uncompressedSize = 0; - info.versionCreated = info.versionNeeded = 0; - } - info.name = relativeName; - return info; -} - -static void QuaZipDir_convertInfoList(const QList &from, - QList &to) -{ - to = from; -} - -static void QuaZipDir_convertInfoList(const QList &from, - QStringList &to) -{ - to.clear(); - for (QList::const_iterator i = from.constBegin(); - i != from.constEnd(); - ++i) { - to.append(i->name); - } -} - -static void QuaZipDir_convertInfoList(const QList &from, - QList &to) -{ - to.clear(); - for (QList::const_iterator i = from.constBegin(); - i != from.constEnd(); - ++i) { - QuaZipFileInfo info32; - i->toQuaZipFileInfo(info32); - to.append(info32); - } -} - -/// \cond internal -/** - An utility class to restore the current file. - */ -class QuaZipDirRestoreCurrent { -public: - inline QuaZipDirRestoreCurrent(QuaZip *zip): - zip(zip), currentFile(zip->getCurrentFileName()) {} - inline ~QuaZipDirRestoreCurrent() - { - zip->setCurrentFile(currentFile); - } -private: - QuaZip *zip; - QString currentFile; -}; -/// \endcond - -/// \cond internal -class QuaZipDirComparator -{ - private: - QDir::SortFlags sort; - static QString getExtension(const QString &name); - int compareStrings(const QString &string1, const QString &string2); - public: - inline QuaZipDirComparator(QDir::SortFlags sort): sort(sort) {} - bool operator()(const QuaZipFileInfo64 &info1, const QuaZipFileInfo64 &info2); -}; - -QString QuaZipDirComparator::getExtension(const QString &name) -{ - if (name.endsWith(QLatin1String(".")) || name.indexOf(QLatin1String("."), 1) == -1) { - return QLatin1String(""); - } else { - return name.mid(name.lastIndexOf(QLatin1String(".")) + 1); - } - -} - -int QuaZipDirComparator::compareStrings(const QString &string1, - const QString &string2) -{ - if (sort & QDir::LocaleAware) { - if (sort & QDir::IgnoreCase) { - return string1.toLower().localeAwareCompare(string2.toLower()); - } else { - return string1.localeAwareCompare(string2); - } - } else { - return string1.compare(string2, (sort & QDir::IgnoreCase) - ? Qt::CaseInsensitive : Qt::CaseSensitive); - } -} - -bool QuaZipDirComparator::operator()(const QuaZipFileInfo64 &info1, - const QuaZipFileInfo64 &info2) -{ - QDir::SortFlags order = sort - & (QDir::Name | QDir::Time | QDir::Size | QDir::Type); - if ((sort & QDir::DirsFirst) == QDir::DirsFirst - || (sort & QDir::DirsLast) == QDir::DirsLast) { - if (info1.name.endsWith(QLatin1String("/")) && !info2.name.endsWith(QLatin1String("/"))) - return (sort & QDir::DirsFirst) == QDir::DirsFirst; - else if (!info1.name.endsWith(QLatin1String("/")) && info2.name.endsWith(QLatin1String("/"))) - return (sort & QDir::DirsLast) == QDir::DirsLast; - } - bool result; - int extDiff; - switch (order) { - case QDir::Name: - result = compareStrings(info1.name, info2.name) < 0; - break; - case QDir::Type: - extDiff = compareStrings(getExtension(info1.name), - getExtension(info2.name)); - if (extDiff == 0) { - result = compareStrings(info1.name, info2.name) < 0; - } else { - result = extDiff < 0; - } - break; - case QDir::Size: - if (info1.uncompressedSize == info2.uncompressedSize) { - result = compareStrings(info1.name, info2.name) < 0; - } else { - result = info1.uncompressedSize < info2.uncompressedSize; - } - break; - case QDir::Time: - if (info1.dateTime == info2.dateTime) { - result = compareStrings(info1.name, info2.name) < 0; - } else { - result = info1.dateTime < info2.dateTime; - } - break; - default: - qWarning("QuaZipDirComparator(): Invalid sort mode 0x%2X", - static_cast(sort)); - return false; - } - return (sort & QDir::Reversed) ? !result : result; -} - -template -bool QuaZipDirPrivate::entryInfoList(QStringList nameFilters, - QDir::Filters filter, QDir::SortFlags sort, TFileInfoList &result) const -{ - QString basePath = simplePath(); - if (!basePath.isEmpty()) - basePath += QLatin1String("/"); - int baseLength = basePath.length(); - result.clear(); - QuaZipDirRestoreCurrent saveCurrent(zip); - if (!zip->goToFirstFile()) { - return zip->getZipError() == UNZ_OK; - } - QDir::Filters fltr = filter; - if (fltr == QDir::NoFilter) - fltr = this->filter; - if (fltr == QDir::NoFilter) - fltr = QDir::AllEntries; - QStringList nmfltr = nameFilters; - if (nmfltr.isEmpty()) - nmfltr = this->nameFilters; - QSet dirsFound; - QList list; - do { - QString name = zip->getCurrentFileName(); - if (!name.startsWith(basePath)) - continue; - QString relativeName = name.mid(baseLength); - if (relativeName.isEmpty()) - continue; - bool isDir = false; - bool isReal = true; - if (relativeName.contains(QLatin1String("/"))) { - int indexOfSlash = relativeName.indexOf(QLatin1String("/")); - // something like "subdir/" - isReal = indexOfSlash == relativeName.length() - 1; - relativeName = relativeName.left(indexOfSlash + 1); - if (dirsFound.contains(relativeName)) - continue; - isDir = true; - } - dirsFound.insert(relativeName); - if ((fltr & QDir::Dirs) == 0 && isDir) - continue; - if ((fltr & QDir::Files) == 0 && !isDir) - continue; - if (!nmfltr.isEmpty() && !QDir::match(nmfltr, relativeName)) - continue; - bool ok; - QuaZipFileInfo64 info = QuaZipDir_getFileInfo(zip, &ok, relativeName, - isReal); - if (!ok) { - return false; - } - list.append(info); - } while (zip->goToNextFile()); - QDir::SortFlags srt = sort; - if (srt == QDir::NoSort) - srt = sorting; -#ifdef QUAZIP_QUAZIPDIR_DEBUG - qDebug("QuaZipDirPrivate::entryInfoList(): before sort:"); - foreach (QuaZipFileInfo64 info, list) { - qDebug("%s\t%s", info.name.toUtf8().constData(), - info.dateTime.toString(Qt::ISODate).toUtf8().constData()); - } -#endif - if (srt != QDir::NoSort && (srt & QDir::Unsorted) != QDir::Unsorted) { - if (QuaZip::convertCaseSensitivity(caseSensitivity) - == Qt::CaseInsensitive) - srt |= QDir::IgnoreCase; - QuaZipDirComparator lessThan(srt); - quazip_sort(list.begin(), list.end(), lessThan); - } - QuaZipDir_convertInfoList(list, result); - return true; -} - -/// \endcond - -QList QuaZipDir::entryInfoList(const QStringList &nameFilters, - QDir::Filters filters, QDir::SortFlags sort) const -{ - QList result; - if (d->entryInfoList(nameFilters, filters, sort, result)) - return result; - else - return QList(); -} - -QList QuaZipDir::entryInfoList(QDir::Filters filters, - QDir::SortFlags sort) const -{ - return entryInfoList(QStringList(), filters, sort); -} - -QList QuaZipDir::entryInfoList64(const QStringList &nameFilters, - QDir::Filters filters, QDir::SortFlags sort) const -{ - QList result; - if (d->entryInfoList(nameFilters, filters, sort, result)) - return result; - else - return QList(); -} - -QList QuaZipDir::entryInfoList64(QDir::Filters filters, - QDir::SortFlags sort) const -{ - return entryInfoList64(QStringList(), filters, sort); -} - -QStringList QuaZipDir::entryList(const QStringList &nameFilters, - QDir::Filters filters, QDir::SortFlags sort) const -{ - QStringList result; - if (d->entryInfoList(nameFilters, filters, sort, result)) - return result; - else - return QStringList(); -} - -QStringList QuaZipDir::entryList(QDir::Filters filters, - QDir::SortFlags sort) const -{ - return entryList(QStringList(), filters, sort); -} - -bool QuaZipDir::exists(const QString &filePath) const -{ - if (filePath == QLatin1String("/") || filePath.isEmpty()) - return true; - QString fileName = filePath; - if (fileName.endsWith(QLatin1String("/"))) - fileName.chop(1); - if (fileName.contains(QLatin1String("/"))) { - QFileInfo fileInfo(fileName); -#ifdef QUAZIP_QUAZIPDIR_DEBUG - qDebug("QuaZipDir::exists(): fileName=%s, fileInfo.fileName()=%s, " - "fileInfo.path()=%s", fileName.toUtf8().constData(), - fileInfo.fileName().toUtf8().constData(), - fileInfo.path().toUtf8().constData()); -#endif - QuaZipDir dir(*this); - return dir.cd(fileInfo.path()) && dir.exists(fileInfo.fileName()); - } else { - if (fileName == QLatin1String("..")) { - return !isRoot(); - } else if (fileName == QLatin1String(".")) { - return true; - } else { - QStringList entries = entryList(QDir::AllEntries, QDir::NoSort); -#ifdef QUAZIP_QUAZIPDIR_DEBUG - qDebug("QuaZipDir::exists(): looking for %s", - fileName.toUtf8().constData()); - for (QStringList::const_iterator i = entries.constBegin(); - i != entries.constEnd(); - ++i) { - qDebug("QuaZipDir::exists(): entry: %s", - i->toUtf8().constData()); - } -#endif - Qt::CaseSensitivity cs = QuaZip::convertCaseSensitivity( - d->caseSensitivity); - if (filePath.endsWith(QLatin1String("/"))) { - return entries.contains(filePath, cs); - } else { - return entries.contains(fileName, cs) - || entries.contains(fileName + QLatin1String("/"), cs); - } - } - } -} - -bool QuaZipDir::exists() const -{ - return QuaZipDir(d->zip).exists(d->dir); -} - -QString QuaZipDir::filePath(const QString &fileName) const -{ - return QDir(d->dir).filePath(fileName); -} - -QDir::Filters QuaZipDir::filter() -{ - return d->filter; -} - -bool QuaZipDir::isRoot() const -{ - return d->simplePath().isEmpty(); -} - -QStringList QuaZipDir::nameFilters() const -{ - return d->nameFilters; -} - -QString QuaZipDir::path() const -{ - return d->dir; -} - -QString QuaZipDir::relativeFilePath(const QString &fileName) const -{ - return QDir(QLatin1String("/") + d->dir).relativeFilePath(fileName); -} - -void QuaZipDir::setCaseSensitivity(QuaZip::CaseSensitivity caseSensitivity) -{ - d->caseSensitivity = caseSensitivity; -} - -void QuaZipDir::setFilter(QDir::Filters filters) -{ - d->filter = filters; -} - -void QuaZipDir::setNameFilters(const QStringList &nameFilters) -{ - d->nameFilters = nameFilters; -} - -void QuaZipDir::setPath(const QString &path) -{ - QString newDir = path; - if (newDir == QLatin1String("/")) { - d->dir = QLatin1String(""); - } else { - if (newDir.endsWith(QLatin1String("/"))) - newDir.chop(1); - if (newDir.startsWith(QLatin1String("/"))) - newDir = newDir.mid(1); - d->dir = newDir; - } -} - -void QuaZipDir::setSorting(QDir::SortFlags sort) -{ - d->sorting = sort; -} - -QDir::SortFlags QuaZipDir::sorting() const -{ - return d->sorting; -} diff --git a/metaforce-gui/quazip/quazip/quazipdir.h b/metaforce-gui/quazip/quazip/quazipdir.h deleted file mode 100644 index a4922b9d3..000000000 --- a/metaforce-gui/quazip/quazip/quazipdir.h +++ /dev/null @@ -1,223 +0,0 @@ -#ifndef QUAZIP_QUAZIPDIR_H -#define QUAZIP_QUAZIPDIR_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -class QuaZipDirPrivate; - -#include "quazip.h" -#include "quazipfileinfo.h" -#include -#include -#include - -/// Provides ZIP archive navigation. -/** -* This class is modelled after QDir, and is designed to provide similar -* features for ZIP archives. -* -* The only significant difference from QDir is that the root path is not -* '/', but an empty string since that's how the file paths are stored in -* the archive. However, QuaZipDir understands the paths starting with -* '/'. It is important in a few places: -* -* - In the cd() function. -* - In the constructor. -* - In the exists() function. -* - In the relativePath() function. -* -* Note that since ZIP uses '/' on all platforms, the '\' separator is -* not supported. -*/ -class QUAZIP_EXPORT QuaZipDir { -private: - QSharedDataPointer d; -public: - /// The copy constructor. - QuaZipDir(const QuaZipDir &that); - /// Constructs a QuaZipDir instance pointing to the specified directory. - /** - If \a dir is not specified, points to the root of the archive. - The same happens if the \a dir is "/". - */ - QuaZipDir(QuaZip *zip, const QString &dir = QString()); - /// Destructor. - ~QuaZipDir(); - /// The assignment operator. - bool operator==(const QuaZipDir &that); - /// operator!= - /** - \return \c true if either this and \a that use different QuaZip - instances or if they point to different directories. - */ - inline bool operator!=(const QuaZipDir &that) {return !operator==(that);} - /// operator== - /** - \return \c true if both this and \a that use the same QuaZip - instance and point to the same directory. - */ - QuaZipDir& operator=(const QuaZipDir &that); - /// Returns the name of the entry at the specified position. - QString operator[](int pos) const; - /// Returns the current case sensitivity mode. - QuaZip::CaseSensitivity caseSensitivity() const; - /// Changes the 'current' directory. - /** - * If the path starts with '/', it is interpreted as an absolute - * path from the root of the archive. Otherwise, it is interpreted - * as a path relative to the current directory as was set by the - * previous cd() or the constructor. - * - * Note that the subsequent path() call will not return a path - * starting with '/' in all cases. - */ - bool cd(const QString &dirName); - /// Goes up. - bool cdUp(); - /// Returns the number of entries in the directory. - uint count() const; - /// Returns the current directory name. - /** - The name doesn't include the path. - */ - QString dirName() const; - /// Returns the list of the entries in the directory. - /** - \param nameFilters The list of file patterns to list, uses the same - syntax as QDir. - \param filters The entry type filters, only Files and Dirs are - accepted. - \param sort Sorting mode. - */ - QList entryInfoList(const QStringList &nameFilters, - QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns the list of the entries in the directory. - /** - \overload - - The same as entryInfoList(QStringList(), filters, sort). - */ - QList entryInfoList(QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns the list of the entries in the directory with zip64 support. - /** - \param nameFilters The list of file patterns to list, uses the same - syntax as QDir. - \param filters The entry type filters, only Files and Dirs are - accepted. - \param sort Sorting mode. - */ - QList entryInfoList64(const QStringList &nameFilters, - QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns the list of the entries in the directory with zip64 support. - /** - \overload - - The same as entryInfoList64(QStringList(), filters, sort). - */ - QList entryInfoList64(QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns the list of the entry names in the directory. - /** - The same as entryInfoList(nameFilters, filters, sort), but only - returns entry names. - */ - QStringList entryList(const QStringList &nameFilters, - QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns the list of the entry names in the directory. - /** - \overload - - The same as entryList(QStringList(), filters, sort). - */ - QStringList entryList(QDir::Filters filters = QDir::NoFilter, - QDir::SortFlags sort = QDir::NoSort) const; - /// Returns \c true if the entry with the specified name exists. - /** - The ".." is considered to exist if the current directory - is not root. The "." and "/" are considered to - always exist. Paths starting with "/" are relative to - the archive root, other paths are relative to the current dir. - */ - bool exists(const QString &fileName) const; - /// Return \c true if the directory pointed by this QuaZipDir exists. - bool exists() const; - /// Returns the full path to the specified file. - /** - Doesn't check if the file actually exists. - */ - QString filePath(const QString &fileName) const; - /// Returns the default filter. - QDir::Filters filter(); - /// Returns if the QuaZipDir points to the root of the archive. - /** - Not that the root path is the empty string, not '/'. - */ - bool isRoot() const; - /// Return the default name filter. - QStringList nameFilters() const; - /// Returns the path to the current dir. - /** - The path never starts with '/', and the root path is an empty - string. - */ - QString path() const; - /// Returns the path to the specified file relative to the current dir. - /** - * This function is mostly useless, provided only for the sake of - * completeness. - * - * @param fileName The path to the file, should start with "/" - * if relative to the archive root. - * @return Path relative to the current dir. - */ - QString relativeFilePath(const QString &fileName) const; - /// Sets the default case sensitivity mode. - void setCaseSensitivity(QuaZip::CaseSensitivity caseSensitivity); - /// Sets the default filter. - void setFilter(QDir::Filters filters); - /// Sets the default name filter. - void setNameFilters(const QStringList &nameFilters); - /// Goes to the specified path. - /** - The difference from cd() is that this function never checks if the - path actually exists and doesn't use relative paths, so it's - possible to go to the root directory with setPath(""). - - Note that this function still chops the trailing and/or leading - '/' and treats a single '/' as the root path (path() will still - return an empty string). - */ - void setPath(const QString &path); - /// Sets the default sorting mode. - void setSorting(QDir::SortFlags sort); - /// Returns the default sorting mode. - QDir::SortFlags sorting() const; -}; - -#endif // QUAZIP_QUAZIPDIR_H diff --git a/metaforce-gui/quazip/quazip/quazipfile.cpp b/metaforce-gui/quazip/quazip/quazipfile.cpp deleted file mode 100644 index d70acf7fe..000000000 --- a/metaforce-gui/quazip/quazip/quazipfile.cpp +++ /dev/null @@ -1,570 +0,0 @@ -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant, see -quazip/(un)zip.h files for details, basically it's zlib license. - **/ - -#include "quazipfile.h" - -#include "quazipfileinfo.h" - -using namespace std; - -#define QUAZIP_VERSION_MADE_BY 0x1Eu - -/// The implementation class for QuaZip. -/** -\internal - -This class contains all the private stuff for the QuaZipFile class, thus -allowing to preserve binary compatibility between releases, the -technique known as the Pimpl (private implementation) idiom. -*/ -class QuaZipFilePrivate { - friend class QuaZipFile; - private: - Q_DISABLE_COPY(QuaZipFilePrivate) - /// The pointer to the associated QuaZipFile instance. - QuaZipFile *q; - /// The QuaZip object to work with. - QuaZip *zip; - /// The file name. - QString fileName; - /// Case sensitivity mode. - QuaZip::CaseSensitivity caseSensitivity; - /// Whether this file is opened in the raw mode. - bool raw; - /// Write position to keep track of. - /** - QIODevice::pos() is broken for non-seekable devices, so we need - our own position. - */ - qint64 writePos; - /// Uncompressed size to write along with a raw file. - quint64 uncompressedSize; - /// CRC to write along with a raw file. - quint32 crc; - /// Whether \ref zip points to an internal QuaZip instance. - /** - This is true if the archive was opened by name, rather than by - supplying an existing QuaZip instance. - */ - bool internal; - /// The last error. - int zipError; - /// Resets \ref zipError. - inline void resetZipError() const {setZipError(UNZ_OK);} - /// Sets the zip error. - /** - This function is marked as const although it changes one field. - This allows to call it from const functions that don't change - anything by themselves. - */ - void setZipError(int zipError) const; - /// The constructor for the corresponding QuaZipFile constructor. - inline QuaZipFilePrivate(QuaZipFile *q): - q(q), - zip(nullptr), - caseSensitivity(QuaZip::csDefault), - raw(false), - writePos(0), - uncompressedSize(0), - crc(0), - internal(true), - zipError(UNZ_OK) {} - /// The constructor for the corresponding QuaZipFile constructor. - inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName): - q(q), - caseSensitivity(QuaZip::csDefault), - raw(false), - writePos(0), - uncompressedSize(0), - crc(0), - internal(true), - zipError(UNZ_OK) - { - zip=new QuaZip(zipName); - } - /// The constructor for the corresponding QuaZipFile constructor. - inline QuaZipFilePrivate(QuaZipFile *q, const QString &zipName, const QString &fileName, - QuaZip::CaseSensitivity cs): - q(q), - raw(false), - writePos(0), - uncompressedSize(0), - crc(0), - internal(true), - zipError(UNZ_OK) - { - zip=new QuaZip(zipName); - this->fileName=fileName; - if (this->fileName.startsWith(QLatin1String("/"))) - this->fileName = this->fileName.mid(1); - this->caseSensitivity=cs; - } - /// The constructor for the QuaZipFile constructor accepting a file name. - inline QuaZipFilePrivate(QuaZipFile *q, QuaZip *zip): - q(q), - zip(zip), - raw(false), - writePos(0), - uncompressedSize(0), - crc(0), - internal(false), - zipError(UNZ_OK) {} - /// The destructor. - inline ~QuaZipFilePrivate() - { - if (internal) - delete zip; - } -}; - -QuaZipFile::QuaZipFile(): - p(new QuaZipFilePrivate(this)) -{ -} - -QuaZipFile::QuaZipFile(QObject *parent): - QIODevice(parent), - p(new QuaZipFilePrivate(this)) -{ -} - -QuaZipFile::QuaZipFile(const QString& zipName, QObject *parent): - QIODevice(parent), - p(new QuaZipFilePrivate(this, zipName)) -{ -} - -QuaZipFile::QuaZipFile(const QString& zipName, const QString& fileName, - QuaZip::CaseSensitivity cs, QObject *parent): - QIODevice(parent), - p(new QuaZipFilePrivate(this, zipName, fileName, cs)) -{ -} - -QuaZipFile::QuaZipFile(QuaZip *zip, QObject *parent): - QIODevice(parent), - p(new QuaZipFilePrivate(this, zip)) -{ -} - -QuaZipFile::~QuaZipFile() -{ - if (isOpen()) - close(); - delete p; -} - -QString QuaZipFile::getZipName() const -{ - return p->zip==nullptr ? QString() : p->zip->getZipName(); -} - -QuaZip *QuaZipFile::getZip() const -{ - return p->internal ? nullptr : p->zip; -} - -QString QuaZipFile::getActualFileName()const -{ - p->setZipError(UNZ_OK); - if (p->zip == nullptr || (openMode() & WriteOnly)) - return QString(); - QString name=p->zip->getCurrentFileName(); - if(name.isNull()) - p->setZipError(p->zip->getZipError()); - return name; -} - -void QuaZipFile::setZipName(const QString& zipName) -{ - if(isOpen()) { - qWarning("QuaZipFile::setZipName(): file is already open - can not set ZIP name"); - return; - } - if(p->zip!=nullptr && p->internal) - delete p->zip; - p->zip=new QuaZip(zipName); - p->internal=true; -} - -void QuaZipFile::setZip(QuaZip *zip) -{ - if(isOpen()) { - qWarning("QuaZipFile::setZip(): file is already open - can not set ZIP"); - return; - } - if(p->zip!=nullptr && p->internal) - delete p->zip; - p->zip=zip; - p->fileName=QString(); - p->internal=false; -} - -void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs) -{ - if(p->zip==nullptr) { - qWarning("QuaZipFile::setFileName(): call setZipName() first"); - return; - } - if(!p->internal) { - qWarning("QuaZipFile::setFileName(): should not be used when not using internal QuaZip"); - return; - } - if(isOpen()) { - qWarning("QuaZipFile::setFileName(): can not set file name for already opened file"); - return; - } - p->fileName=fileName; - if (p->fileName.startsWith(QLatin1String("/"))) - p->fileName = p->fileName.mid(1); - p->caseSensitivity=cs; -} - -void QuaZipFilePrivate::setZipError(int zipError) const -{ - QuaZipFilePrivate *fakeThis = const_cast(this); // non-const - fakeThis->zipError=zipError; - if(zipError==UNZ_OK) - q->setErrorString(QString()); - else - q->setErrorString(QuaZipFile::tr("ZIP/UNZIP API error %1").arg(zipError)); -} - -bool QuaZipFile::open(OpenMode mode) -{ - return open(mode, nullptr); -} - -bool QuaZipFile::open(OpenMode mode, int *method, int *level, bool raw, const char *password) -{ - p->resetZipError(); - if(isOpen()) { - qWarning("QuaZipFile::open(): already opened"); - return false; - } - if(mode&Unbuffered) { - qWarning("QuaZipFile::open(): Unbuffered mode is not supported"); - return false; - } - if((mode&ReadOnly)&&!(mode&WriteOnly)) { - if(p->internal) { - if(!p->zip->open(QuaZip::mdUnzip)) { - p->setZipError(p->zip->getZipError()); - return false; - } - if(!p->zip->setCurrentFile(p->fileName, p->caseSensitivity)) { - p->setZipError(p->zip->getZipError()); - p->zip->close(); - return false; - } - } else { - if(p->zip==nullptr) { - qWarning("QuaZipFile::open(): zip is null"); - return false; - } - if(p->zip->getMode()!=QuaZip::mdUnzip) { - qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d", - (int)mode, (int)p->zip->getMode()); - return false; - } - if(!p->zip->hasCurrentFile()) { - qWarning("QuaZipFile::open(): zip does not have current file"); - return false; - } - } - p->setZipError(unzOpenCurrentFile3(p->zip->getUnzFile(), method, level, (int)raw, password)); - if(p->zipError==UNZ_OK) { - setOpenMode(mode); - p->raw=raw; - return true; - } else - return false; - } - qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode); - return false; -} - -bool QuaZipFile::open(OpenMode mode, const QuaZipNewInfo& info, - const char *password, quint32 crc, - int method, int level, bool raw, - int windowBits, int memLevel, int strategy) -{ - zip_fileinfo info_z; - p->resetZipError(); - if(isOpen()) { - qWarning("QuaZipFile::open(): already opened"); - return false; - } - if((mode&WriteOnly)&&!(mode&ReadOnly)) { - if(p->internal) { - qWarning("QuaZipFile::open(): write mode is incompatible with internal QuaZip approach"); - return false; - } - if(p->zip==nullptr) { - qWarning("QuaZipFile::open(): zip is null"); - return false; - } - if(p->zip->getMode()!=QuaZip::mdCreate&&p->zip->getMode()!=QuaZip::mdAppend&&p->zip->getMode()!=QuaZip::mdAdd) { - qWarning("QuaZipFile::open(): file open mode %d incompatible with ZIP open mode %d", - (int)mode, (int)p->zip->getMode()); - return false; - } - info_z.tmz_date.tm_year=info.dateTime.date().year(); - info_z.tmz_date.tm_mon=info.dateTime.date().month() - 1; - info_z.tmz_date.tm_mday=info.dateTime.date().day(); - info_z.tmz_date.tm_hour=info.dateTime.time().hour(); - info_z.tmz_date.tm_min=info.dateTime.time().minute(); - info_z.tmz_date.tm_sec=info.dateTime.time().second(); - info_z.dosDate = 0; - info_z.internal_fa=(uLong)info.internalAttr; - info_z.external_fa=(uLong)info.externalAttr; - if (p->zip->isDataDescriptorWritingEnabled()) - zipSetFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR); - else - zipClearFlags(p->zip->getZipFile(), ZIP_WRITE_DATA_DESCRIPTOR); - p->setZipError(zipOpenNewFileInZip4_64(p->zip->getZipFile(), - p->zip->isUtf8Enabled() - ? info.name.toUtf8().constData() - : p->zip->getFileNameCodec()->fromUnicode(info.name).constData(), - &info_z, - info.extraLocal.constData(), info.extraLocal.length(), - info.extraGlobal.constData(), info.extraGlobal.length(), - p->zip->isUtf8Enabled() - ? info.comment.toUtf8().constData() - : p->zip->getCommentCodec()->fromUnicode(info.comment).constData(), - method, level, (int)raw, - windowBits, memLevel, strategy, - password, (uLong)crc, - (p->zip->getOsCode() << 8) | QUAZIP_VERSION_MADE_BY, - 0, - p->zip->isZip64Enabled())); - if(p->zipError==UNZ_OK) { - p->writePos=0; - setOpenMode(mode); - p->raw=raw; - if(raw) { - p->crc=crc; - p->uncompressedSize=info.uncompressedSize; - } - return true; - } else - return false; - } - qWarning("QuaZipFile::open(): open mode %d not supported by this function", (int)mode); - return false; -} - -bool QuaZipFile::isSequential()const -{ - return true; -} - -qint64 QuaZipFile::pos()const -{ - if(p->zip==nullptr) { - qWarning("QuaZipFile::pos(): call setZipName() or setZip() first"); - return -1; - } - if(!isOpen()) { - qWarning("QuaZipFile::pos(): file is not open"); - return -1; - } - if(openMode()&ReadOnly) - // QIODevice::pos() is broken for sequential devices, - // but thankfully bytesAvailable() returns the number of - // bytes buffered, so we know how far ahead we are. - return unztell64(p->zip->getUnzFile()) - QIODevice::bytesAvailable(); - else - return p->writePos; -} - -bool QuaZipFile::atEnd()const -{ - if(p->zip==nullptr) { - qWarning("QuaZipFile::atEnd(): call setZipName() or setZip() first"); - return false; - } - if(!isOpen()) { - qWarning("QuaZipFile::atEnd(): file is not open"); - return false; - } - if(openMode()&ReadOnly) - // the same problem as with pos() - return QIODevice::bytesAvailable() == 0 - && unzeof(p->zip->getUnzFile())==1; - else - return true; -} - -qint64 QuaZipFile::size()const -{ - if(!isOpen()) { - qWarning("QuaZipFile::atEnd(): file is not open"); - return -1; - } - if(openMode()&ReadOnly) - return p->raw?csize():usize(); - else - return p->writePos; -} - -qint64 QuaZipFile::csize()const -{ - unz_file_info64 info_z; - p->setZipError(UNZ_OK); - if(p->zip==nullptr||p->zip->getMode()!=QuaZip::mdUnzip) return -1; - p->setZipError(unzGetCurrentFileInfo64(p->zip->getUnzFile(), &info_z, nullptr, 0, nullptr, 0, nullptr, 0)); - if(p->zipError!=UNZ_OK) - return -1; - return info_z.compressed_size; -} - -qint64 QuaZipFile::usize()const -{ - unz_file_info64 info_z; - p->setZipError(UNZ_OK); - if(p->zip==nullptr||p->zip->getMode()!=QuaZip::mdUnzip) return -1; - p->setZipError(unzGetCurrentFileInfo64(p->zip->getUnzFile(), &info_z, nullptr, 0, nullptr, 0, nullptr, 0)); - if(p->zipError!=UNZ_OK) - return -1; - return info_z.uncompressed_size; -} - -bool QuaZipFile::getFileInfo(QuaZipFileInfo *info) -{ - QuaZipFileInfo64 info64; - if (getFileInfo(&info64)) { - info64.toQuaZipFileInfo(*info); - return true; - } else { - return false; - } -} - -bool QuaZipFile::getFileInfo(QuaZipFileInfo64 *info) -{ - if(p->zip==nullptr||p->zip->getMode()!=QuaZip::mdUnzip) return false; - p->zip->getCurrentFileInfo(info); - p->setZipError(p->zip->getZipError()); - return p->zipError==UNZ_OK; -} - -void QuaZipFile::close() -{ - p->resetZipError(); - if(p->zip==nullptr||!p->zip->isOpen()) return; - if(!isOpen()) { - qWarning("QuaZipFile::close(): file isn't open"); - return; - } - if(openMode()&ReadOnly) - p->setZipError(unzCloseCurrentFile(p->zip->getUnzFile())); - else if(openMode()&WriteOnly) - if(isRaw()) p->setZipError(zipCloseFileInZipRaw64(p->zip->getZipFile(), p->uncompressedSize, p->crc)); - else p->setZipError(zipCloseFileInZip(p->zip->getZipFile())); - else { - qWarning("Wrong open mode: %d", (int)openMode()); - return; - } - if(p->zipError==UNZ_OK) setOpenMode(QIODevice::NotOpen); - else return; - if(p->internal) { - p->zip->close(); - p->setZipError(p->zip->getZipError()); - } -} - -qint64 QuaZipFile::readData(char *data, qint64 maxSize) -{ - p->setZipError(UNZ_OK); - qint64 bytesRead=unzReadCurrentFile(p->zip->getUnzFile(), data, (unsigned)maxSize); - if (bytesRead < 0) { - p->setZipError((int) bytesRead); - return -1; - } - return bytesRead; -} - -qint64 QuaZipFile::writeData(const char* data, qint64 maxSize) -{ - p->setZipError(ZIP_OK); - p->setZipError(zipWriteInFileInZip(p->zip->getZipFile(), data, (uint)maxSize)); - if(p->zipError!=ZIP_OK) return -1; - else { - p->writePos+=maxSize; - return maxSize; - } -} - -QString QuaZipFile::getFileName() const -{ - return p->fileName; -} - -QuaZip::CaseSensitivity QuaZipFile::getCaseSensitivity() const -{ - return p->caseSensitivity; -} - -bool QuaZipFile::isRaw() const -{ - return p->raw; -} - -int QuaZipFile::getZipError() const -{ - return p->zipError; -} - -qint64 QuaZipFile::bytesAvailable() const -{ - return size() - pos(); -} - -QByteArray QuaZipFile::getLocalExtraField() -{ - int size = unzGetLocalExtrafield(p->zip->getUnzFile(), nullptr, 0); - QByteArray extra(size, '\0'); - int err = unzGetLocalExtrafield(p->zip->getUnzFile(), extra.data(), static_cast(extra.size())); - if (err < 0) { - p->setZipError(err); - return QByteArray(); - } - return extra; -} - -QDateTime QuaZipFile::getExtModTime() -{ - return QuaZipFileInfo64::getExtTime(getLocalExtraField(), QUAZIP_EXTRA_EXT_MOD_TIME_FLAG); -} - -QDateTime QuaZipFile::getExtAcTime() -{ - return QuaZipFileInfo64::getExtTime(getLocalExtraField(), QUAZIP_EXTRA_EXT_AC_TIME_FLAG); -} - -QDateTime QuaZipFile::getExtCrTime() -{ - return QuaZipFileInfo64::getExtTime(getLocalExtraField(), QUAZIP_EXTRA_EXT_CR_TIME_FLAG); -} diff --git a/metaforce-gui/quazip/quazip/quazipfile.h b/metaforce-gui/quazip/quazip/quazipfile.h deleted file mode 100644 index b49c50b9f..000000000 --- a/metaforce-gui/quazip/quazip/quazipfile.h +++ /dev/null @@ -1,508 +0,0 @@ -#ifndef QUA_ZIPFILE_H -#define QUA_ZIPFILE_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant, see -quazip/(un)zip.h files for details, basically it's zlib license. - **/ - -#include - -#include "quazip_global.h" -#include "quazip.h" -#include "quazipnewinfo.h" - -class QuaZipFilePrivate; - -/// A file inside ZIP archive. -/** \class QuaZipFile quazipfile.h - * This is the most interesting class. Not only it provides C++ - * interface to the ZIP/UNZIP package, but also integrates it with Qt by - * subclassing QIODevice. This makes possible to access files inside ZIP - * archive using QTextStream or QDataStream, for example. Actually, this - * is the main purpose of the whole QuaZip library. - * - * You can either use existing QuaZip instance to create instance of - * this class or pass ZIP archive file name to this class, in which case - * it will create internal QuaZip object. See constructors' descriptions - * for details. Writing is only possible with the existing instance. - * - * Note that due to the underlying library's limitation it is not - * possible to use multiple QuaZipFile instances to open several files - * in the same archive at the same time. If you need to write to - * multiple files in parallel, then you should write to temporary files - * first, then pack them all at once when you have finished writing. If - * you need to read multiple files inside the same archive in parallel, - * you should extract them all into a temporary directory first. - * - * \section quazipfile-sequential Sequential or random-access? - * - * At the first thought, QuaZipFile has fixed size, the start and the - * end and should be therefore considered random-access device. But - * there is one major obstacle to making it random-access: ZIP/UNZIP API - * does not support seek() operation and the only way to implement it is - * through reopening the file and re-reading to the required position, - * but this is prohibitively slow. - * - * Therefore, QuaZipFile is considered to be a sequential device. This - * has advantage of availability of the ungetChar() operation (QIODevice - * does not implement it properly for non-sequential devices unless they - * support seek()). Disadvantage is a somewhat strange behaviour of the - * size() and pos() functions. This should be kept in mind while using - * this class. - * - **/ -class QUAZIP_EXPORT QuaZipFile: public QIODevice { - friend class QuaZipFilePrivate; - Q_OBJECT - private: - QuaZipFilePrivate *p; - // these are not supported nor implemented - QuaZipFile(const QuaZipFile& that); - QuaZipFile& operator=(const QuaZipFile& that); - protected: - /// Implementation of the QIODevice::readData(). - qint64 readData(char *data, qint64 maxSize); - /// Implementation of the QIODevice::writeData(). - qint64 writeData(const char *data, qint64 maxSize); - public: - /// Constructs a QuaZipFile instance. - /** You should use setZipName() and setFileName() or setZip() before - * trying to call open() on the constructed object. - **/ - QuaZipFile(); - /// Constructs a QuaZipFile instance. - /** \a parent argument specifies this object's parent object. - * - * You should use setZipName() and setFileName() or setZip() before - * trying to call open() on the constructed object. - **/ - QuaZipFile(QObject *parent); - /// Constructs a QuaZipFile instance. - /** \a parent argument specifies this object's parent object and \a - * zipName specifies ZIP archive file name. - * - * You should use setFileName() before trying to call open() on the - * constructed object. - * - * QuaZipFile constructed by this constructor can be used for read - * only access. Use QuaZipFile(QuaZip*,QObject*) for writing. - **/ - QuaZipFile(const QString& zipName, QObject *parent =nullptr); - /// Constructs a QuaZipFile instance. - /** \a parent argument specifies this object's parent object, \a - * zipName specifies ZIP archive file name and \a fileName and \a cs - * specify a name of the file to open inside archive. - * - * QuaZipFile constructed by this constructor can be used for read - * only access. Use QuaZipFile(QuaZip*,QObject*) for writing. - * - * \sa QuaZip::setCurrentFile() - **/ - QuaZipFile(const QString& zipName, const QString& fileName, - QuaZip::CaseSensitivity cs =QuaZip::csDefault, QObject *parent =nullptr); - /// Constructs a QuaZipFile instance. - /** \a parent argument specifies this object's parent object. - * - * \a zip is the pointer to the existing QuaZip object. This - * QuaZipFile object then can be used to read current file in the - * \a zip or to write to the file inside it. - * - * \warning Using this constructor for reading current file can be - * tricky. Let's take the following example: - * \code - * QuaZip zip("archive.zip"); - * zip.open(QuaZip::mdUnzip); - * zip.setCurrentFile("file-in-archive"); - * QuaZipFile file(&zip); - * file.open(QIODevice::ReadOnly); - * // ok, now we can read from the file - * file.read(somewhere, some); - * zip.setCurrentFile("another-file-in-archive"); // oops... - * QuaZipFile anotherFile(&zip); - * anotherFile.open(QIODevice::ReadOnly); - * anotherFile.read(somewhere, some); // this is still ok... - * file.read(somewhere, some); // and this is NOT - * \endcode - * So, what exactly happens here? When we change current file in the - * \c zip archive, \c file that references it becomes invalid - * (actually, as far as I understand ZIP/UNZIP sources, it becomes - * closed, but QuaZipFile has no means to detect it). - * - * Summary: do not close \c zip object or change its current file as - * long as QuaZipFile is open. Even better - use another constructors - * which create internal QuaZip instances, one per object, and - * therefore do not cause unnecessary trouble. This constructor may - * be useful, though, if you already have a QuaZip instance and do - * not want to access several files at once. Good example: - * \code - * QuaZip zip("archive.zip"); - * zip.open(QuaZip::mdUnzip); - * // first, we need some information about archive itself - * QByteArray comment=zip.getComment(); - * // and now we are going to access files inside it - * QuaZipFile file(&zip); - * for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile()) { - * file.open(QIODevice::ReadOnly); - * // do something cool with file here - * file.close(); // do not forget to close! - * } - * zip.close(); - * \endcode - **/ - QuaZipFile(QuaZip *zip, QObject *parent =nullptr); - /// Destroys a QuaZipFile instance. - /** Closes file if open, destructs internal QuaZip object (if it - * exists and \em is internal, of course). - **/ - virtual ~QuaZipFile(); - /// Returns the ZIP archive file name. - /** If this object was created by passing QuaZip pointer to the - * constructor, this function will return that QuaZip's file name - * (or null string if that object does not have file name yet). - * - * Otherwise, returns associated ZIP archive file name or null - * string if there are no name set yet. - * - * \sa setZipName() getFileName() - **/ - QString getZipName()const; - /// Returns a pointer to the associated QuaZip object. - /** Returns \c NULL if there is no associated QuaZip or it is - * internal (so you will not mess with it). - **/ - QuaZip* getZip()const; - /// Returns file name. - /** This function returns file name you passed to this object either - * by using - * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*) - * or by calling setFileName(). Real name of the file may differ in - * case if you used case-insensitivity. - * - * Returns null string if there is no file name set yet. This is the - * case when this QuaZipFile operates on the existing QuaZip object - * (constructor QuaZipFile(QuaZip*,QObject*) or setZip() was used). - * - * \sa getActualFileName - **/ - QString getFileName() const; - /// Returns case sensitivity of the file name. - /** This function returns case sensitivity argument you passed to - * this object either by using - * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*) - * or by calling setFileName(). - * - * Returns unpredictable value if getFileName() returns null string - * (this is the case when you did not used setFileName() or - * constructor above). - * - * \sa getFileName - **/ - QuaZip::CaseSensitivity getCaseSensitivity() const; - /// Returns the actual file name in the archive. - /** This is \em not a ZIP archive file name, but a name of file inside - * archive. It is not necessary the same name that you have passed - * to the - * QuaZipFile(const QString&,const QString&,QuaZip::CaseSensitivity,QObject*), - * setFileName() or QuaZip::setCurrentFile() - this is the real file - * name inside archive, so it may differ in case if the file name - * search was case-insensitive. - * - * Equivalent to calling getCurrentFileName() on the associated - * QuaZip object. Returns null string if there is no associated - * QuaZip object or if it does not have a current file yet. And this - * is the case if you called setFileName() but did not open the - * file yet. So this is perfectly fine: - * \code - * QuaZipFile file("somezip.zip"); - * file.setFileName("somefile"); - * QString name=file.getName(); // name=="somefile" - * QString actual=file.getActualFileName(); // actual is null string - * file.open(QIODevice::ReadOnly); - * QString actual=file.getActualFileName(); // actual can be "SoMeFiLe" on Windows - * \endcode - * - * \sa getZipName(), getFileName(), QuaZip::CaseSensitivity - **/ - QString getActualFileName()const; - /// Sets the ZIP archive file name. - /** Automatically creates internal QuaZip object and destroys - * previously created internal QuaZip object, if any. - * - * Will do nothing if this file is already open. You must close() it - * first. - **/ - void setZipName(const QString& zipName); - /// Returns \c true if the file was opened in raw mode. - /** If the file is not open, the returned value is undefined. - * - * \sa open(OpenMode,int*,int*,bool,const char*) - **/ - bool isRaw() const; - /// Binds to the existing QuaZip instance. - /** This function destroys internal QuaZip object, if any, and makes - * this QuaZipFile to use current file in the \a zip object for any - * further operations. See QuaZipFile(QuaZip*,QObject*) for the - * possible pitfalls. - * - * Will do nothing if the file is currently open. You must close() - * it first. - **/ - void setZip(QuaZip *zip); - /// Sets the file name. - /** Will do nothing if at least one of the following conditions is - * met: - * - ZIP name has not been set yet (getZipName() returns null - * string). - * - This QuaZipFile is associated with external QuaZip. In this - * case you should call that QuaZip's setCurrentFile() function - * instead! - * - File is already open so setting the name is meaningless. - * - * \sa QuaZip::setCurrentFile - **/ - void setFileName(const QString& fileName, QuaZip::CaseSensitivity cs =QuaZip::csDefault); - /// Opens a file for reading. - /** Returns \c true on success, \c false otherwise. - * Call getZipError() to get error code. - * - * \note Since ZIP/UNZIP API provides buffered reading only, - * QuaZipFile does not support unbuffered reading. So do not pass - * QIODevice::Unbuffered flag in \a mode, or open will fail. - **/ - virtual bool open(OpenMode mode); - /// Opens a file for reading. - /** \overload - * Argument \a password specifies a password to decrypt the file. If - * it is NULL then this function behaves just like open(OpenMode). - **/ - inline bool open(OpenMode mode, const char *password) - {return open(mode, nullptr, nullptr, false, password);} - /// Opens a file for reading. - /** \overload - * Argument \a password specifies a password to decrypt the file. - * - * An integers pointed by \a method and \a level will receive codes - * of the compression method and level used. See unzip.h. - * - * If raw is \c true then no decompression is performed. - * - * \a method should not be \c NULL. \a level can be \c NULL if you - * don't want to know the compression level. - **/ - bool open(OpenMode mode, int *method, int *level, bool raw, const char *password =nullptr); - /// Opens a file for writing. - /** \a info argument specifies information about file. It should at - * least specify a correct file name. Also, it is a good idea to - * specify correct timestamp (by default, current time will be - * used). See QuaZipNewInfo. - * - * The \a password argument specifies the password for crypting. Pass NULL - * if you don't need any crypting. The \a crc argument was supposed - * to be used for crypting too, but then it turned out that it's - * false information, so you need to set it to 0 unless you want to - * use the raw mode (see below). - * - * Arguments \a method and \a level specify compression method and - * level. The only method supported is Z_DEFLATED, but you may also - * specify 0 for no compression. If all of the files in the archive - * use both method 0 and either level 0 is explicitly specified or - * data descriptor writing is disabled with - * QuaZip::setDataDescriptorWritingEnabled(), then the - * resulting archive is supposed to be compatible with the 1.0 ZIP - * format version, should you need that. Except for this, \a level - * has no other effects with method 0. - * - * If \a raw is \c true, no compression is performed. In this case, - * \a crc and uncompressedSize field of the \a info are required. - * - * Arguments \a windowBits, \a memLevel, \a strategy provide zlib - * algorithms tuning. See deflateInit2() in zlib. - **/ - bool open(OpenMode mode, const QuaZipNewInfo& info, - const char *password =nullptr, quint32 crc =0, - int method =Z_DEFLATED, int level =Z_DEFAULT_COMPRESSION, bool raw =false, - int windowBits =-MAX_WBITS, int memLevel =DEF_MEM_LEVEL, int strategy =Z_DEFAULT_STRATEGY); - /// Returns \c true, but \ref quazipfile-sequential "beware"! - virtual bool isSequential()const; - /// Returns current position in the file. - /** Implementation of the QIODevice::pos(). When reading, this - * function is a wrapper to the ZIP/UNZIP unztell(), therefore it is - * unable to keep track of the ungetChar() calls (which is - * non-virtual and therefore is dangerous to reimplement). So if you - * are using ungetChar() feature of the QIODevice, this function - * reports incorrect value until you get back characters which you - * ungot. - * - * When writing, pos() returns number of bytes already written - * (uncompressed unless you use raw mode). - * - * \note Although - * \ref quazipfile-sequential "QuaZipFile is a sequential device" - * and therefore pos() should always return zero, it does not, - * because it would be misguiding. Keep this in mind. - * - * This function returns -1 if the file or archive is not open. - * - * Error code returned by getZipError() is not affected by this - * function call. - **/ - virtual qint64 pos()const; - /// Returns \c true if the end of file was reached. - /** This function returns \c false in the case of error. This means - * that you called this function on either not open file, or a file - * in the not open archive or even on a QuaZipFile instance that - * does not even have QuaZip instance associated. Do not do that - * because there is no means to determine whether \c false is - * returned because of error or because end of file was reached. - * Well, on the other side you may interpret \c false return value - * as "there is no file open to check for end of file and there is - * no end of file therefore". - * - * When writing, this function always returns \c true (because you - * are always writing to the end of file). - * - * Error code returned by getZipError() is not affected by this - * function call. - **/ - virtual bool atEnd()const; - /// Returns file size. - /** This function returns csize() if the file is open for reading in - * raw mode, usize() if it is open for reading in normal mode and - * pos() if it is open for writing. - * - * Returns -1 on error, call getZipError() to get error code. - * - * \note This function returns file size despite that - * \ref quazipfile-sequential "QuaZipFile is considered to be sequential device", - * for which size() should return bytesAvailable() instead. But its - * name would be very misguiding otherwise, so just keep in mind - * this inconsistence. - **/ - virtual qint64 size()const; - /// Returns compressed file size. - /** Equivalent to calling getFileInfo() and then getting - * compressedSize field, but more convenient and faster. - * - * File must be open for reading before calling this function. - * - * Returns -1 on error, call getZipError() to get error code. - **/ - qint64 csize()const; - /// Returns uncompressed file size. - /** Equivalent to calling getFileInfo() and then getting - * uncompressedSize field, but more convenient and faster. See - * getFileInfo() for a warning. - * - * File must be open for reading before calling this function. - * - * Returns -1 on error, call getZipError() to get error code. - **/ - qint64 usize()const; - /// Gets information about current file. - /** This function does the same thing as calling - * QuaZip::getCurrentFileInfo() on the associated QuaZip object, - * but you can not call getCurrentFileInfo() if the associated - * QuaZip is internal (because you do not have access to it), while - * you still can call this function in that case. - * - * File must be open for reading before calling this function. - * - * \return \c false in the case of an error. - * - * This function doesn't support zip64, but will still work fine on zip64 - * archives if file sizes are below 4 GB, otherwise the values will be set - * as if converted using QuaZipFileInfo64::toQuaZipFileInfo(). - * - * \sa getFileInfo(QuaZipFileInfo64*) - **/ - bool getFileInfo(QuaZipFileInfo *info); - /// Gets information about current file with zip64 support. - /** - * @overload - * - * \sa getFileInfo(QuaZipFileInfo*) - */ - bool getFileInfo(QuaZipFileInfo64 *info); - /// Closes the file. - /** Call getZipError() to determine if the close was successful. - **/ - virtual void close(); - /// Returns the error code returned by the last ZIP/UNZIP API call. - int getZipError() const; - /// Returns the number of bytes available for reading. - virtual qint64 bytesAvailable() const; - /// Returns the local extra field - /** - There are two (optional) local extra fields associated with a file. - One is located in the central header and is available along - with the rest of the file information in @ref QuaZipFileInfo64::extra. - Another is located before the file itself, - and is returned by this function. The file must be open first. - - @return the local extra field, or an empty array if there is none - (or file is not open) - */ - QByteArray getLocalExtraField(); - /// Returns the extended modification timestamp - /** - * The getExt*Time() functions only work if there is an extended timestamp - * extra field (ID 0x5455) present. Otherwise, they all return invalid null - * timestamps. - * - * Modification time, but not other times, can also be accessed through - * @ref QuaZipFileInfo64 without the need to open the file first. - * - * @sa dateTime - * @sa QuaZipFileInfo64::getExtModTime() - * @sa getExtAcTime() - * @sa getExtCrTime() - * @return The extended modification time, UTC - */ - QDateTime getExtModTime(); - /// Returns the extended access timestamp - /** - * The getExt*Time() functions only work if there is an extended timestamp - * extra field (ID 0x5455) present. Otherwise, they all return invalid null - * timestamps. - * @sa dateTime - * @sa QuaZipFileInfo64::getExtModTime() - * @sa getExtModTime() - * @sa getExtCrTime() - * @return The extended access time, UTC - */ - QDateTime getExtAcTime(); - /// Returns the extended creation timestamp - /** - * The getExt*Time() functions only work if there is an extended timestamp - * extra field (ID 0x5455) present. Otherwise, they all return invalid null - * timestamps. - * @sa dateTime - * @sa QuaZipFileInfo64::getExtModTime() - * @sa getExtModTime() - * @sa getExtAcTime() - * @return The extended creation time, UTC - */ - QDateTime getExtCrTime(); -}; - -#endif diff --git a/metaforce-gui/quazip/quazip/quazipfileinfo.cpp b/metaforce-gui/quazip/quazip/quazipfileinfo.cpp deleted file mode 100644 index c27ba370c..000000000 --- a/metaforce-gui/quazip/quazip/quazipfileinfo.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include "quazipfileinfo.h" - -#include - -static QFile::Permissions permissionsFromExternalAttr(quint32 externalAttr) { - quint32 uPerm = (externalAttr & 0xFFFF0000u) >> 16; - QFile::Permissions perm; - if ((uPerm & 0400) != 0) - perm |= QFile::ReadOwner; - if ((uPerm & 0200) != 0) - perm |= QFile::WriteOwner; - if ((uPerm & 0100) != 0) - perm |= QFile::ExeOwner; - if ((uPerm & 0040) != 0) - perm |= QFile::ReadGroup; - if ((uPerm & 0020) != 0) - perm |= QFile::WriteGroup; - if ((uPerm & 0010) != 0) - perm |= QFile::ExeGroup; - if ((uPerm & 0004) != 0) - perm |= QFile::ReadOther; - if ((uPerm & 0002) != 0) - perm |= QFile::WriteOther; - if ((uPerm & 0001) != 0) - perm |= QFile::ExeOther; - return perm; - -} - -QFile::Permissions QuaZipFileInfo::getPermissions() const -{ - return permissionsFromExternalAttr(externalAttr); -} - -QFile::Permissions QuaZipFileInfo64::getPermissions() const -{ - return permissionsFromExternalAttr(externalAttr); -} - -bool QuaZipFileInfo64::isSymbolicLink() const -{ - quint32 uPerm = (externalAttr & 0xFFFF0000u) >> 16; - return (uPerm & 0170000) == 0120000; -} - -bool QuaZipFileInfo64::toQuaZipFileInfo(QuaZipFileInfo &info) const -{ - bool noOverflow = true; - info.name = name; - info.versionCreated = versionCreated; - info.versionNeeded = versionNeeded; - info.flags = flags; - info.method = method; - info.dateTime = dateTime; - info.crc = crc; - if (compressedSize > 0xFFFFFFFFu) { - info.compressedSize = 0xFFFFFFFFu; - noOverflow = false; - } else { - info.compressedSize = compressedSize; - } - if (uncompressedSize > 0xFFFFFFFFu) { - info.uncompressedSize = 0xFFFFFFFFu; - noOverflow = false; - } else { - info.uncompressedSize = uncompressedSize; - } - info.diskNumberStart = diskNumberStart; - info.internalAttr = internalAttr; - info.externalAttr = externalAttr; - info.comment = comment; - info.extra = extra; - return noOverflow; -} - -static QDateTime getNTFSTime(const QByteArray &extra, int position, - int *fineTicks) -{ - QDateTime dateTime; - QuaExtraFieldHash extraHash = QuaZipFileInfo64::parseExtraField(extra); - QList ntfsExtraFields = extraHash[QUAZIP_EXTRA_NTFS_MAGIC]; - if (ntfsExtraFields.isEmpty()) - return dateTime; - QByteArray ntfsExtraField = ntfsExtraFields.at(0); - if (ntfsExtraField.length() <= 4) - return dateTime; - QByteArray ntfsAttributes = ntfsExtraField.mid(4); - QuaExtraFieldHash ntfsHash = QuaZipFileInfo64::parseExtraField(ntfsAttributes); - QList ntfsTimeAttributes = ntfsHash[QUAZIP_EXTRA_NTFS_TIME_MAGIC]; - if (ntfsTimeAttributes.isEmpty()) - return dateTime; - QByteArray ntfsTimes = ntfsTimeAttributes.at(0); - if (ntfsTimes.size() < 24) - return dateTime; - QDataStream timeReader(ntfsTimes); - timeReader.setByteOrder(QDataStream::LittleEndian); - timeReader.device()->seek(position); - quint64 time; - timeReader >> time; - if (time == 0) - return dateTime; - QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC); - dateTime = base.addMSecs(time / 10000); - if (fineTicks != nullptr) { - *fineTicks = static_cast(time % 10000); - } - return dateTime; -} - -QDateTime QuaZipFileInfo64::getNTFSmTime(int *fineTicks) const -{ - return getNTFSTime(extra, 0, fineTicks); -} - -QDateTime QuaZipFileInfo64::getNTFSaTime(int *fineTicks) const -{ - return getNTFSTime(extra, 8, fineTicks); -} - -QDateTime QuaZipFileInfo64::getNTFScTime(int *fineTicks) const -{ - return getNTFSTime(extra, 16, fineTicks); -} - -QDateTime QuaZipFileInfo64::getExtTime(const QByteArray &extra, int flag) -{ - QDateTime dateTime; - QuaExtraFieldHash extraHash = QuaZipFileInfo64::parseExtraField(extra); - QList extTimeFields = extraHash[QUAZIP_EXTRA_EXT_TIME_MAGIC]; - if (extTimeFields.isEmpty()) - return dateTime; - QByteArray extTimeField = extTimeFields.at(0); - if (extTimeField.length() < 1) - return dateTime; - QDataStream input(extTimeField); - input.setByteOrder(QDataStream::LittleEndian); - quint8 flags; - input >> flags; - int flagsRemaining = flags; - while (!input.atEnd()) { - int nextFlag = flagsRemaining & -flagsRemaining; - flagsRemaining &= flagsRemaining - 1; - qint32 time; - input >> time; - if (nextFlag == flag) { - QDateTime base(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC); - dateTime = base.addSecs(time); - return dateTime; - } - } - return dateTime; -} - -QDateTime QuaZipFileInfo64::getExtModTime() const -{ - return getExtTime(extra, 1); -} - -QuaExtraFieldHash QuaZipFileInfo64::parseExtraField(const QByteArray &extraField) -{ - QDataStream input(extraField); - input.setByteOrder(QDataStream::LittleEndian); - QHash > result; - while (!input.atEnd()) { - quint16 id, size; - input >> id; - if (input.status() == QDataStream::ReadPastEnd) - return result; - input >> size; - if (input.status() == QDataStream::ReadPastEnd) - return result; - QByteArray data; - data.resize(size); - int read = input.readRawData(data.data(), data.size()); - if (read < data.size()) - return result; - result[id] << data; - } - return result; -} diff --git a/metaforce-gui/quazip/quazip/quazipfileinfo.h b/metaforce-gui/quazip/quazip/quazipfileinfo.h deleted file mode 100644 index 1083f8be7..000000000 --- a/metaforce-gui/quazip/quazip/quazipfileinfo.h +++ /dev/null @@ -1,232 +0,0 @@ -#ifndef QUA_ZIPFILEINFO_H -#define QUA_ZIPFILEINFO_H - -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include -#include -#include -#include - -#include "quazip_global.h" - -/// The typedef to store extra field parse results -typedef QHash > QuaExtraFieldHash; - -/// Information about a file inside archive. -/** - * \deprecated Use QuaZipFileInfo64 instead. Not only it supports large files, - * but also more convenience methods as well. - * - * Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to - * fill this structure. */ -struct QUAZIP_EXPORT QuaZipFileInfo { - /// File name. - QString name; - /// Version created by. - quint16 versionCreated; - /// Version needed to extract. - quint16 versionNeeded; - /// General purpose flags. - quint16 flags; - /// Compression method. - quint16 method; - /// Last modification date and time. - QDateTime dateTime; - /// CRC. - quint32 crc; - /// Compressed file size. - quint32 compressedSize; - /// Uncompressed file size. - quint32 uncompressedSize; - /// Disk number start. - quint16 diskNumberStart; - /// Internal file attributes. - quint16 internalAttr; - /// External file attributes. - quint32 externalAttr; - /// Comment. - QString comment; - /// Extra field. - QByteArray extra; - /// Get the file permissions. - /** - Returns the high 16 bits of external attributes converted to - QFile::Permissions. - */ - QFile::Permissions getPermissions() const; -}; - -/// Information about a file inside archive (with zip64 support). -/** Call QuaZip::getCurrentFileInfo() or QuaZipFile::getFileInfo() to - * fill this structure. */ -struct QUAZIP_EXPORT QuaZipFileInfo64 { - /// File name. - QString name; - /// Version created by. - quint16 versionCreated; - /// Version needed to extract. - quint16 versionNeeded; - /// General purpose flags. - quint16 flags; - /// Compression method. - quint16 method; - /// Last modification date and time. - /** - * This is the time stored in the standard ZIP header. This format only allows - * to store time with 2-second precision, so the seconds will always be even - * and the milliseconds will always be zero. If you need more precise - * date and time, you can try to call the getNTFSmTime() function or - * its siblings, provided that the archive itself contains these NTFS times. - */ - QDateTime dateTime; - /// CRC. - quint32 crc; - /// Compressed file size. - quint64 compressedSize; - /// Uncompressed file size. - quint64 uncompressedSize; - /// Disk number start. - quint16 diskNumberStart; - /// Internal file attributes. - quint16 internalAttr; - /// External file attributes. - quint32 externalAttr; - /// Comment. - QString comment; - /// Extra field. - QByteArray extra; - /// Get the file permissions. - /** - Returns the high 16 bits of external attributes converted to - QFile::Permissions. - */ - QFile::Permissions getPermissions() const; - /// Checks whether the file is a symbolic link. - /** - Returns true iff the highest 16 bits of the external attributes - indicate that the file is a symbolic link according to Unix file mode. - */ - bool isSymbolicLink() const; - /// Converts to QuaZipFileInfo - /** - If any of the fields are greater than 0xFFFFFFFFu, they are set to - 0xFFFFFFFFu exactly, not just truncated. This function should be mainly used - for compatibility with the old code expecting QuaZipFileInfo, in the cases - when it's impossible or otherwise unadvisable (due to ABI compatibility - reasons, for example) to modify that old code to use QuaZipFileInfo64. - - \return \c true if all fields converted correctly, \c false if an overflow - occured. - */ - bool toQuaZipFileInfo(QuaZipFileInfo &info) const; - /// Returns the NTFS modification time - /** - * The getNTFS*Time() functions only work if there is an NTFS extra field - * present. Otherwise, they all return invalid null timestamps. - * @param fineTicks If not null, the fractional part of milliseconds returned - * there, measured in 100-nanosecond ticks. Will be set to - * zero if there is no NTFS extra field. - * @sa dateTime - * @sa getNTFSaTime() - * @sa getNTFScTime() - * @return The NTFS modification time, UTC - */ - QDateTime getNTFSmTime(int *fineTicks = nullptr) const; - /// Returns the NTFS access time - /** - * The getNTFS*Time() functions only work if there is an NTFS extra field - * present. Otherwise, they all return invalid null timestamps. - * @param fineTicks If not null, the fractional part of milliseconds returned - * there, measured in 100-nanosecond ticks. Will be set to - * zero if there is no NTFS extra field. - * @sa dateTime - * @sa getNTFSmTime() - * @sa getNTFScTime() - * @return The NTFS access time, UTC - */ - QDateTime getNTFSaTime(int *fineTicks = nullptr) const; - /// Returns the NTFS creation time - /** - * The getNTFS*Time() functions only work if there is an NTFS extra field - * present. Otherwise, they all return invalid null timestamps. - * @param fineTicks If not null, the fractional part of milliseconds returned - * there, measured in 100-nanosecond ticks. Will be set to - * zero if there is no NTFS extra field. - * @sa dateTime - * @sa getNTFSmTime() - * @sa getNTFSaTime() - * @return The NTFS creation time, UTC - */ - QDateTime getNTFScTime(int *fineTicks = nullptr) const; - /// Returns the extended modification timestamp - /** - * The getExt*Time() functions only work if there is an extended timestamp - * extra field (ID 0x5455) present. Otherwise, they all return invalid null - * timestamps. - * - * QuaZipFileInfo64 only contains the modification time because it's extracted - * from @ref extra, which contains the global extra field, and access and - * creation time are in the local header which can be accessed through - * @ref QuaZipFile. - * - * @sa dateTime - * @sa QuaZipFile::getExtModTime() - * @sa QuaZipFile::getExtAcTime() - * @sa QuaZipFile::getExtCrTime() - * @return The extended modification time, UTC - */ - QDateTime getExtModTime() const; - /// Checks whether the file is encrypted. - bool isEncrypted() const {return (flags & 1) != 0;} - /// Parses extra field - /** - * The returned hash table contains a list of data blocks for every header ID - * in the provided extra field. The number of data blocks in a hash table value - * equals to the number of occurrences of the appropriate header id. In most cases, - * a block with a specific header ID only occurs once, and therefore the returned - * hash table will contain a list consisting of a single element for that header ID. - * - * @param extraField extra field to parse - * @return header id to list of data block hash - */ - static QuaExtraFieldHash parseExtraField(const QByteArray &extraField); - /// Extracts extended time from the extra field - /** - * Utility function used by various getExt*Time() functions, but can be used directly - * if the extra field is obtained elsewhere (from a third party library, for example). - * - * @param extra the extra field for a file - * @param flag 1 - modification time, 2 - access time, 4 - creation time - * @return the extracted time or null QDateTime if not present - * @sa getExtModTime() - * @sa QuaZipFile::getExtModTime() - * @sa QuaZipFile::getExtAcTime() - * @sa QuaZipFile::getExtCrTime() - */ - static QDateTime getExtTime(const QByteArray &extra, int flag); -}; - -#endif diff --git a/metaforce-gui/quazip/quazip/quazipnewinfo.cpp b/metaforce-gui/quazip/quazip/quazipnewinfo.cpp deleted file mode 100644 index a7a4e5741..000000000 --- a/metaforce-gui/quazip/quazip/quazipnewinfo.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/* -Copyright (C) 2005-2014 Sergey A. Tachenov - -This file is part of QuaZip. - -QuaZip is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 2.1 of the License, or -(at your option) any later version. - -QuaZip is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with QuaZip. If not, see . - -See COPYING file for the full LGPL text. - -Original ZIP package is copyrighted by Gilles Vollant and contributors, -see quazip/(un)zip.h files for details. Basically it's the zlib license. -*/ - -#include - -#include "quazipnewinfo.h" -#include "quazip_qt_compat.h" - -#include - -static void QuaZipNewInfo_setPermissions(QuaZipNewInfo *info, - QFile::Permissions perm, bool isDir, bool isSymLink = false) -{ - quint32 uPerm = isDir ? 0040000 : 0100000; - - if ( isSymLink ) { -#ifdef Q_OS_WIN - uPerm = 0200000; -#else - uPerm = 0120000; -#endif - } - - if ((perm & QFile::ReadOwner) != 0) - uPerm |= 0400; - if ((perm & QFile::WriteOwner) != 0) - uPerm |= 0200; - if ((perm & QFile::ExeOwner) != 0) - uPerm |= 0100; - if ((perm & QFile::ReadGroup) != 0) - uPerm |= 0040; - if ((perm & QFile::WriteGroup) != 0) - uPerm |= 0020; - if ((perm & QFile::ExeGroup) != 0) - uPerm |= 0010; - if ((perm & QFile::ReadOther) != 0) - uPerm |= 0004; - if ((perm & QFile::WriteOther) != 0) - uPerm |= 0002; - if ((perm & QFile::ExeOther) != 0) - uPerm |= 0001; - info->externalAttr = (info->externalAttr & ~0xFFFF0000u) | (uPerm << 16); -} - -template -void QuaZipNewInfo_init(QuaZipNewInfo &self, const FileInfo &existing) -{ - self.name = existing.name; - self.dateTime = existing.dateTime; - self.internalAttr = existing.internalAttr; - self.externalAttr = existing.externalAttr; - self.comment = existing.comment; - self.extraLocal = existing.extra; - self.extraGlobal = existing.extra; - self.uncompressedSize = existing.uncompressedSize; -} - -QuaZipNewInfo::QuaZipNewInfo(const QuaZipFileInfo &existing) -{ - QuaZipNewInfo_init(*this, existing); -} - -QuaZipNewInfo::QuaZipNewInfo(const QuaZipFileInfo64 &existing) -{ - QuaZipNewInfo_init(*this, existing); -} - -QuaZipNewInfo::QuaZipNewInfo(const QString& name): - name(name), dateTime(QDateTime::currentDateTime()), internalAttr(0), externalAttr(0), - uncompressedSize(0) -{ -} - -QuaZipNewInfo::QuaZipNewInfo(const QString& name, const QString& file): - name(name), internalAttr(0), externalAttr(0), uncompressedSize(0) -{ - QFileInfo info(file); - QDateTime lm = info.lastModified(); - if (!info.exists()) { - dateTime = QDateTime::currentDateTime(); - } else { - dateTime = lm; - QuaZipNewInfo_setPermissions(this, info.permissions(), info.isDir(), quazip_is_symlink(info)); - } -} - -void QuaZipNewInfo::setFileDateTime(const QString& file) -{ - QFileInfo info(file); - QDateTime lm = info.lastModified(); - if (info.exists()) - dateTime = lm; -} - -void QuaZipNewInfo::setFilePermissions(const QString &file) -{ - QFileInfo info = QFileInfo(file); - QFile::Permissions perm = info.permissions(); - QuaZipNewInfo_setPermissions(this, perm, info.isDir(), quazip_is_symlink(info)); -} - -void QuaZipNewInfo::setPermissions(QFile::Permissions permissions) -{ - QuaZipNewInfo_setPermissions(this, permissions, name.endsWith(QLatin1String("/"))); -} - -void QuaZipNewInfo::setFileNTFSTimes(const QString &fileName) -{ - QFileInfo fi(fileName); - if (!fi.exists()) { - qWarning("QuaZipNewInfo::setFileNTFSTimes(): '%s' doesn't exist", - fileName.toUtf8().constData()); - return; - } - setFileNTFSmTime(fi.lastModified()); - setFileNTFSaTime(fi.lastRead()); - setFileNTFScTime(quazip_ctime(fi)); -} - -static void setNTFSTime(QByteArray &extra, const QDateTime &time, int position, - int fineTicks) { - int ntfsPos = -1, timesPos = -1; - unsigned ntfsLength = 0, ntfsTimesLength = 0; - for (int i = 0; i <= extra.size() - 4; ) { - unsigned type = static_cast(static_cast( - extra.at(i))) - | (static_cast(static_cast( - extra.at(i + 1))) << 8); - i += 2; - unsigned length = static_cast(static_cast( - extra.at(i))) - | (static_cast(static_cast( - extra.at(i + 1))) << 8); - i += 2; - if (type == QUAZIP_EXTRA_NTFS_MAGIC) { - ntfsPos = i - 4; // the beginning of the NTFS record - ntfsLength = length; - if (length <= 4) { - break; // no times in the NTFS record - } - i += 4; // reserved - while (i <= extra.size() - 4) { - unsigned tag = static_cast( - static_cast(extra.at(i))) - | (static_cast( - static_cast(extra.at(i + 1))) - << 8); - i += 2; - unsigned tagsize = static_cast( - static_cast(extra.at(i))) - | (static_cast( - static_cast(extra.at(i + 1))) - << 8); - i += 2; - if (tag == QUAZIP_EXTRA_NTFS_TIME_MAGIC) { - timesPos = i - 4; // the beginning of the NTFS times tag - ntfsTimesLength = tagsize; - break; - } else { - i += tagsize; - } - } - break; // I ain't going to search for yet another NTFS record! - } else { - i += length; - } - } - if (ntfsPos == -1) { - // No NTFS record, need to create one. - ntfsPos = extra.size(); - ntfsLength = 32; - extra.resize(extra.size() + 4 + ntfsLength); - // the NTFS record header - extra[ntfsPos] = static_cast(QUAZIP_EXTRA_NTFS_MAGIC); - extra[ntfsPos + 1] = static_cast(QUAZIP_EXTRA_NTFS_MAGIC >> 8); - extra[ntfsPos + 2] = 32; // the 2-byte size in LittleEndian - extra[ntfsPos + 3] = 0; - // zero the record - memset(extra.data() + ntfsPos + 4, 0, 32); - timesPos = ntfsPos + 8; - // now set the tag data - extra[timesPos] = static_cast(QUAZIP_EXTRA_NTFS_TIME_MAGIC); - extra[timesPos + 1] = static_cast(QUAZIP_EXTRA_NTFS_TIME_MAGIC - >> 8); - // the size: - extra[timesPos + 2] = 24; - extra[timesPos + 3] = 0; - ntfsTimesLength = 24; - } - if (timesPos == -1) { - // No time tag in the NTFS record, need to add one. - timesPos = ntfsPos + 4 + ntfsLength; - extra.resize(extra.size() + 28); - // Now we need to move the rest of the field - // (possibly zero bytes, but memmove() is OK with that). - // 0 ......... ntfsPos .. ntfsPos + 4 ... timesPos - //

- memmove(extra.data() + timesPos + 28, extra.data() + timesPos, - extra.size() - 28 - timesPos); - ntfsLength += 28; - // now set the tag data - extra[timesPos] = static_cast(QUAZIP_EXTRA_NTFS_TIME_MAGIC); - extra[timesPos + 1] = static_cast(QUAZIP_EXTRA_NTFS_TIME_MAGIC - >> 8); - // the size: - extra[timesPos + 2] = 24; - extra[timesPos + 3] = 0; - // zero the record - memset(extra.data() + timesPos + 4, 0, 24); - ntfsTimesLength = 24; - } - if (ntfsTimesLength < 24) { - // Broken times field. OK, this is really unlikely, but just in case... - size_t timesEnd = timesPos + 4 + ntfsTimesLength; - extra.resize(extra.size() + (24 - ntfsTimesLength)); - // Move it! - // 0 ......... timesPos .... timesPos + 4 .. timesEnd - //