////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// THIS IS AUTO-GENERATED CODE.  PLEASE DO NOT EDIT (File bug reports against tools).
///
/// Auto-generated by: Parameter Parser V5.5.1 (2411131018)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxeepromdriver.cpp
/// @brief Auto-generated Chromatix parameter file
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "camxeepromdriver.h"
#include "parametersetmanager.h"

CAMX_NAMESPACE_BEGIN

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// SetValue/GetValue Functions
/// Gets or sets the requested value
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Read enum value
/// @param entry [in] Symbol table entry
/// @param enumValue [out] Enum value to read
/// @param alignment [in] Symbol table byte alignment
/// @return true if successful
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ReadEnum_EndianType(
    ParameterFileSymbolTableEntry* const entry,
    EndianType& enumValue,
    BYTE const alignment)
{
    bool result {false};

    UINT32 uintValue {entry->ReadEnum(&result, alignment)};

    if (result)
    {
        switch (uintValue)
        {
        case static_cast<UINT32>(EndianType::BIG):
            enumValue = EndianType::BIG;
            result    = true;
            break;
        case static_cast<UINT32>(EndianType::LITTLE):
            enumValue = EndianType::LITTLE;
            result    = true;
            break;
        default:
            PARAMETER_LOG_ERROR(entry->SetManager, "Invalid value(% u) converting UINT32 to EndianType", uintValue);
            break;
        }
    }
    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Read enum value
/// @param entry [in] Symbol table entry
/// @param enumValue [out] Enum value to read
/// @param alignment [in] Symbol table byte alignment
/// @return true if successful
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ReadEnum_SignType(
    ParameterFileSymbolTableEntry* const entry,
    SignType& enumValue,
    BYTE const alignment)
{
    bool result {false};

    UINT32 uintValue {entry->ReadEnum(&result, alignment)};

    if (result)
    {
        switch (uintValue)
        {
        case static_cast<UINT32>(SignType::SIGNED):
            enumValue = SignType::SIGNED;
            result    = true;
            break;
        case static_cast<UINT32>(SignType::UNSIGNED):
            enumValue = SignType::UNSIGNED;
            result    = true;
            break;
        default:
            PARAMETER_LOG_ERROR(entry->SetManager, "Invalid value(% u) converting UINT32 to SignType", uintValue);
            break;
        }
    }
    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Read enum value
/// @param entry [in] Symbol table entry
/// @param enumValue [out] Enum value to read
/// @param alignment [in] Symbol table byte alignment
/// @return true if successful
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ReadEnum_AfLensSagType(
    ParameterFileSymbolTableEntry* const entry,
    AfLensSagType& enumValue,
    BYTE const alignment)
{
    bool result {false};

    UINT32 uintValue {entry->ReadEnum(&result, alignment)};

    if (result)
    {
        switch (uintValue)
        {
        case static_cast<UINT32>(AfLensSagType::DEFAULT):
            enumValue = AfLensSagType::DEFAULT;
            result    = true;
            break;
        case static_cast<UINT32>(AfLensSagType::DEG0_OTP):
            enumValue = AfLensSagType::DEG0_OTP;
            result    = true;
            break;
        case static_cast<UINT32>(AfLensSagType::DEG0_AVG):
            enumValue = AfLensSagType::DEG0_AVG;
            result    = true;
            break;
        case static_cast<UINT32>(AfLensSagType::DEG180_OTP):
            enumValue = AfLensSagType::DEG180_OTP;
            result    = true;
            break;
        case static_cast<UINT32>(AfLensSagType::DEG180_AVG):
            enumValue = AfLensSagType::DEG180_AVG;
            result    = true;
            break;
        case static_cast<UINT32>(AfLensSagType::MAX):
            enumValue = AfLensSagType::MAX;
            result    = true;
            break;
        default:
            PARAMETER_LOG_ERROR(entry->SetManager, "Invalid value(% u) converting UINT32 to AfLensSagType", uintValue);
            break;
        }
    }
    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Read enum value
/// @param entry [in] Symbol table entry
/// @param enumValue [out] Enum value to read
/// @param alignment [in] Symbol table byte alignment
/// @return true if successful
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ReadEnum_WBType(
    ParameterFileSymbolTableEntry* const entry,
    WBType& enumValue,
    BYTE const alignment)
{
    bool result {false};

    UINT32 uintValue {entry->ReadEnum(&result, alignment)};

    if (result)
    {
        switch (uintValue)
        {
        case static_cast<UINT32>(WBType::INDIVIDUAL):
            enumValue = WBType::INDIVIDUAL;
            result    = true;
            break;
        case static_cast<UINT32>(WBType::RATIO):
            enumValue = WBType::RATIO;
            result    = true;
            break;
        default:
            PARAMETER_LOG_ERROR(entry->SetManager, "Invalid value(% u) converting UINT32 to WBType", uintValue);
            break;
        }
    }
    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Read enum value
/// @param entry [in] Symbol table entry
/// @param enumValue [out] Enum value to read
/// @param alignment [in] Symbol table byte alignment
/// @return true if successful
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool ReadEnum_EEPROMIlluminantType(
    ParameterFileSymbolTableEntry* const entry,
    EEPROMIlluminantType& enumValue,
    BYTE const alignment)
{
    bool result {false};

    UINT32 uintValue {entry->ReadEnum(&result, alignment)};

    if (result)
    {
        switch (uintValue)
        {
        case static_cast<UINT32>(EEPROMIlluminantType::D65):
            enumValue = EEPROMIlluminantType::D65;
            result    = true;
            break;
        case static_cast<UINT32>(EEPROMIlluminantType::TL84):
            enumValue = EEPROMIlluminantType::TL84;
            result    = true;
            break;
        case static_cast<UINT32>(EEPROMIlluminantType::A):
            enumValue = EEPROMIlluminantType::A;
            result    = true;
            break;
        case static_cast<UINT32>(EEPROMIlluminantType::D50):
            enumValue = EEPROMIlluminantType::D50;
            result    = true;
            break;
        case static_cast<UINT32>(EEPROMIlluminantType::H):
            enumValue = EEPROMIlluminantType::H;
            result    = true;
            break;
        case static_cast<UINT32>(EEPROMIlluminantType::MAX):
            enumValue = EEPROMIlluminantType::MAX;
            result    = true;
            break;
        default:
            PARAMETER_LOG_ERROR(entry->SetManager, "Invalid value(% u) converting UINT32 to EEPROMIlluminantType", uintValue);
            break;
        }
    }
    return result;
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Default Constructor
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EEPROMDriverDataClass::EEPROMDriverDataClass(
    const CHAR* const name)
    : ParameterModule(name, MAJOR, MINOR, PATCH, nullptr)
{
    PARAMETER_INITIALIZE(SymbolTableID);
    PARAMETER_INITIALIZE(module_version);
    PARAMETER_INITIALIZE(slaveInfo);
    PARAMETER_INITIALIZE(memoryMap);
    PARAMETER_INITIALIZE(formatInfo);
    PARAMETER_INITIALIZE(customInfoCount);
    PARAMETER_INITIALIZE(customInfo);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Constructor
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EEPROMDriverDataClass::EEPROMDriverDataClass(
    const CHAR* const name,
    ModuleData* const moduleData)
    : ParameterModule(name, MAJOR, MINOR, PATCH, moduleData)
{
    PARAMETER_INITIALIZE(SymbolTableID);
    PARAMETER_INITIALIZE(module_version);
    PARAMETER_INITIALIZE(slaveInfo);
    PARAMETER_INITIALIZE(memoryMap);
    PARAMETER_INITIALIZE(formatInfo);
    PARAMETER_INITIALIZE(customInfo);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EEPROMDriverDataClass::~EEPROMDriverDataClass()
{
    if (Loaded)
    {
        UnloadModule();
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// GetName
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const CHAR* EEPROMDriverDataClass::GetName(
    const CHAR* const type)
{
    const CHAR* name = type;
    CHAR temp[ParameterFileSymbolTableEntry::TYPE_LEN + 1];
    if (PARAMETER_STRCMP(type, ModuleData::GetType(temp, "EEPROMDriverData")) == 0)
    {
        name = "EEPROMDriverData";
    }
    return name;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load EEPROMSlaveInformation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool EEPROMSlaveInformation::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(EEPROMName);
    PARAMETER_INITIALIZE(slaveAddress);
    PARAMETER_INITIALIZE(regAddrType);
    PARAMETER_INITIALIZE(regDataType);
    PARAMETER_INITIALIZE(i2cFrequencyMode);
    PARAMETER_INITIALIZE(powerUpSequence);
    PARAMETER_INITIALIZE(powerDownSequence);


    // Reading String EEPROMName from symbol table
    {
        UINT32 count = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, count, alignment)
        ParameterFileSymbolTableEntry stringPointerEntryCls;
        ParameterFileSymbolTableEntry* const stringPointerEntry = &stringPointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(stringPointerEntryCls, entry, alignment);
        }
        SYMBOL_TABLE_ENTRY_READ_STRING(stringPointerEntry, result, EEPROMName, count, alignment)
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, slaveAddress, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, regAddrType, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, regDataType, alignment)
    if (result)
    {
        result = ReadEnum_I2CFrequencyMode(entry, i2cFrequencyMode, alignment);
    }
    if (result)
    {
        result = powerUpSequence.Load(entry, alignment);
    }
    if (result)
    {
        result = powerDownSequence.Load(entry, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load MemoryType
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool MemoryType::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(isAvailable);
    PARAMETER_INITIALIZE(endianness);

    SYMBOL_TABLE_ENTRY_READ(entry, result, isAvailable, alignment)
    if (result)
    {
        result = ReadEnum_EndianType(entry, endianness, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load MemoryInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool MemoryInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(offset);
    PARAMETER_INITIALIZE(mask);
    PARAMETER_INITIALIZE(signedness);

    SYMBOL_TABLE_ENTRY_READ(entry, result, offset, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, mask, alignment)
    if (result)
    {
        result = ReadEnum_SignType(entry, signedness, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load AFCalibrationInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool AFCalibrationInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(chartDistanceCM);
    PARAMETER_INITIALIZE(DACValue);

    result = chartDistanceCM.Load(entry, alignment);
    if (result)
    {
        result = DACValue.Load(entry, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load AFInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool AFInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(autoFocusData);
    PARAMETER_INITIALIZE(macro);
    PARAMETER_INITIALIZE(infinity);
    PARAMETER_INITIALIZE(calibrationInfo);
    PARAMETER_INITIALIZE(hall);
    PARAMETER_INITIALIZE(hallBias);
    PARAMETER_INITIALIZE(hallRegisterAddr);
    PARAMETER_INITIALIZE(verticalMacro);
    PARAMETER_INITIALIZE(verticalInfinity);
    PARAMETER_INITIALIZE(horizontalMacro);
    PARAMETER_INITIALIZE(horizontalInfinity);
    PARAMETER_INITIALIZE(macroMargin);
    PARAMETER_INITIALIZE(infinityMargin);
    PARAMETER_INITIALIZE(lensSagCalMac);
    PARAMETER_INITIALIZE(lensSagCalInf);
    PARAMETER_INITIALIZE(otpGravityOfs0to90);
    PARAMETER_INITIALIZE(otpGravityOfs90to180);
    PARAMETER_INITIALIZE(avgGravityOfs0to90);
    PARAMETER_INITIALIZE(avgGravityOfs90to180);
    PARAMETER_INITIALIZE(actuatorIDExists);
    PARAMETER_INITIALIZE(actuatorID);

    result = autoFocusData.Load(entry, alignment);
    if (result)
    {
        result = macro.Load(entry, alignment);
    }
    if (result)
    {
        result = infinity.Load(entry, alignment);
    }

    // Reading Array calibrationInfo from symbol table
    // Do not check result value here because the count value needs to be initialized in this block
    {
        calibrationInfoCount = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, calibrationInfoCount, alignment)
        constexpr const CHAR* const file {__FILE__};
        constexpr INT32 line {LINE_CONST};
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }

        if (result)
        {
            calibrationInfoID = pointerEntry->ID;
            DupObjInfo* calibrationInfoDupInfo = pointerEntry->GetDupObject(calibrationInfoCount, file, line);
            if (calibrationInfoDupInfo != nullptr && calibrationInfoDupInfo->Object != nullptr)
            {
                calibrationInfo = (AFCalibrationInfo*)calibrationInfoDupInfo->Object;
                if (calibrationInfo == nullptr)
                {
                    if (calibrationInfoDupInfo->File != nullptr)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "calibrationInfo duplicate found but object is nullptr: %s:%d, RefCount: %d\n",
                            calibrationInfoDupInfo->File, calibrationInfoDupInfo->Line, calibrationInfoDupInfo->RefCount);
                    }
                    else
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "calibrationInfo duplicate found but Object is nullptr: <nullptr file ptr>:%d, RefCount: %d\n",
                            calibrationInfoDupInfo->Line, calibrationInfoDupInfo->RefCount);
                    }
                }
            }

            if (calibrationInfo == nullptr)
            {
                if (result && calibrationInfoCount > 0)
                {
                    calibrationInfo = PARAMETER_NEW AFCalibrationInfo[calibrationInfoCount];
                    (void)pointerEntry->SetDupObject(calibrationInfo, calibrationInfoCount, file, line);
                }
                if (!result || calibrationInfo == nullptr)
                {
                    if (calibrationInfoCount > 0)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "Failed to allocate calibrationInfo\n");
                    }
                    calibrationInfoCount = 0;
                }
                for (UINT32 i = 0; result && i < calibrationInfoCount; i++)
                {
                    result = calibrationInfo[i].Load(pointerEntry, alignment);
                }
            }
        }
        if (calibrationInfo == nullptr)
        {
            calibrationInfoCount = 0;
        }
    }
    if (result)
    {
        result = hall.Load(entry, alignment);
    }
    if (result)
    {
        result = hallBias.Load(entry, alignment);
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, hallRegisterAddr, alignment)
    if (result)
    {
        result = verticalMacro.Load(entry, alignment);
    }
    if (result)
    {
        result = verticalInfinity.Load(entry, alignment);
    }
    if (result)
    {
        result = horizontalMacro.Load(entry, alignment);
    }
    if (result)
    {
        result = horizontalInfinity.Load(entry, alignment);
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, macroMargin, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, infinityMargin, alignment)
    if (result)
    {
        result = ReadEnum_AfLensSagType(entry, lensSagCalMac, alignment);
    }
    if (result)
    {
        result = ReadEnum_AfLensSagType(entry, lensSagCalInf, alignment);
    }
    if (result)
    {
        result = otpGravityOfs0to90.Load(entry, alignment);
    }
    if (result)
    {
        result = otpGravityOfs90to180.Load(entry, alignment);
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, avgGravityOfs0to90, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, avgGravityOfs90to180, alignment)

    // Reading Optional parameter actuatorID from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, actuatorIDExists, alignment)
        actuatorIDID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && actuatorIDExists)
        {
            if (result)
            {
                result = actuatorID.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(actuatorID);
        }
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load SPCSettingsInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool SPCSettingsInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(dataOffset);
    PARAMETER_INITIALIZE(SPCAddress);
    PARAMETER_INITIALIZE(settingsSize);

    result = dataOffset.Load(entry, alignment);
    SYMBOL_TABLE_ENTRY_READ(entry, result, SPCAddress, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, settingsSize, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load WBlightInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool WBlightInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(illuminantType);
    PARAMETER_INITIALIZE(rValue);
    PARAMETER_INITIALIZE(grValue);
    PARAMETER_INITIALIZE(bValue);
    PARAMETER_INITIALIZE(gbValue);
    PARAMETER_INITIALIZE(rOverGValue);
    PARAMETER_INITIALIZE(bOverGValue);
    PARAMETER_INITIALIZE(grOverGBValue);

    result = ReadEnum_EEPROMIlluminantType(entry, illuminantType, alignment);
    if (result)
    {
        result = rValue.Load(entry, alignment);
    }
    if (result)
    {
        result = grValue.Load(entry, alignment);
    }
    if (result)
    {
        result = bValue.Load(entry, alignment);
    }
    if (result)
    {
        result = gbValue.Load(entry, alignment);
    }
    if (result)
    {
        result = rOverGValue.Load(entry, alignment);
    }
    if (result)
    {
        result = bOverGValue.Load(entry, alignment);
    }
    if (result)
    {
        result = grOverGBValue.Load(entry, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load WBInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool WBInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(WBData);
    PARAMETER_INITIALIZE(datatype);
    PARAMETER_INITIALIZE(lightInfo);
    PARAMETER_INITIALIZE(mirror);
    PARAMETER_INITIALIZE(flip);
    PARAMETER_INITIALIZE(qValue);
    PARAMETER_INITIALIZE(isInvertGROverGB);

    result = WBData.Load(entry, alignment);
    if (result)
    {
        result = ReadEnum_WBType(entry, datatype, alignment);
    }

    // Reading Array lightInfo from symbol table
    // Do not check result value here because the count value needs to be initialized in this block
    {
        lightInfoCount = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, lightInfoCount, alignment)
        constexpr const CHAR* const file {__FILE__};
        constexpr INT32 line {LINE_CONST};
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }

        if (result)
        {
            lightInfoID = pointerEntry->ID;
            DupObjInfo* lightInfoDupInfo = pointerEntry->GetDupObject(lightInfoCount, file, line);
            if (lightInfoDupInfo != nullptr && lightInfoDupInfo->Object != nullptr)
            {
                lightInfo = (WBlightInfo*)lightInfoDupInfo->Object;
                if (lightInfo == nullptr)
                {
                    if (lightInfoDupInfo->File != nullptr)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "lightInfo duplicate found but object is nullptr: %s:%d, RefCount: %d\n",
                            lightInfoDupInfo->File, lightInfoDupInfo->Line, lightInfoDupInfo->RefCount);
                    }
                    else
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "lightInfo duplicate found but Object is nullptr: <nullptr file ptr>:%d, RefCount: %d\n",
                            lightInfoDupInfo->Line, lightInfoDupInfo->RefCount);
                    }
                }
            }

            if (lightInfo == nullptr)
            {
                if (result && lightInfoCount > 0)
                {
                    lightInfo = PARAMETER_NEW WBlightInfo[lightInfoCount];
                    (void)pointerEntry->SetDupObject(lightInfo, lightInfoCount, file, line);
                }
                if (!result || lightInfo == nullptr)
                {
                    if (lightInfoCount > 0)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "Failed to allocate lightInfo\n");
                    }
                    lightInfoCount = 0;
                }
                for (UINT32 i = 0; result && i < lightInfoCount; i++)
                {
                    result = lightInfo[i].Load(pointerEntry, alignment);
                }
            }
        }
        if (lightInfo == nullptr)
        {
            lightInfoCount = 0;
        }
    }
    if (result)
    {
        result = mirror.Load(entry, alignment);
    }
    if (result)
    {
        result = flip.Load(entry, alignment);
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, qValue, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, isInvertGROverGB, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load LSClightInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool LSClightInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(illuminantType);
    PARAMETER_INITIALIZE(rGainMSB);
    PARAMETER_INITIALIZE(rGainLSB);
    PARAMETER_INITIALIZE(grGainMSB);
    PARAMETER_INITIALIZE(grGainLSB);
    PARAMETER_INITIALIZE(gbGainMSB);
    PARAMETER_INITIALIZE(gbGainLSB);
    PARAMETER_INITIALIZE(bGainMSB);
    PARAMETER_INITIALIZE(bGainLSB);

    result = ReadEnum_EEPROMIlluminantType(entry, illuminantType, alignment);
    if (result)
    {
        result = rGainMSB.Load(entry, alignment);
    }
    if (result)
    {
        result = rGainLSB.Load(entry, alignment);
    }
    if (result)
    {
        result = grGainMSB.Load(entry, alignment);
    }
    if (result)
    {
        result = grGainLSB.Load(entry, alignment);
    }
    if (result)
    {
        result = gbGainMSB.Load(entry, alignment);
    }
    if (result)
    {
        result = gbGainLSB.Load(entry, alignment);
    }
    if (result)
    {
        result = bGainMSB.Load(entry, alignment);
    }
    if (result)
    {
        result = bGainLSB.Load(entry, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load LSCInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool LSCInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(LSCData);
    PARAMETER_INITIALIZE(lightInfo);
    PARAMETER_INITIALIZE(meshHWRollOffSize);
    PARAMETER_INITIALIZE(rIncrement);
    PARAMETER_INITIALIZE(grIncrement);
    PARAMETER_INITIALIZE(gbIncrement);
    PARAMETER_INITIALIZE(bIncrement);

    result = LSCData.Load(entry, alignment);

    // Reading Array lightInfo from symbol table
    // Do not check result value here because the count value needs to be initialized in this block
    {
        lightInfoCount = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, lightInfoCount, alignment)
        constexpr const CHAR* const file {__FILE__};
        constexpr INT32 line {LINE_CONST};
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }

        if (result)
        {
            lightInfoID = pointerEntry->ID;
            DupObjInfo* lightInfoDupInfo = pointerEntry->GetDupObject(lightInfoCount, file, line);
            if (lightInfoDupInfo != nullptr && lightInfoDupInfo->Object != nullptr)
            {
                lightInfo = (LSClightInfo*)lightInfoDupInfo->Object;
                if (lightInfo == nullptr)
                {
                    if (lightInfoDupInfo->File != nullptr)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "lightInfo duplicate found but object is nullptr: %s:%d, RefCount: %d\n",
                            lightInfoDupInfo->File, lightInfoDupInfo->Line, lightInfoDupInfo->RefCount);
                    }
                    else
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "lightInfo duplicate found but Object is nullptr: <nullptr file ptr>:%d, RefCount: %d\n",
                            lightInfoDupInfo->Line, lightInfoDupInfo->RefCount);
                    }
                }
            }

            if (lightInfo == nullptr)
            {
                if (result && lightInfoCount > 0)
                {
                    lightInfo = PARAMETER_NEW LSClightInfo[lightInfoCount];
                    (void)pointerEntry->SetDupObject(lightInfo, lightInfoCount, file, line);
                }
                if (!result || lightInfo == nullptr)
                {
                    if (lightInfoCount > 0)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "Failed to allocate lightInfo\n");
                    }
                    lightInfoCount = 0;
                }
                for (UINT32 i = 0; result && i < lightInfoCount; i++)
                {
                    result = lightInfo[i].Load(pointerEntry, alignment);
                }
            }
        }
        if (lightInfo == nullptr)
        {
            lightInfoCount = 0;
        }
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, meshHWRollOffSize, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, rIncrement, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, grIncrement, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, gbIncrement, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, bIncrement, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load AbsoluteMethodAECSyncInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool AbsoluteMethodAECSyncInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(version);
    PARAMETER_INITIALIZE(averageLuma);
    PARAMETER_INITIALIZE(gain);
    PARAMETER_INITIALIZE(exposureTimeUs);

    result = version.Load(entry, alignment);
    if (result)
    {
        result = averageLuma.Load(entry, alignment);
    }
    if (result)
    {
        result = gain.Load(entry, alignment);
    }
    if (result)
    {
        result = exposureTimeUs.Load(entry, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load DualCameraLensInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool DualCameraLensInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(focalLength);
    PARAMETER_INITIALIZE(focalLengthRatio);
    PARAMETER_INITIALIZE(nativeSensorResolutionWidth);
    PARAMETER_INITIALIZE(nativeSensorResolutionHeight);
    PARAMETER_INITIALIZE(calibrationResolutionWidth);
    PARAMETER_INITIALIZE(calibrationResolutionHeight);
    PARAMETER_INITIALIZE(AFSyncInfo);

    result = focalLength.Load(entry, alignment);
    if (result)
    {
        result = focalLengthRatio.Load(entry, alignment);
    }
    if (result)
    {
        result = nativeSensorResolutionWidth.Load(entry, alignment);
    }
    if (result)
    {
        result = nativeSensorResolutionHeight.Load(entry, alignment);
    }
    if (result)
    {
        result = calibrationResolutionWidth.Load(entry, alignment);
    }
    if (result)
    {
        result = calibrationResolutionHeight.Load(entry, alignment);
    }

    // Reading Array AFSyncInfo from symbol table
    // Do not check result value here because the count value needs to be initialized in this block
    {
        AFSyncInfoCount = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, AFSyncInfoCount, alignment)
        constexpr const CHAR* const file {__FILE__};
        constexpr INT32 line {LINE_CONST};
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }

        if (result)
        {
            AFSyncInfoID = pointerEntry->ID;
            DupObjInfo* AFSyncInfoDupInfo = pointerEntry->GetDupObject(AFSyncInfoCount, file, line);
            if (AFSyncInfoDupInfo != nullptr && AFSyncInfoDupInfo->Object != nullptr)
            {
                AFSyncInfo = (AFCalibrationInfo*)AFSyncInfoDupInfo->Object;
                if (AFSyncInfo == nullptr)
                {
                    if (AFSyncInfoDupInfo->File != nullptr)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "AFSyncInfo duplicate found but object is nullptr: %s:%d, RefCount: %d\n",
                            AFSyncInfoDupInfo->File, AFSyncInfoDupInfo->Line, AFSyncInfoDupInfo->RefCount);
                    }
                    else
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "AFSyncInfo duplicate found but Object is nullptr: <nullptr file ptr>:%d, RefCount: %d\n",
                            AFSyncInfoDupInfo->Line, AFSyncInfoDupInfo->RefCount);
                    }
                }
            }

            if (AFSyncInfo == nullptr)
            {
                if (result && AFSyncInfoCount > 0)
                {
                    AFSyncInfo = PARAMETER_NEW AFCalibrationInfo[AFSyncInfoCount];
                    (void)pointerEntry->SetDupObject(AFSyncInfo, AFSyncInfoCount, file, line);
                }
                if (!result || AFSyncInfo == nullptr)
                {
                    if (AFSyncInfoCount > 0)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "Failed to allocate AFSyncInfo\n");
                    }
                    AFSyncInfoCount = 0;
                }
                for (UINT32 i = 0; result && i < AFSyncInfoCount; i++)
                {
                    result = AFSyncInfo[i].Load(pointerEntry, alignment);
                }
            }
        }
        if (AFSyncInfo == nullptr)
        {
            AFSyncInfoCount = 0;
        }
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load DualCameraSystemInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool DualCameraSystemInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(calibrationFormatVersion);
    PARAMETER_INITIALIZE(rotationMatrixSize);
    PARAMETER_INITIALIZE(relativeRotationMatrixOffset);
    PARAMETER_INITIALIZE(geometricMatrixSize);
    PARAMETER_INITIALIZE(relativeGeometricSurfaceParametersOffset);
    PARAMETER_INITIALIZE(relativePrinciplePointX);
    PARAMETER_INITIALIZE(relativePrinciplePointY);
    PARAMETER_INITIALIZE(relativePositionFlag);
    PARAMETER_INITIALIZE(relativeBaselineDistance);
    PARAMETER_INITIALIZE(masterSensorMirrorFlipSetting);
    PARAMETER_INITIALIZE(auxSensorMirrorFlipSetting);
    PARAMETER_INITIALIZE(moduleOrientationFlag);
    PARAMETER_INITIALIZE(rotationFlag);
    PARAMETER_INITIALIZE(brightnessRatioExists);
    PARAMETER_INITIALIZE(brightnessRatio);
    PARAMETER_INITIALIZE(referenceSlaveGainExists);
    PARAMETER_INITIALIZE(referenceSlaveGain);
    PARAMETER_INITIALIZE(referenceSlaveExpTimeExists);
    PARAMETER_INITIALIZE(referenceSlaveExpTime);
    PARAMETER_INITIALIZE(referenceMasterGainExists);
    PARAMETER_INITIALIZE(referenceMasterGain);
    PARAMETER_INITIALIZE(referenceMasterExpTimeExists);
    PARAMETER_INITIALIZE(referenceMasterExpTime);
    PARAMETER_INITIALIZE(referenceMasterColorTempExists);
    PARAMETER_INITIALIZE(referenceMasterColorTemp);
    PARAMETER_INITIALIZE(qValueExists);
    PARAMETER_INITIALIZE(qValue);
    PARAMETER_INITIALIZE(absoluteMethodAECSyncInfoExists);
    PARAMETER_INITIALIZE(absoluteMethodAECSyncInfo);

    result = calibrationFormatVersion.Load(entry, alignment);
    SYMBOL_TABLE_ENTRY_READ(entry, result, rotationMatrixSize, alignment)
    if (result)
    {
        result = relativeRotationMatrixOffset.Load(entry, alignment);
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, geometricMatrixSize, alignment)
    if (result)
    {
        result = relativeGeometricSurfaceParametersOffset.Load(entry, alignment);
    }
    if (result)
    {
        result = relativePrinciplePointX.Load(entry, alignment);
    }
    if (result)
    {
        result = relativePrinciplePointY.Load(entry, alignment);
    }
    if (result)
    {
        result = relativePositionFlag.Load(entry, alignment);
    }
    if (result)
    {
        result = relativeBaselineDistance.Load(entry, alignment);
    }
    if (result)
    {
        result = masterSensorMirrorFlipSetting.Load(entry, alignment);
    }
    if (result)
    {
        result = auxSensorMirrorFlipSetting.Load(entry, alignment);
    }
    if (result)
    {
        result = moduleOrientationFlag.Load(entry, alignment);
    }
    if (result)
    {
        result = rotationFlag.Load(entry, alignment);
    }

    // Reading Optional parameter brightnessRatio from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, brightnessRatioExists, alignment)
        brightnessRatioID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && brightnessRatioExists)
        {
            if (result)
            {
                result = brightnessRatio.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(brightnessRatio);
        }
    }

    // Reading Optional parameter referenceSlaveGain from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, referenceSlaveGainExists, alignment)
        referenceSlaveGainID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && referenceSlaveGainExists)
        {
            if (result)
            {
                result = referenceSlaveGain.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(referenceSlaveGain);
        }
    }

    // Reading Optional parameter referenceSlaveExpTime from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, referenceSlaveExpTimeExists, alignment)
        referenceSlaveExpTimeID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && referenceSlaveExpTimeExists)
        {
            if (result)
            {
                result = referenceSlaveExpTime.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(referenceSlaveExpTime);
        }
    }

    // Reading Optional parameter referenceMasterGain from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, referenceMasterGainExists, alignment)
        referenceMasterGainID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && referenceMasterGainExists)
        {
            if (result)
            {
                result = referenceMasterGain.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(referenceMasterGain);
        }
    }

    // Reading Optional parameter referenceMasterExpTime from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, referenceMasterExpTimeExists, alignment)
        referenceMasterExpTimeID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && referenceMasterExpTimeExists)
        {
            if (result)
            {
                result = referenceMasterExpTime.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(referenceMasterExpTime);
        }
    }

    // Reading Optional parameter referenceMasterColorTemp from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, referenceMasterColorTempExists, alignment)
        referenceMasterColorTempID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && referenceMasterColorTempExists)
        {
            if (result)
            {
                result = referenceMasterColorTemp.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(referenceMasterColorTemp);
        }
    }

    // Reading Optional parameter qValue from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, qValueExists, alignment)
        qValueID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && qValueExists)
        {
            SYMBOL_TABLE_ENTRY_READ(pointerEntry, result, qValue, alignment)
        }
        else
        {
            PARAMETER_INITIALIZE(qValue);
        }
    }

    // Reading Optional parameter absoluteMethodAECSyncInfo from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, absoluteMethodAECSyncInfoExists, alignment)
        absoluteMethodAECSyncInfoID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && absoluteMethodAECSyncInfoExists)
        {
            if (result)
            {
                result = absoluteMethodAECSyncInfo.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(absoluteMethodAECSyncInfo);
        }
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load QSCSettingsInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool QSCSettingsInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(dataOffset);
    PARAMETER_INITIALIZE(QSCAddress);
    PARAMETER_INITIALIZE(settingsSize);

    result = dataOffset.Load(entry, alignment);
    SYMBOL_TABLE_ENTRY_READ(entry, result, QSCAddress, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, settingsSize, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load DualCameraInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool DualCameraInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(DualCameraData);
    PARAMETER_INITIALIZE(offset);
    PARAMETER_INITIALIZE(settingsize);
    PARAMETER_INITIALIZE(masterInfo);
    PARAMETER_INITIALIZE(auxInfo);
    PARAMETER_INITIALIZE(systemInfo);

    result = DualCameraData.Load(entry, alignment);
    SYMBOL_TABLE_ENTRY_READ(entry, result, offset, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, settingsize, alignment)
    if (result)
    {
        result = masterInfo.Load(entry, alignment);
    }
    if (result)
    {
        result = auxInfo.Load(entry, alignment);
    }
    if (result)
    {
        result = systemInfo.Load(entry, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load SPCInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool SPCInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(SPCData);
    PARAMETER_INITIALIZE(SPCSettings);
    PARAMETER_INITIALIZE(addressType);
    PARAMETER_INITIALIZE(dataType);
    PARAMETER_INITIALIZE(delay);

    result = SPCData.Load(entry, alignment);

    // Reading Array SPCSettings from symbol table
    // Do not check result value here because the count value needs to be initialized in this block
    {
        SPCSettingsCount = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, SPCSettingsCount, alignment)
        constexpr const CHAR* const file {__FILE__};
        constexpr INT32 line {LINE_CONST};
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }

        if (result)
        {
            SPCSettingsID = pointerEntry->ID;
            DupObjInfo* SPCSettingsDupInfo = pointerEntry->GetDupObject(SPCSettingsCount, file, line);
            if (SPCSettingsDupInfo != nullptr && SPCSettingsDupInfo->Object != nullptr)
            {
                SPCSettings = (SPCSettingsInfo*)SPCSettingsDupInfo->Object;
                if (SPCSettings == nullptr)
                {
                    if (SPCSettingsDupInfo->File != nullptr)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "SPCSettings duplicate found but object is nullptr: %s:%d, RefCount: %d\n",
                            SPCSettingsDupInfo->File, SPCSettingsDupInfo->Line, SPCSettingsDupInfo->RefCount);
                    }
                    else
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "SPCSettings duplicate found but Object is nullptr: <nullptr file ptr>:%d, RefCount: %d\n",
                            SPCSettingsDupInfo->Line, SPCSettingsDupInfo->RefCount);
                    }
                }
            }

            if (SPCSettings == nullptr)
            {
                if (result && SPCSettingsCount > 0)
                {
                    SPCSettings = PARAMETER_NEW SPCSettingsInfo[SPCSettingsCount];
                    (void)pointerEntry->SetDupObject(SPCSettings, SPCSettingsCount, file, line);
                }
                if (!result || SPCSettings == nullptr)
                {
                    if (SPCSettingsCount > 0)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "Failed to allocate SPCSettings\n");
                    }
                    SPCSettingsCount = 0;
                }
                for (UINT32 i = 0; result && i < SPCSettingsCount; i++)
                {
                    result = SPCSettings[i].Load(pointerEntry, alignment);
                }
            }
        }
        if (SPCSettings == nullptr)
        {
            SPCSettingsCount = 0;
        }
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, addressType, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, dataType, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, delay, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load OISInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool OISInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(OISData);
    PARAMETER_INITIALIZE(dataOffset);
    PARAMETER_INITIALIZE(OISAddressArray);
    PARAMETER_INITIALIZE(settingsSize);
    PARAMETER_INITIALIZE(addressType);
    PARAMETER_INITIALIZE(dataType);
    PARAMETER_INITIALIZE(delay);

    result = OISData.Load(entry, alignment);
    if (result)
    {
        result = dataOffset.Load(entry, alignment);
    }

    // Reading Array OISAddressArray from symbol table
    // Do not check result value here because the count value needs to be initialized in this block
    {
        OISAddressArrayCount = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, OISAddressArrayCount, alignment)
        constexpr const CHAR* const file {__FILE__};
        constexpr INT32 line {LINE_CONST};
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }

        if (result)
        {
            OISAddressArrayID = pointerEntry->ID;
            DupObjInfo* OISAddressArrayDupInfo = pointerEntry->GetDupObject(OISAddressArrayCount, file, line);
            if (OISAddressArrayDupInfo != nullptr && OISAddressArrayDupInfo->Object != nullptr)
            {
                OISAddressArray = (UINT32*)OISAddressArrayDupInfo->Object;
                if (OISAddressArray == nullptr)
                {
                    if (OISAddressArrayDupInfo->File != nullptr)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "OISAddressArray duplicate found but object is nullptr: %s:%d, RefCount: %d\n",
                            OISAddressArrayDupInfo->File, OISAddressArrayDupInfo->Line, OISAddressArrayDupInfo->RefCount);
                    }
                    else
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "OISAddressArray duplicate found but Object is nullptr: <nullptr file ptr>:%d, RefCount: %d\n",
                            OISAddressArrayDupInfo->Line, OISAddressArrayDupInfo->RefCount);
                    }
                }
            }

            if (OISAddressArray == nullptr)
            {
                if (result && OISAddressArrayCount > 0)
                {
                    OISAddressArray = pointerEntry->ReadArray<UINT32>(OISAddressArrayCount, alignment);
                    result = OISAddressArray != nullptr;
                }
                if (!result || OISAddressArray == nullptr)
                {
                    if (OISAddressArrayCount > 0)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "Failed to allocate OISAddressArray\n");
                    }
                    OISAddressArrayCount = 0;
                }
            }
        }
        if (OISAddressArray == nullptr)
        {
            OISAddressArrayCount = 0;
        }
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, settingsSize, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, addressType, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, dataType, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, delay, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load PDAFDCCInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool PDAFDCCInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(DCCData);
    PARAMETER_INITIALIZE(slopeDataOffset);
    PARAMETER_INITIALIZE(offsetDataOffset);
    PARAMETER_INITIALIZE(knotX);
    PARAMETER_INITIALIZE(knotY);
    PARAMETER_INITIALIZE(offsetX);
    PARAMETER_INITIALIZE(offsetY);
    PARAMETER_INITIALIZE(areaX);
    PARAMETER_INITIALIZE(areaY);
    PARAMETER_INITIALIZE(qValue);

    result = DCCData.Load(entry, alignment);
    if (result)
    {
        result = slopeDataOffset.Load(entry, alignment);
    }
    if (result)
    {
        result = offsetDataOffset.Load(entry, alignment);
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, knotX, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, knotY, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, offsetX, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, offsetY, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, areaX, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, areaY, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, qValue, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load PDOffsetMapInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool PDOffsetMapInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(offsetMapCalDistanceCM);
    PARAMETER_INITIALIZE(MapWidth);
    PARAMETER_INITIALIZE(MapHeight);
    PARAMETER_INITIALIZE(OffsetMapHorizontal);
    PARAMETER_INITIALIZE(OffsetMapVertical);

    SYMBOL_TABLE_ENTRY_READ(entry, result, offsetMapCalDistanceCM, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, MapWidth, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, MapHeight, alignment)
    if (result)
    {
        result = OffsetMapHorizontal.Load(entry, alignment);
    }
    if (result)
    {
        result = OffsetMapVertical.Load(entry, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load PDAF2DInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool PDAF2DInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(PDAF2DData);
    PARAMETER_INITIALIZE(version);
    PARAMETER_INITIALIZE(mapWidth);
    PARAMETER_INITIALIZE(mapHeight);
    PARAMETER_INITIALIZE(gainWidth);
    PARAMETER_INITIALIZE(gainHeight);
    PARAMETER_INITIALIZE(leftGainMap);
    PARAMETER_INITIALIZE(rightGainMap);
    PARAMETER_INITIALIZE(upGainMapExists);
    PARAMETER_INITIALIZE(upGainMap);
    PARAMETER_INITIALIZE(downGainMapExists);
    PARAMETER_INITIALIZE(downGainMap);
    PARAMETER_INITIALIZE(conversionCoefficientCount);
    PARAMETER_INITIALIZE(conversionCoefficient);
    PARAMETER_INITIALIZE(conversionCoefficientVertExists);
    PARAMETER_INITIALIZE(conversionCoefficientVert);
    PARAMETER_INITIALIZE(DCCQFormatExists);
    PARAMETER_INITIALIZE(DCCQFormat);
    PARAMETER_INITIALIZE(DCCMapWidthExists);
    PARAMETER_INITIALIZE(DCCMapWidth);
    PARAMETER_INITIALIZE(DCCMapHeightExists);
    PARAMETER_INITIALIZE(DCCMapHeight);
    PARAMETER_INITIALIZE(DCCQFormatMemoryInfoExists);
    PARAMETER_INITIALIZE(DCCQFormatMemoryInfo);
    PARAMETER_INITIALIZE(DCCMapWidthMemoryInfoExists);
    PARAMETER_INITIALIZE(DCCMapWidthMemoryInfo);
    PARAMETER_INITIALIZE(DCCMapHeightMemoryInfoExists);
    PARAMETER_INITIALIZE(DCCMapHeightMemoryInfo);
    PARAMETER_INITIALIZE(PDAFOffsetMaps);

    result = PDAF2DData.Load(entry, alignment);
    if (result)
    {
        result = version.Load(entry, alignment);
    }
    if (result)
    {
        result = mapWidth.Load(entry, alignment);
    }
    if (result)
    {
        result = mapHeight.Load(entry, alignment);
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, gainWidth, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, gainHeight, alignment)
    if (result)
    {
        result = leftGainMap.Load(entry, alignment);
    }
    if (result)
    {
        result = rightGainMap.Load(entry, alignment);
    }

    // Reading Optional parameter upGainMap from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, upGainMapExists, alignment)
        upGainMapID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && upGainMapExists)
        {
            if (result)
            {
                result = upGainMap.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(upGainMap);
        }
    }

    // Reading Optional parameter downGainMap from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, downGainMapExists, alignment)
        downGainMapID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && downGainMapExists)
        {
            if (result)
            {
                result = downGainMap.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(downGainMap);
        }
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, conversionCoefficientCount, alignment)
    if (result)
    {
        result = conversionCoefficient.Load(entry, alignment);
    }

    // Reading Optional parameter conversionCoefficientVert from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, conversionCoefficientVertExists, alignment)
        conversionCoefficientVertID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && conversionCoefficientVertExists)
        {
            if (result)
            {
                result = conversionCoefficientVert.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(conversionCoefficientVert);
        }
    }

    // Reading Optional parameter DCCQFormat from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, DCCQFormatExists, alignment)
        DCCQFormatID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && DCCQFormatExists)
        {
            SYMBOL_TABLE_ENTRY_READ(pointerEntry, result, DCCQFormat, alignment)
        }
        else
        {
            PARAMETER_INITIALIZE(DCCQFormat);
        }
    }

    // Reading Optional parameter DCCMapWidth from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, DCCMapWidthExists, alignment)
        DCCMapWidthID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && DCCMapWidthExists)
        {
            SYMBOL_TABLE_ENTRY_READ(pointerEntry, result, DCCMapWidth, alignment)
        }
        else
        {
            PARAMETER_INITIALIZE(DCCMapWidth);
        }
    }

    // Reading Optional parameter DCCMapHeight from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, DCCMapHeightExists, alignment)
        DCCMapHeightID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && DCCMapHeightExists)
        {
            SYMBOL_TABLE_ENTRY_READ(pointerEntry, result, DCCMapHeight, alignment)
        }
        else
        {
            PARAMETER_INITIALIZE(DCCMapHeight);
        }
    }

    // Reading Optional parameter DCCQFormatMemoryInfo from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, DCCQFormatMemoryInfoExists, alignment)
        DCCQFormatMemoryInfoID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && DCCQFormatMemoryInfoExists)
        {
            if (result)
            {
                result = DCCQFormatMemoryInfo.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(DCCQFormatMemoryInfo);
        }
    }

    // Reading Optional parameter DCCMapWidthMemoryInfo from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, DCCMapWidthMemoryInfoExists, alignment)
        DCCMapWidthMemoryInfoID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && DCCMapWidthMemoryInfoExists)
        {
            if (result)
            {
                result = DCCMapWidthMemoryInfo.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(DCCMapWidthMemoryInfo);
        }
    }

    // Reading Optional parameter DCCMapHeightMemoryInfo from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, DCCMapHeightMemoryInfoExists, alignment)
        DCCMapHeightMemoryInfoID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && DCCMapHeightMemoryInfoExists)
        {
            if (result)
            {
                result = DCCMapHeightMemoryInfo.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(DCCMapHeightMemoryInfo);
        }
    }

    // Reading Array PDAFOffsetMaps from symbol table
    // Do not check result value here because the count value needs to be initialized in this block
    {
        PDAFOffsetMapsCount = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, PDAFOffsetMapsCount, alignment)
        constexpr const CHAR* const file {__FILE__};
        constexpr INT32 line {LINE_CONST};
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }

        if (result)
        {
            PDAFOffsetMapsID = pointerEntry->ID;
            DupObjInfo* PDAFOffsetMapsDupInfo = pointerEntry->GetDupObject(PDAFOffsetMapsCount, file, line);
            if (PDAFOffsetMapsDupInfo != nullptr && PDAFOffsetMapsDupInfo->Object != nullptr)
            {
                PDAFOffsetMaps = (PDOffsetMapInfo*)PDAFOffsetMapsDupInfo->Object;
                if (PDAFOffsetMaps == nullptr)
                {
                    if (PDAFOffsetMapsDupInfo->File != nullptr)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "PDAFOffsetMaps duplicate found but object is nullptr: %s:%d, RefCount: %d\n",
                            PDAFOffsetMapsDupInfo->File, PDAFOffsetMapsDupInfo->Line, PDAFOffsetMapsDupInfo->RefCount);
                    }
                    else
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "PDAFOffsetMaps duplicate found but Object is nullptr: <nullptr file ptr>:%d, RefCount: %d\n",
                            PDAFOffsetMapsDupInfo->Line, PDAFOffsetMapsDupInfo->RefCount);
                    }
                }
            }

            if (PDAFOffsetMaps == nullptr)
            {
                if (result && PDAFOffsetMapsCount > 0)
                {
                    PDAFOffsetMaps = PARAMETER_NEW PDOffsetMapInfo[PDAFOffsetMapsCount];
                    (void)pointerEntry->SetDupObject(PDAFOffsetMaps, PDAFOffsetMapsCount, file, line);
                }
                if (!result || PDAFOffsetMaps == nullptr)
                {
                    if (PDAFOffsetMapsCount > 0)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "Failed to allocate PDAFOffsetMaps\n");
                    }
                    PDAFOffsetMapsCount = 0;
                }
                for (UINT32 i = 0; result && i < PDAFOffsetMapsCount; i++)
                {
                    result = PDAFOffsetMaps[i].Load(pointerEntry, alignment);
                }
            }
        }
        if (PDAFOffsetMaps == nullptr)
        {
            PDAFOffsetMapsCount = 0;
        }
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load QSCInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool QSCInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(QSCData);
    PARAMETER_INITIALIZE(QSCSettings);
    PARAMETER_INITIALIZE(addressType);
    PARAMETER_INITIALIZE(dataType);
    PARAMETER_INITIALIZE(delay);

    result = QSCData.Load(entry, alignment);

    // Reading Array QSCSettings from symbol table
    // Do not check result value here because the count value needs to be initialized in this block
    {
        QSCSettingsCount = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, QSCSettingsCount, alignment)
        constexpr const CHAR* const file {__FILE__};
        constexpr INT32 line {LINE_CONST};
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }

        if (result)
        {
            QSCSettingsID = pointerEntry->ID;
            DupObjInfo* QSCSettingsDupInfo = pointerEntry->GetDupObject(QSCSettingsCount, file, line);
            if (QSCSettingsDupInfo != nullptr && QSCSettingsDupInfo->Object != nullptr)
            {
                QSCSettings = (QSCSettingsInfo*)QSCSettingsDupInfo->Object;
                if (QSCSettings == nullptr)
                {
                    if (QSCSettingsDupInfo->File != nullptr)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "QSCSettings duplicate found but object is nullptr: %s:%d, RefCount: %d\n",
                            QSCSettingsDupInfo->File, QSCSettingsDupInfo->Line, QSCSettingsDupInfo->RefCount);
                    }
                    else
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "QSCSettings duplicate found but Object is nullptr: <nullptr file ptr>:%d, RefCount: %d\n",
                            QSCSettingsDupInfo->Line, QSCSettingsDupInfo->RefCount);
                    }
                }
            }

            if (QSCSettings == nullptr)
            {
                if (result && QSCSettingsCount > 0)
                {
                    QSCSettings = PARAMETER_NEW QSCSettingsInfo[QSCSettingsCount];
                    (void)pointerEntry->SetDupObject(QSCSettings, QSCSettingsCount, file, line);
                }
                if (!result || QSCSettings == nullptr)
                {
                    if (QSCSettingsCount > 0)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "Failed to allocate QSCSettings\n");
                    }
                    QSCSettingsCount = 0;
                }
                for (UINT32 i = 0; result && i < QSCSettingsCount; i++)
                {
                    result = QSCSettings[i].Load(pointerEntry, alignment);
                }
            }
        }
        if (QSCSettings == nullptr)
        {
            QSCSettingsCount = 0;
        }
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, addressType, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, dataType, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, delay, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load LensDistortionInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool LensDistortionInfo::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(lensData);
    PARAMETER_INITIALIZE(lensOffsetStart);
    PARAMETER_INITIALIZE(lensDistortionSize);
    PARAMETER_INITIALIZE(horizontalFocalLength);
    PARAMETER_INITIALIZE(verticalFocalLength);
    PARAMETER_INITIALIZE(opticalAxisX);
    PARAMETER_INITIALIZE(opticalAxisY);
    PARAMETER_INITIALIZE(skewExists);
    PARAMETER_INITIALIZE(skew);
    PARAMETER_INITIALIZE(kappa0);
    PARAMETER_INITIALIZE(kappa1);
    PARAMETER_INITIALIZE(kappa2);
    PARAMETER_INITIALIZE(kappa3);
    PARAMETER_INITIALIZE(kappa4);

    result = lensData.Load(entry, alignment);
    SYMBOL_TABLE_ENTRY_READ(entry, result, lensOffsetStart, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, lensDistortionSize, alignment)
    if (result)
    {
        result = horizontalFocalLength.Load(entry, alignment);
    }
    if (result)
    {
        result = verticalFocalLength.Load(entry, alignment);
    }
    if (result)
    {
        result = opticalAxisX.Load(entry, alignment);
    }
    if (result)
    {
        result = opticalAxisY.Load(entry, alignment);
    }

    // Reading Optional parameter skew from symbol table
    {
        SYMBOL_TABLE_ENTRY_READ(entry, result, skewExists, alignment)
        skewID = entry->ID;
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }
        if (result && skewExists)
        {
            if (result)
            {
                result = skew.Load(pointerEntry, alignment);
            }
        }
        else
        {
            PARAMETER_INITIALIZE(skew);
        }
    }
    if (result)
    {
        result = kappa0.Load(entry, alignment);
    }
    if (result)
    {
        result = kappa1.Load(entry, alignment);
    }
    if (result)
    {
        result = kappa2.Load(entry, alignment);
    }
    if (result)
    {
        result = kappa3.Load(entry, alignment);
    }
    if (result)
    {
        result = kappa4.Load(entry, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load EEPROMDataFormatInformation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool EEPROMDataFormatInformation::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(AF);
    PARAMETER_INITIALIZE(WB);
    PARAMETER_INITIALIZE(LSC);
    PARAMETER_INITIALIZE(dualCamera);
    PARAMETER_INITIALIZE(SPC);
    PARAMETER_INITIALIZE(OIS);
    PARAMETER_INITIALIZE(PDAFDCC);
    PARAMETER_INITIALIZE(PDAF2D);
    PARAMETER_INITIALIZE(QSC);
    PARAMETER_INITIALIZE(Lens);

    result = AF.Load(entry, alignment);
    if (result)
    {
        result = WB.Load(entry, alignment);
    }
    if (result)
    {
        result = LSC.Load(entry, alignment);
    }
    if (result)
    {
        result = dualCamera.Load(entry, alignment);
    }
    if (result)
    {
        result = SPC.Load(entry, alignment);
    }
    if (result)
    {
        result = OIS.Load(entry, alignment);
    }
    if (result)
    {
        result = PDAFDCC.Load(entry, alignment);
    }
    if (result)
    {
        result = PDAF2D.Load(entry, alignment);
    }
    if (result)
    {
        result = QSC.Load(entry, alignment);
    }
    if (result)
    {
        result = Lens.Load(entry, alignment);
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load CustomInformation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool CustomInformation::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(name);
    PARAMETER_INITIALIZE(value);


    // Reading String name from symbol table
    {
        UINT32 count = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, count, alignment)
        ParameterFileSymbolTableEntry stringPointerEntryCls;
        ParameterFileSymbolTableEntry* const stringPointerEntry = &stringPointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(stringPointerEntryCls, entry, alignment);
        }
        SYMBOL_TABLE_ENTRY_READ_STRING(stringPointerEntry, result, name, count, alignment)
    }
    SYMBOL_TABLE_ENTRY_READ(entry, result, value, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load EEPROMDriverData
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool EEPROMDriverData::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(module_version);
    PARAMETER_INITIALIZE(slaveInfo);
    PARAMETER_INITIALIZE(memoryMap);
    PARAMETER_INITIALIZE(formatInfo);
    PARAMETER_INITIALIZE(customInfo);

    result = module_version.Load(entry, alignment);
    if (result)
    {
        result = slaveInfo.Load(entry, alignment);
    }
    if (result)
    {
        result = memoryMap.Load(entry, alignment);
    }
    if (result)
    {
        result = formatInfo.Load(entry, alignment);
    }

    // Reading Array customInfo from symbol table
    // Do not check result value here because the count value needs to be initialized in this block
    {
        customInfoCount = 0;
        SYMBOL_TABLE_ENTRY_READ(entry, result, customInfoCount, alignment)
        constexpr const CHAR* const file {__FILE__};
        constexpr INT32 line {LINE_CONST};
        ParameterFileSymbolTableEntry  pointerEntryCls;
        ParameterFileSymbolTableEntry* const pointerEntry = &pointerEntryCls;
        if (result)
        {
            result = entry->Table->ReadPointerEntry(pointerEntryCls, entry, alignment);
        }

        if (result)
        {
            customInfoID = pointerEntry->ID;
            DupObjInfo* customInfoDupInfo = pointerEntry->GetDupObject(customInfoCount, file, line);
            if (customInfoDupInfo != nullptr && customInfoDupInfo->Object != nullptr)
            {
                customInfo = (CustomInformation*)customInfoDupInfo->Object;
                if (customInfo == nullptr)
                {
                    if (customInfoDupInfo->File != nullptr)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "customInfo duplicate found but object is nullptr: %s:%d, RefCount: %d\n",
                            customInfoDupInfo->File, customInfoDupInfo->Line, customInfoDupInfo->RefCount);
                    }
                    else
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "customInfo duplicate found but Object is nullptr: <nullptr file ptr>:%d, RefCount: %d\n",
                            customInfoDupInfo->Line, customInfoDupInfo->RefCount);
                    }
                }
            }

            if (customInfo == nullptr)
            {
                if (result && customInfoCount > 0)
                {
                    customInfo = PARAMETER_NEW CustomInformation[customInfoCount];
                    (void)pointerEntry->SetDupObject(customInfo, customInfoCount, file, line);
                }
                if (!result || customInfo == nullptr)
                {
                    if (customInfoCount > 0)
                    {
                        PARAMETER_LOG_ERROR(entry->SetManager, "Failed to allocate customInfo\n");
                    }
                    customInfoCount = 0;
                }
                for (UINT32 i = 0; result && i < customInfoCount; i++)
                {
                    result = customInfo[i].Load(pointerEntry, alignment);
                }
            }
        }
        if (customInfo == nullptr)
        {
            customInfoCount = 0;
        }
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load module_versionStruct
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool EEPROMDriverData::module_versionStruct::Load(
    ParameterFileSymbolTableEntry* const entry,
    BYTE const alignment)
{
    bool result = true;

    PARAMETER_INITIALIZE(major_revision);
    PARAMETER_INITIALIZE(minor_revision);
    PARAMETER_INITIALIZE(incr_revision);

    SYMBOL_TABLE_ENTRY_READ(entry, result, major_revision, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, minor_revision, alignment)
    SYMBOL_TABLE_ENTRY_READ(entry, result, incr_revision, alignment)

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload EEPROMSlaveInformation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EEPROMSlaveInformation::Unload(ParameterFileSymbolTable* const __table)
{
    if (__table != nullptr && __table->ReleaseDupObject(EEPROMName))
    {
        PARAMETER_DELETE[] EEPROMName;
    }
    EEPROMName = nullptr;
    powerUpSequence.Unload(__table);
    powerDownSequence.Unload(__table);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload AFInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void AFInfo::Unload(ParameterFileSymbolTable* const __table)
{
    if (__table != nullptr && __table->ReleaseDupObject(calibrationInfo))
    {
        PARAMETER_DELETE[] calibrationInfo;
    }
    calibrationInfo = nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload WBInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void WBInfo::Unload(ParameterFileSymbolTable* const __table)
{
    if (__table != nullptr && __table->ReleaseDupObject(lightInfo))
    {
        PARAMETER_DELETE[] lightInfo;
    }
    lightInfo = nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload LSCInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void LSCInfo::Unload(ParameterFileSymbolTable* const __table)
{
    if (__table != nullptr && __table->ReleaseDupObject(lightInfo))
    {
        PARAMETER_DELETE[] lightInfo;
    }
    lightInfo = nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload DualCameraLensInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void DualCameraLensInfo::Unload(ParameterFileSymbolTable* const __table)
{
    if (__table != nullptr && __table->ReleaseDupObject(AFSyncInfo))
    {
        PARAMETER_DELETE[] AFSyncInfo;
    }
    AFSyncInfo = nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload DualCameraInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void DualCameraInfo::Unload(ParameterFileSymbolTable* const __table)
{
    masterInfo.Unload(__table);
    auxInfo.Unload(__table);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload SPCInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void SPCInfo::Unload(ParameterFileSymbolTable* const __table)
{
    if (__table != nullptr && __table->ReleaseDupObject(SPCSettings))
    {
        PARAMETER_DELETE[] SPCSettings;
    }
    SPCSettings = nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload OISInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void OISInfo::Unload(ParameterFileSymbolTable* const __table)
{
    if (__table != nullptr && __table->ReleaseDupObject(OISAddressArray))
    {
        PARAMETER_DELETE[] OISAddressArray;
    }
    OISAddressArray = nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload PDAF2DInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void PDAF2DInfo::Unload(ParameterFileSymbolTable* const __table)
{
    if (__table != nullptr && __table->ReleaseDupObject(PDAFOffsetMaps))
    {
        PARAMETER_DELETE[] PDAFOffsetMaps;
    }
    PDAFOffsetMaps = nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload QSCInfo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void QSCInfo::Unload(ParameterFileSymbolTable* const __table)
{
    if (__table != nullptr && __table->ReleaseDupObject(QSCSettings))
    {
        PARAMETER_DELETE[] QSCSettings;
    }
    QSCSettings = nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload EEPROMDataFormatInformation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EEPROMDataFormatInformation::Unload(ParameterFileSymbolTable* const __table)
{
    AF.Unload(__table);
    WB.Unload(__table);
    LSC.Unload(__table);
    dualCamera.Unload(__table);
    SPC.Unload(__table);
    OIS.Unload(__table);
    PDAF2D.Unload(__table);
    QSC.Unload(__table);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload CustomInformation
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CustomInformation::Unload(ParameterFileSymbolTable* const __table)
{
    if (__table != nullptr && __table->ReleaseDupObject(name))
    {
        PARAMETER_DELETE[] name;
    }
    name = nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload EEPROMDriverData
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EEPROMDriverData::Unload(ParameterFileSymbolTable* const __table)
{
    slaveInfo.Unload(__table);
    memoryMap.Unload(__table);
    formatInfo.Unload(__table);
    for (UINT32 i = 0; i < customInfoCount; i++)
    {
        customInfo[i].Unload(__table);
    }
    if (__table != nullptr && __table->ReleaseDupObject(customInfo))
    {
        PARAMETER_DELETE[] customInfo;
    }
    customInfo = nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Release the ParameterModule object
/// Requires that this object was created via a ParameterSetManager::GetModule call
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EEPROMDriverData::Release()
{
    ((EEPROMDriverDataClass*)this)->Release();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Returns the ParameterModule::Modified value
/// The Modified value is incremented when the module's data or pointer values change
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
UINT32 EEPROMDriverData::GetModified()
{
    return ((EEPROMDriverDataClass*)this)->Modified;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Create module, and return a new object
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ParameterModule* EEPROMDriverDataClass::Create(
    ModuleData*    moduleData,
    DefaultModule* const defModule) const
{
    EEPROMDriverDataClass* cls = nullptr;

    if (PARAMETER_STRCMP(Type, moduleData->Type) == 0 && Version.Value == moduleData->Version.Value)
    {
        const UINT32 id = moduleData->DuplicateID > 0 ? moduleData->DuplicateID : moduleData->ID;

        ParameterModule* const module = defModule->Find(id);
        if (module != nullptr)
        {
            cls = (EEPROMDriverDataClass*)module;
        }
        else
        {
            cls = PARAMETER_NEW EEPROMDriverDataClass(GetName(moduleData->Type), moduleData);
            cls->SymbolTableID = id;
            defModule->AddModule((ParameterModule*)cls);
        }
    }
    else if (Version.Value != moduleData->Version.Value)
    {
        PARAMETER_LOG_ERROR(moduleData->SetManager, "Unable to create EEPROMDriverDataClass, binary version (%lld) does not match source version (%lld)\n",
            moduleData->Version.Value, Version.Value);
    }
    else
    {
        PARAMETER_LOG_ERROR(moduleData->SetManager, "Unable to create EEPROMDriverDataClass, binary name (%s) does not match source name (%s)\n",
            moduleData->Type, Type);
    }

    return (ParameterModule*)cls;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Load module data, return true is successful
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool EEPROMDriverDataClass::LoadModule(
    ParameterFileSymbolTable* const table)
{
    bool result = true;

    if (!Loaded)
    {
        BYTE const alignment = table->Alignment;
        EEPROMDriverDataClass* const cls = this;

        ParameterFileSymbolTableEntry  entryObj;
        ParameterFileSymbolTableEntry* const entry = &entryObj;
        result = table->Find(entryObj, SymbolTableID);

        if (!result)
        {
            PARAMETER_LOG_ERROR(entry->SetManager, "EEPROMDriverDataClass::LoadModule Failed to find module ID (%d) in Symbol Table\n", SymbolTableID);
        }

        if (result)
        {
            result = cls->Load(entry, alignment);
        }
        Modified++;
        Loaded = true;
    }

    if (!result)
    {
        /// Module failed to fully load, unload it
        UnloadModule();
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Unload module data
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EEPROMDriverDataClass::UnloadModule()
{
    if (Loaded)
    {
        if (Data != nullptr && Data->SymbolTable != nullptr)
        {
            Unload(Data->SymbolTable);
        }
        else
        {
            PARAMETER_LOG_ERROR(Data != nullptr ? Data->SetManager : nullptr, "UnloadModule %s called with nullptr "
                "Data->SymbolTable object\n", Name);
            Unload(nullptr);
        }
        Loaded = false;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// /// Release the ParameterModule object
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void EEPROMDriverDataClass::Release()
{
    ParameterModule::Release();
}

CAMX_NAMESPACE_END
