mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-19 01:40:43 +01:00
amd/gmlib: add gmlib for radeonsi
radeonsi drivers can use gmlib to generate 3dlut used to do tonemapping. Signed-off-by: Peyton Lee <peytolee@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33731>
This commit is contained in:
parent
2e124dd389
commit
2e46c41448
27 changed files with 6471 additions and 0 deletions
1
src/amd/gmlib/README.md
Executable file
1
src/amd/gmlib/README.md
Executable file
|
|
@ -0,0 +1 @@
|
|||
# GMLib
|
||||
45
src/amd/gmlib/ToneMapGenerator/inc/ToneMapGenerator.h
Executable file
45
src/amd/gmlib/ToneMapGenerator/inc/ToneMapGenerator.h
Executable file
|
|
@ -0,0 +1,45 @@
|
|||
/* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "ToneMapTypes.h"
|
||||
#include "AGMGenerator.h"
|
||||
|
||||
struct SrcTmParams {
|
||||
struct ToneMapHdrMetaData streamMetaData;
|
||||
enum ToneMapTransferFunction inputContainerGamma;
|
||||
};
|
||||
|
||||
struct DstTmParams {
|
||||
struct ToneMapHdrMetaData dstMetaData;
|
||||
enum ToneMapTransferFunction outputContainerGamma;
|
||||
enum ToneMapColorPrimaries outputContainerPrimaries;
|
||||
};
|
||||
|
||||
struct ToneMapGenerator {
|
||||
struct AGMGenerator agmGenerator;
|
||||
enum ToneMapAlgorithm tmAlgo;
|
||||
bool memAllocSet;
|
||||
struct SrcTmParams cachedSrcTmParams;
|
||||
struct DstTmParams cachedDstTmParams;
|
||||
};
|
||||
|
||||
enum TMGReturnCode ToneMapGenerator_GenerateToneMappingParameters(
|
||||
struct ToneMapGenerator* p_tmGenerator,
|
||||
const struct ToneMapHdrMetaData* streamMetaData,
|
||||
const struct ToneMapHdrMetaData* dstMetaData,
|
||||
enum ToneMapTransferFunction inputContainerGamma,
|
||||
enum ToneMapTransferFunction outputContainerGamma,
|
||||
enum ToneMapColorPrimaries outputContainerPrimaries,
|
||||
unsigned short lutDim,
|
||||
struct ToneMappingParameters* tmParams);
|
||||
|
||||
enum TMGReturnCode ToneMapGenerator_SetInternalAllocators(
|
||||
struct ToneMapGenerator* p_tmGenerator,
|
||||
TMGAlloc allocFunc,
|
||||
TMGFree freeFunc,
|
||||
void* memCtx);
|
||||
73
src/amd/gmlib/ToneMapGenerator/inc/ToneMapTypes.h
Executable file
73
src/amd/gmlib/ToneMapGenerator/inc/ToneMapTypes.h
Executable file
|
|
@ -0,0 +1,73 @@
|
|||
/* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
|
||||
#define MAX_LUMINANCE 10000.0
|
||||
#define INPUT_NORMALIZATION_FACTOR 4000 //nits
|
||||
typedef void* (*TMGAlloc)(unsigned int, void*);
|
||||
typedef void (*TMGFree)(void*, void*);
|
||||
|
||||
struct ToneMapHdrMetaData
|
||||
{
|
||||
unsigned short redPrimaryX;
|
||||
unsigned short redPrimaryY;
|
||||
unsigned short greenPrimaryX;
|
||||
unsigned short greenPrimaryY;
|
||||
unsigned short bluePrimaryX;
|
||||
unsigned short bluePrimaryY;
|
||||
unsigned short whitePointX;
|
||||
unsigned short whitePointY;
|
||||
unsigned int maxMasteringLuminance;
|
||||
unsigned int minMasteringLuminance;
|
||||
unsigned short maxContentLightLevel;
|
||||
unsigned short maxFrameAverageLightLevel;
|
||||
};
|
||||
|
||||
enum ToneMapTransferFunction {
|
||||
TMG_TF_SRGB,
|
||||
TMG_TF_BT709,
|
||||
TMG_TF_G24,
|
||||
TMG_TF_PQ,
|
||||
TMG_TF_NormalizedPQ,
|
||||
TMG_TF_ModifiedPQ,
|
||||
TMG_TF_Linear,
|
||||
TMG_TF_HLG
|
||||
};
|
||||
|
||||
enum ToneMapColorPrimaries {
|
||||
TMG_CP_BT601,
|
||||
TMG_CP_BT709,
|
||||
TMG_CP_BT2020,
|
||||
TMG_CP_DCIP3
|
||||
};
|
||||
|
||||
enum ToneMapAlgorithm {
|
||||
TMG_A_AGM,
|
||||
TMG_A_BT2390,
|
||||
TMG_A_BT2390_4
|
||||
};
|
||||
|
||||
struct ToneMappingParameters {
|
||||
enum ToneMapColorPrimaries lutColorIn;
|
||||
enum ToneMapColorPrimaries lutColorOut;
|
||||
enum ToneMapTransferFunction shaperTf;
|
||||
enum ToneMapTransferFunction lutOutTf;
|
||||
unsigned short lutDim;
|
||||
unsigned short* lutData;
|
||||
void* formattedLutData;
|
||||
unsigned short inputNormalizationFactor;
|
||||
};
|
||||
|
||||
enum TMGReturnCode {
|
||||
TMG_RET_OK,
|
||||
TMG_RET_ERROR_DUPLICATE_INIT,
|
||||
TMG_RET_ERROR_INVALID_PARAM,
|
||||
TMG_RET_ERROR_NOT_INITIALIZED,
|
||||
TMG_RET_ERROR_GMLIB
|
||||
};
|
||||
39
src/amd/gmlib/ToneMapGenerator/src/inc/AGMGenerator.h
Executable file
39
src/amd/gmlib/ToneMapGenerator/src/inc/AGMGenerator.h
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
/* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "ToneMapTypes.h"
|
||||
#include "gm_api_funcs.h"
|
||||
|
||||
/* Replace CPP class: AGMGenerator */
|
||||
struct AGMGenerator {
|
||||
TMGAlloc allocFunc;
|
||||
TMGFree freeFunc;
|
||||
void* memoryContext;
|
||||
bool initalized;
|
||||
struct s_gamut_map agmParams;
|
||||
struct s_gm_opts gamutMapParams;
|
||||
};
|
||||
|
||||
enum TMGReturnCode AGMGenerator_ApplyToneMap(
|
||||
struct AGMGenerator* p_agm_generator,
|
||||
const struct ToneMapHdrMetaData* streamMetaData,
|
||||
const struct ToneMapHdrMetaData* dtMetaData,
|
||||
const enum ToneMapAlgorithm tmAlgorithm,
|
||||
const struct ToneMappingParameters* tmParams,
|
||||
bool updateSrcParams,
|
||||
bool updateDstParams,
|
||||
bool enableMerge3DLUT);
|
||||
|
||||
enum TMGReturnCode AGMGenerator_SetGMAllocator(
|
||||
struct AGMGenerator* p_agm_generator,
|
||||
TMGAlloc allocFunc,
|
||||
TMGFree freeFunc,
|
||||
void* memCtx);
|
||||
|
||||
/* Replace ~AGMGenerator() */
|
||||
void AGMGenerator_Exit(struct AGMGenerator* p_agm_generator);
|
||||
176
src/amd/gmlib/ToneMapGenerator/src/inc/CSCGenerator.h
Executable file
176
src/amd/gmlib/ToneMapGenerator/src/inc/CSCGenerator.h
Executable file
|
|
@ -0,0 +1,176 @@
|
|||
/* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "csc_api_funcs.h"
|
||||
#include "ToneMapTypes.h"
|
||||
|
||||
static bool TranslateTfEnum(
|
||||
enum ToneMapTransferFunction inTf,
|
||||
enum cs_gamma_type* outTf)
|
||||
{
|
||||
|
||||
switch (inTf) {
|
||||
case(TMG_TF_SRGB):
|
||||
*outTf = EGT_sRGB;
|
||||
break;
|
||||
case(TMG_TF_BT709):
|
||||
*outTf = EGT_709;
|
||||
break;
|
||||
case(TMG_TF_G24):
|
||||
*outTf = EGT_2_4;
|
||||
break;
|
||||
case(TMG_TF_HLG):
|
||||
*outTf = EGT_HLG;
|
||||
break;
|
||||
case(TMG_TF_NormalizedPQ):
|
||||
case(TMG_TF_PQ):
|
||||
*outTf = EGT_PQ;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void CSCCtor(struct s_csc_map* csc_map)
|
||||
{
|
||||
csc_ctor(csc_map);
|
||||
}
|
||||
|
||||
static enum TMGReturnCode CSCSetOptions(
|
||||
const struct ToneMapHdrMetaData* srcMetaData,
|
||||
enum ToneMapTransferFunction inTf,
|
||||
const struct ToneMapHdrMetaData* dstMetaData,
|
||||
enum ToneMapTransferFunction outTf,
|
||||
const struct ToneMappingParameters* tmParams,
|
||||
bool merge3DLUT,
|
||||
struct s_csc_api_opts* csc_opts)
|
||||
{
|
||||
|
||||
enum TMGReturnCode ret = TMG_RET_OK;
|
||||
enum cs_gamma_type inGamma;
|
||||
enum cs_gamma_type outGamma;
|
||||
|
||||
if (!TranslateTfEnum(inTf, &inGamma)) {
|
||||
ret = TMG_RET_ERROR_INVALID_PARAM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if(!TranslateTfEnum(outTf, &outGamma)) {
|
||||
ret = TMG_RET_ERROR_INVALID_PARAM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
csc_opts->ptr_3dlut_rgb = tmParams->lutData;
|
||||
csc_opts->num_pnts_3dlut = tmParams->lutDim;
|
||||
csc_opts->bitwidth_3dlut = 12;
|
||||
csc_opts->en_merge_3dlut = merge3DLUT;
|
||||
|
||||
|
||||
csc_opts->cs_opts_src.color_space_type = ECST_CUSTOM;
|
||||
csc_opts->cs_opts_src.rgbw_xy[0] =
|
||||
srcMetaData->redPrimaryX / 50000.0;
|
||||
csc_opts->cs_opts_src.rgbw_xy[1] =
|
||||
srcMetaData->redPrimaryY / 50000.0;
|
||||
csc_opts->cs_opts_src.rgbw_xy[2] =
|
||||
srcMetaData->greenPrimaryX / 50000.0;
|
||||
csc_opts->cs_opts_src.rgbw_xy[3] =
|
||||
srcMetaData->greenPrimaryY / 50000.0;
|
||||
csc_opts->cs_opts_src.rgbw_xy[4] =
|
||||
srcMetaData->bluePrimaryX / 50000.0;
|
||||
csc_opts->cs_opts_src.rgbw_xy[5] =
|
||||
srcMetaData->bluePrimaryY / 50000.0;
|
||||
csc_opts->cs_opts_src.rgbw_xy[6] =
|
||||
srcMetaData->whitePointX / 50000.0;
|
||||
csc_opts->cs_opts_src.rgbw_xy[7] =
|
||||
srcMetaData->whitePointY / 50000.0;
|
||||
|
||||
csc_opts->cs_opts_src.gamma_type = inGamma;
|
||||
csc_opts->cs_opts_src.luminance_limits[0] = 0.0;
|
||||
csc_opts->cs_opts_src.luminance_limits[1] =
|
||||
(double)srcMetaData->maxMasteringLuminance;
|
||||
|
||||
if (inTf == TMG_TF_NormalizedPQ)
|
||||
csc_opts->cs_opts_src.pq_norm = (double)tmParams->inputNormalizationFactor;
|
||||
else
|
||||
csc_opts->cs_opts_src.pq_norm = MAX_LUMINANCE;
|
||||
|
||||
|
||||
csc_opts->cs_opts_dst.color_space_type = ECST_CUSTOM;
|
||||
csc_opts->cs_opts_dst.rgbw_xy[0] =
|
||||
dstMetaData->redPrimaryX / 50000.0;
|
||||
csc_opts->cs_opts_dst.rgbw_xy[1] =
|
||||
dstMetaData->redPrimaryY / 50000.0;
|
||||
csc_opts->cs_opts_dst.rgbw_xy[2] =
|
||||
dstMetaData->greenPrimaryX / 50000.0;
|
||||
csc_opts->cs_opts_dst.rgbw_xy[3] =
|
||||
dstMetaData->greenPrimaryY / 50000.0;
|
||||
csc_opts->cs_opts_dst.rgbw_xy[4] =
|
||||
dstMetaData->bluePrimaryX / 50000.0;
|
||||
csc_opts->cs_opts_dst.rgbw_xy[5] =
|
||||
dstMetaData->bluePrimaryY / 50000.0;
|
||||
csc_opts->cs_opts_dst.rgbw_xy[6] =
|
||||
dstMetaData->whitePointX / 50000.0;
|
||||
csc_opts->cs_opts_dst.rgbw_xy[7] =
|
||||
dstMetaData->whitePointY / 50000.0;
|
||||
|
||||
csc_opts->cs_opts_dst.gamma_type = outGamma;
|
||||
csc_opts->cs_opts_dst.luminance_limits[0] = 0.0;
|
||||
csc_opts->cs_opts_dst.luminance_limits[1] =
|
||||
(double)dstMetaData->maxMasteringLuminance;
|
||||
|
||||
if (outTf == TMG_TF_NormalizedPQ)
|
||||
csc_opts->cs_opts_dst.pq_norm = (double)tmParams->inputNormalizationFactor;
|
||||
else
|
||||
csc_opts->cs_opts_dst.pq_norm = MAX_LUMINANCE;
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void CSCSetDefault(struct s_csc_api_opts* csc_opts)
|
||||
{
|
||||
csc_api_set_def(csc_opts);
|
||||
}
|
||||
|
||||
static void CSCGenerateMap(struct s_csc_api_opts* csc_opts, struct s_csc_map* csc_map)
|
||||
{
|
||||
csc_api_gen_map(csc_opts, csc_map);
|
||||
}
|
||||
|
||||
static enum TMGReturnCode CSCGenerate3DLUT(struct s_csc_api_opts* csc_opts, struct s_csc_map* csc_map)
|
||||
{
|
||||
int retcode = csc_api_gen_3dlut(csc_opts, csc_map);
|
||||
|
||||
return retcode ? TMG_RET_ERROR_GMLIB : TMG_RET_OK;
|
||||
}
|
||||
|
||||
static enum TMGReturnCode CSCGenerator_ApplyCSC(
|
||||
const struct ToneMapHdrMetaData* srcMetaData,
|
||||
enum ToneMapTransferFunction inTf,
|
||||
const struct ToneMapHdrMetaData* dstMetaData,
|
||||
enum ToneMapTransferFunction outTf,
|
||||
struct ToneMappingParameters* tmParams,
|
||||
bool enable3DLUTMerge)
|
||||
{
|
||||
struct s_csc_map csc_map;
|
||||
struct s_csc_api_opts csc_opts;
|
||||
|
||||
CSCCtor(&csc_map);
|
||||
CSCSetDefault(&csc_opts);
|
||||
CSCSetOptions(srcMetaData,
|
||||
inTf,
|
||||
dstMetaData,
|
||||
outTf,
|
||||
tmParams,
|
||||
enable3DLUTMerge,
|
||||
&csc_opts);
|
||||
CSCGenerateMap(&csc_opts, &csc_map);
|
||||
|
||||
return CSCGenerate3DLUT(&csc_opts, &csc_map);
|
||||
}
|
||||
261
src/amd/gmlib/ToneMapGenerator/src/src/AGMGenerator.c
Executable file
261
src/amd/gmlib/ToneMapGenerator/src/src/AGMGenerator.c
Executable file
|
|
@ -0,0 +1,261 @@
|
|||
/* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "AGMGenerator.h"
|
||||
|
||||
// Function declaration
|
||||
void AGMGenerator_GMCtor(struct AGMGenerator* p_agm_generator);
|
||||
void AGMGenerator_GMSetDefault(struct AGMGenerator* p_agm_generator);
|
||||
enum TMGReturnCode AGMGenerator_SetAgmOptions(
|
||||
struct AGMGenerator* p_agm_generator,
|
||||
const struct ToneMapHdrMetaData* srcMetaData,
|
||||
const struct ToneMapHdrMetaData* dstMetaData,
|
||||
const enum ToneMapAlgorithm tmAlgorithm,
|
||||
const struct ToneMappingParameters* tmParams,
|
||||
bool updateSrcParams,
|
||||
bool updateDstParams,
|
||||
bool enableMerge3DLUT);
|
||||
enum TMGReturnCode AGMGenerator_GMGenerateMap(struct AGMGenerator* p_agm_generator);
|
||||
enum TMGReturnCode AGMGenerator_GMGenerate3DLUT(struct AGMGenerator* p_agm_generator);
|
||||
|
||||
static bool TranslateTfEnum(
|
||||
enum ToneMapTransferFunction inTf,
|
||||
enum cs_gamma_type* outTf)
|
||||
{
|
||||
|
||||
switch (inTf) {
|
||||
case(TMG_TF_SRGB):
|
||||
*outTf = EGT_sRGB;
|
||||
break;
|
||||
case(TMG_TF_BT709):
|
||||
*outTf = EGT_709;
|
||||
break;
|
||||
case(TMG_TF_G24):
|
||||
*outTf = EGT_2_4;
|
||||
break;
|
||||
case(TMG_TF_HLG):
|
||||
*outTf = EGT_HLG;
|
||||
break;
|
||||
case(TMG_TF_NormalizedPQ):
|
||||
case(TMG_TF_PQ):
|
||||
*outTf = EGT_PQ;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
enum TMGReturnCode AGMGenerator_SetGMAllocator(
|
||||
struct AGMGenerator* p_agm_generator,
|
||||
TMGAlloc allocFunc,
|
||||
TMGFree freeFunc,
|
||||
void* memCtx)
|
||||
{
|
||||
p_agm_generator->allocFunc = allocFunc;
|
||||
p_agm_generator->freeFunc = freeFunc;
|
||||
p_agm_generator->memoryContext = memCtx;
|
||||
return TMG_RET_OK;
|
||||
}
|
||||
|
||||
enum TMGReturnCode AGMGenerator_ApplyToneMap(
|
||||
struct AGMGenerator* p_agm_generator,
|
||||
const struct ToneMapHdrMetaData* streamMetaData,
|
||||
const struct ToneMapHdrMetaData* dstMetaData,
|
||||
const enum ToneMapAlgorithm tmAlgorithm,
|
||||
const struct ToneMappingParameters* tmParams,
|
||||
bool updateSrcParams,
|
||||
bool updateDstParams,
|
||||
bool enableMerge3DLUT)
|
||||
{
|
||||
enum TMGReturnCode ret = TMG_RET_OK;
|
||||
|
||||
if (!p_agm_generator->initalized) {
|
||||
AGMGenerator_GMCtor(p_agm_generator);
|
||||
AGMGenerator_GMSetDefault(p_agm_generator);
|
||||
p_agm_generator->initalized = true;
|
||||
}
|
||||
|
||||
if ((ret = AGMGenerator_SetAgmOptions(
|
||||
p_agm_generator,
|
||||
streamMetaData,
|
||||
dstMetaData,
|
||||
tmAlgorithm,
|
||||
tmParams,
|
||||
updateSrcParams,
|
||||
updateDstParams,
|
||||
enableMerge3DLUT)) != TMG_RET_OK)
|
||||
goto exit;
|
||||
|
||||
if ((ret = AGMGenerator_GMGenerateMap(p_agm_generator)) != TMG_RET_OK)
|
||||
goto exit;
|
||||
|
||||
if ((ret = AGMGenerator_GMGenerate3DLUT(p_agm_generator)) != TMG_RET_OK)
|
||||
goto exit;
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
enum TMGReturnCode AGMGenerator_SetAgmOptions(
|
||||
struct AGMGenerator* p_agm_generator,
|
||||
const struct ToneMapHdrMetaData* srcMetaData,
|
||||
const struct ToneMapHdrMetaData* dstMetaData,
|
||||
const enum ToneMapAlgorithm tmAlgorithm,
|
||||
const struct ToneMappingParameters* tmParams,
|
||||
bool updateSrcParams,
|
||||
bool updateDstParams,
|
||||
bool enableMerge3DLUT)
|
||||
{
|
||||
enum TMGReturnCode ret = TMG_RET_OK;
|
||||
enum cs_gamma_type inGamma;
|
||||
enum cs_gamma_type outGamma;
|
||||
|
||||
if (!TranslateTfEnum(tmParams->shaperTf, &inGamma)) {
|
||||
ret = TMG_RET_ERROR_INVALID_PARAM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!TranslateTfEnum(tmParams->lutOutTf, &outGamma)) {
|
||||
ret = TMG_RET_ERROR_INVALID_PARAM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (tmAlgorithm == TMG_A_AGM) {
|
||||
p_agm_generator->gamutMapParams.gamut_map_mode = EGMM_TM_CHTO;
|
||||
p_agm_generator->gamutMapParams.hue_rot_mode = EHRM_HR;
|
||||
}
|
||||
else {
|
||||
p_agm_generator->gamutMapParams.gamut_map_mode = EGMM_TM;
|
||||
p_agm_generator->gamutMapParams.hue_rot_mode = EHRM_NONE;
|
||||
}
|
||||
|
||||
p_agm_generator->gamutMapParams.update_msk = updateSrcParams ? GM_UPDATE_SRC : 0;
|
||||
p_agm_generator->gamutMapParams.update_msk = updateDstParams ? (p_agm_generator->gamutMapParams.update_msk | GM_UPDATE_DST) : p_agm_generator->gamutMapParams.update_msk;
|
||||
|
||||
p_agm_generator->gamutMapParams.ptr_3dlut_rgb = tmParams->lutData;
|
||||
p_agm_generator->gamutMapParams.num_pnts_3dlut = tmParams->lutDim;
|
||||
p_agm_generator->gamutMapParams.bitwidth_3dlut = 12;
|
||||
p_agm_generator->gamutMapParams.en_merge_3dlut = enableMerge3DLUT;
|
||||
p_agm_generator->gamutMapParams.mode = GM_PQTAB_GBD;
|
||||
p_agm_generator->gamutMapParams.en_tm_scale_color = 1;
|
||||
p_agm_generator->gamutMapParams.num_hue_pnts = GM_NUM_HUE;
|
||||
p_agm_generator->gamutMapParams.num_edge_pnts = GM_NUM_EDGE;
|
||||
p_agm_generator->gamutMapParams.num_int_pnts = GM_NUM_INT;
|
||||
p_agm_generator->gamutMapParams.org2_perc_c = GM_ORG2_PERC;
|
||||
p_agm_generator->gamutMapParams.step_samp = 0.0005; // GM_STEP_SAMP = 0.0001;
|
||||
p_agm_generator->gamutMapParams.show_pix_mode = ESPM_NONE;
|
||||
|
||||
for (int i = 0; i < GM_NUM_PRIM; i++) {
|
||||
p_agm_generator->gamutMapParams.vec_org1_factor[i] = gm_vec_org13_factor_def[i][0];
|
||||
p_agm_generator->gamutMapParams.vec_org3_factor[i] = gm_vec_org13_factor_def[i][1];
|
||||
}
|
||||
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.color_space_type = ECST_CUSTOM;
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.rgbw_xy[0] =
|
||||
srcMetaData->redPrimaryX / 50000.0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.rgbw_xy[1] =
|
||||
srcMetaData->redPrimaryY / 50000.0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.rgbw_xy[2] =
|
||||
srcMetaData->greenPrimaryX / 50000.0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.rgbw_xy[3] =
|
||||
srcMetaData->greenPrimaryY / 50000.0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.rgbw_xy[4] =
|
||||
srcMetaData->bluePrimaryX / 50000.0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.rgbw_xy[5] =
|
||||
srcMetaData->bluePrimaryY / 50000.0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.rgbw_xy[6] =
|
||||
srcMetaData->whitePointX / 50000.0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.rgbw_xy[7] =
|
||||
srcMetaData->whitePointY / 50000.0;
|
||||
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.gamma_type = inGamma;
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.luminance_limits[0] = 0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.luminance_limits[1] =
|
||||
(double)srcMetaData->maxMasteringLuminance;
|
||||
|
||||
if (tmParams->shaperTf == TMG_TF_NormalizedPQ) {
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.pq_norm = (double)tmParams->inputNormalizationFactor;
|
||||
}
|
||||
else {
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.pq_norm = MAX_LUMINANCE;
|
||||
}
|
||||
|
||||
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.color_space_type = ECST_CUSTOM;
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.rgbw_xy[0] =
|
||||
dstMetaData->redPrimaryX / 50000.0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.rgbw_xy[1] =
|
||||
dstMetaData->redPrimaryY / 50000.0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.rgbw_xy[2] =
|
||||
dstMetaData->greenPrimaryX / 50000.0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.rgbw_xy[3] =
|
||||
dstMetaData->greenPrimaryY / 50000.0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.rgbw_xy[4] =
|
||||
dstMetaData->bluePrimaryX / 50000.0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.rgbw_xy[5] =
|
||||
dstMetaData->bluePrimaryY / 50000.0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.rgbw_xy[6] =
|
||||
dstMetaData->whitePointX / 50000.0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.rgbw_xy[7] =
|
||||
dstMetaData->whitePointY / 50000.0;
|
||||
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.gamma_type = outGamma;
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.mode = 0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.luminance_limits[0] = 0;
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.luminance_limits[1] =
|
||||
(double)dstMetaData->maxMasteringLuminance;
|
||||
|
||||
if (tmParams->lutOutTf == TMG_TF_NormalizedPQ) {
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.pq_norm = (double)tmParams->inputNormalizationFactor;
|
||||
}
|
||||
else {
|
||||
p_agm_generator->gamutMapParams.cs_opts_dst.pq_norm = MAX_LUMINANCE;
|
||||
}
|
||||
|
||||
// Correct Luminance Bounds if Neccessary
|
||||
if (p_agm_generator->gamutMapParams.cs_opts_src.luminance_limits[0] > p_agm_generator->gamutMapParams.cs_opts_dst.luminance_limits[0]) {
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.luminance_limits[0] = p_agm_generator->gamutMapParams.cs_opts_dst.luminance_limits[0];
|
||||
p_agm_generator->gamutMapParams.update_msk |= GM_UPDATE_SRC;
|
||||
}
|
||||
if (p_agm_generator->gamutMapParams.cs_opts_src.luminance_limits[1] < p_agm_generator->gamutMapParams.cs_opts_dst.luminance_limits[1]) {
|
||||
p_agm_generator->gamutMapParams.cs_opts_src.luminance_limits[1] = p_agm_generator->gamutMapParams.cs_opts_dst.luminance_limits[1];
|
||||
p_agm_generator->gamutMapParams.update_msk |= GM_UPDATE_SRC;
|
||||
}
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AGMGenerator_GMSetDefault(struct AGMGenerator* p_agm_generator)
|
||||
{
|
||||
gm_api_set_def(&p_agm_generator->gamutMapParams);
|
||||
}
|
||||
|
||||
enum TMGReturnCode AGMGenerator_GMGenerateMap(struct AGMGenerator* p_agm_generator)
|
||||
{
|
||||
int retcode = gm_api_gen_map(&p_agm_generator->gamutMapParams, &p_agm_generator->agmParams);
|
||||
|
||||
return retcode ? TMG_RET_ERROR_GMLIB : TMG_RET_OK;
|
||||
}
|
||||
|
||||
enum TMGReturnCode AGMGenerator_GMGenerate3DLUT(struct AGMGenerator* p_agm_generator)
|
||||
{
|
||||
int retcode = gm_api_gen_3dlut(&p_agm_generator->gamutMapParams, &p_agm_generator->agmParams);
|
||||
|
||||
return retcode ? TMG_RET_ERROR_GMLIB : TMG_RET_OK;
|
||||
}
|
||||
|
||||
void AGMGenerator_GMCtor(struct AGMGenerator* p_agm_generator)
|
||||
{
|
||||
gm_ctor(&p_agm_generator->agmParams, p_agm_generator->allocFunc, p_agm_generator->freeFunc, p_agm_generator->memoryContext);
|
||||
}
|
||||
|
||||
void AGMGenerator_Exit(struct AGMGenerator* p_agm_generator)
|
||||
{
|
||||
gm_dtor(&p_agm_generator->agmParams);
|
||||
}
|
||||
354
src/amd/gmlib/ToneMapGenerator/src/src/ToneMapGenerator.c
Executable file
354
src/amd/gmlib/ToneMapGenerator/src/src/ToneMapGenerator.c
Executable file
|
|
@ -0,0 +1,354 @@
|
|||
/* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ToneMapGenerator.h"
|
||||
#include "AGMGenerator.h"
|
||||
#include "CSCGenerator.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Defines comes from ColorPrimaryTable.h */
|
||||
struct ToneMapHdrMetaData BT2020Container = {
|
||||
(unsigned short)(0.708 * 50000), (unsigned short)(0.292 * 50000),
|
||||
(unsigned short)(0.17 * 50000), (unsigned short)(0.797 * 50000),
|
||||
(unsigned short)(0.131 * 50000), (unsigned short)(0.046 * 50000),
|
||||
(unsigned short)(0.3127 * 50000), (unsigned short)(0.3290 * 50000),
|
||||
(unsigned int)(10000 * 10000), (unsigned int)(0.05 * 10000),
|
||||
(unsigned short)10000,
|
||||
(unsigned short)10000
|
||||
};
|
||||
|
||||
struct ToneMapHdrMetaData DCIP3Container = {
|
||||
(unsigned short)(0.68 * 50000), (unsigned short)(0.32 * 50000),
|
||||
(unsigned short)(0.265 * 50000), (unsigned short)(0.69 * 50000),
|
||||
(unsigned short)(0.15 * 50000), (unsigned short)(0.06 * 50000),
|
||||
(unsigned short)(0.3127 * 50000), (unsigned short)(0.3290 * 50000),
|
||||
(unsigned int)(10000 * 10000), (unsigned int)(0.05 * 10000),
|
||||
(unsigned short)10000,
|
||||
(unsigned short)10000
|
||||
};
|
||||
|
||||
struct ToneMapHdrMetaData BT709Container = {
|
||||
(unsigned short)(0.64 * 50000), (unsigned short)(0.33 * 50000),
|
||||
(unsigned short)(0.30 * 50000), (unsigned short)(0.60 * 50000),
|
||||
(unsigned short)(0.15 * 50000), (unsigned short)(0.06 * 50000),
|
||||
(unsigned short)(0.3127 * 50000), (unsigned short)(0.3290 * 50000),
|
||||
(unsigned int)(10000 * 10000), (unsigned int)(0.05 * 10000),
|
||||
(unsigned short)10000,
|
||||
(unsigned short)10000
|
||||
};
|
||||
|
||||
struct ToneMapHdrMetaData BT601Container = {
|
||||
(unsigned short)(0.63 * 50000), (unsigned short)(0.34 * 50000),
|
||||
(unsigned short)(0.31 * 50000), (unsigned short)(0.595 * 50000),
|
||||
(unsigned short)(0.155 * 50000), (unsigned short)(0.07 * 50000),
|
||||
(unsigned short)(0.3127 * 50000), (unsigned short)(0.3290 * 50000),
|
||||
(unsigned int)(10000 * 10000), (unsigned int)(0.05 * 10000),
|
||||
(unsigned short)10000,
|
||||
(unsigned short)10000
|
||||
};
|
||||
|
||||
|
||||
//Function declaration
|
||||
enum ToneMapColorPrimaries ToneMapGenerator_GetLutColorIn(void);
|
||||
enum ToneMapColorPrimaries ToneMapGenerator_GetLutColorOut(
|
||||
enum ToneMapTransferFunction outputContainerGamma,
|
||||
enum ToneMapColorPrimaries outputContainerPrimaries);
|
||||
enum ToneMapTransferFunction ToneMapGenerator_GetShaperTf(
|
||||
enum ToneMapTransferFunction inputContainerGamma);
|
||||
enum ToneMapTransferFunction ToneMapGenerator_GetLutOutTf(
|
||||
enum ToneMapTransferFunction outputContainerGamma,
|
||||
enum ToneMapColorPrimaries outputContainerPrimaries);
|
||||
unsigned short ToneMapGenerator_GetInputNormFactor(
|
||||
const struct ToneMapHdrMetaData* streamMetaData);
|
||||
bool ToneMapGenerator_CacheSrcTmParams(
|
||||
struct ToneMapGenerator* p_tmGenerator,
|
||||
const struct ToneMapHdrMetaData* streamMetaData,
|
||||
enum ToneMapTransferFunction inputContainerGamma);
|
||||
bool ToneMapGenerator_CacheDstTmParams(
|
||||
struct ToneMapGenerator* p_tmGenerator,
|
||||
const struct ToneMapHdrMetaData* dstMetaData,
|
||||
enum ToneMapTransferFunction outputContainerGamma,
|
||||
enum ToneMapColorPrimaries outputContainerPrimaries);
|
||||
enum TMGReturnCode ToneMapGenerator_GenerateLutData(
|
||||
struct ToneMapGenerator* p_tmGenerator,
|
||||
const struct ToneMapHdrMetaData* streamMetaData,
|
||||
const struct ToneMapHdrMetaData* dstMetaData,
|
||||
enum ToneMapAlgorithm tmAlgorithm,
|
||||
bool updateSrcParams,
|
||||
bool updateDstParams,
|
||||
struct ToneMappingParameters* tmParams);
|
||||
struct ToneMapHdrMetaData ToneMapGenerator_GetColorContainerData(
|
||||
enum ToneMapColorPrimaries containerColor);
|
||||
bool ToneMapGenerator_ContentEqualsContainer(
|
||||
const struct ToneMapHdrMetaData* contentMetaData,
|
||||
const struct ToneMapHdrMetaData* containerPrimaries);
|
||||
|
||||
|
||||
enum TMGReturnCode ToneMapGenerator_GenerateToneMappingParameters(
|
||||
struct ToneMapGenerator* p_tmGenerator,
|
||||
const struct ToneMapHdrMetaData* streamMetaData,
|
||||
const struct ToneMapHdrMetaData* dstMetaData,
|
||||
enum ToneMapTransferFunction inputContainerGamma,
|
||||
enum ToneMapTransferFunction outputContainerGamma,
|
||||
enum ToneMapColorPrimaries outputContainerPrimaries,
|
||||
unsigned short lutDim,
|
||||
struct ToneMappingParameters* tmParams)
|
||||
{
|
||||
|
||||
enum TMGReturnCode ret = TMG_RET_OK;
|
||||
bool updateSrcParams;
|
||||
bool updateDstParams;
|
||||
|
||||
if (!p_tmGenerator->memAllocSet) {
|
||||
ret = TMG_RET_ERROR_NOT_INITIALIZED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tmParams->lutOutTf = ToneMapGenerator_GetLutOutTf(outputContainerGamma, outputContainerPrimaries);
|
||||
tmParams->lutColorIn = ToneMapGenerator_GetLutColorIn();
|
||||
tmParams->lutColorOut = ToneMapGenerator_GetLutColorOut(outputContainerGamma, outputContainerPrimaries);
|
||||
tmParams->shaperTf = ToneMapGenerator_GetShaperTf(inputContainerGamma);
|
||||
tmParams->formattedLutData = NULL;
|
||||
tmParams->lutDim = lutDim;
|
||||
tmParams->inputNormalizationFactor = ToneMapGenerator_GetInputNormFactor(streamMetaData);
|
||||
|
||||
updateSrcParams = ToneMapGenerator_CacheSrcTmParams(p_tmGenerator, streamMetaData, inputContainerGamma);
|
||||
updateDstParams = ToneMapGenerator_CacheDstTmParams(p_tmGenerator, dstMetaData, outputContainerGamma, outputContainerPrimaries);
|
||||
|
||||
ret = ToneMapGenerator_GenerateLutData(p_tmGenerator, streamMetaData, dstMetaData, p_tmGenerator->tmAlgo, updateSrcParams, updateDstParams, tmParams);
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
enum ToneMapColorPrimaries ToneMapGenerator_GetLutColorIn()
|
||||
{
|
||||
return TMG_CP_BT2020;
|
||||
}
|
||||
|
||||
enum ToneMapColorPrimaries ToneMapGenerator_GetLutColorOut(
|
||||
enum ToneMapTransferFunction outputContainerGamma,
|
||||
enum ToneMapColorPrimaries outputContainerPrimaries)
|
||||
{
|
||||
enum ToneMapColorPrimaries lutOutPrimaries;
|
||||
|
||||
if (outputContainerGamma == TMG_TF_Linear)
|
||||
lutOutPrimaries = TMG_CP_BT2020;
|
||||
else
|
||||
lutOutPrimaries = outputContainerPrimaries;
|
||||
|
||||
return lutOutPrimaries;
|
||||
}
|
||||
|
||||
enum ToneMapTransferFunction ToneMapGenerator_GetShaperTf(
|
||||
enum ToneMapTransferFunction inputContainerGamma)
|
||||
{
|
||||
enum ToneMapTransferFunction shaperTf;
|
||||
|
||||
switch (inputContainerGamma) {
|
||||
case(TMG_TF_PQ):
|
||||
case(TMG_TF_Linear):
|
||||
shaperTf = TMG_TF_NormalizedPQ;
|
||||
break;
|
||||
default:
|
||||
shaperTf = inputContainerGamma;
|
||||
break;
|
||||
}
|
||||
|
||||
return shaperTf;
|
||||
}
|
||||
|
||||
enum ToneMapTransferFunction ToneMapGenerator_GetLutOutTf(
|
||||
enum ToneMapTransferFunction outputContainerGamma,
|
||||
enum ToneMapColorPrimaries outputContainerPrimaries)
|
||||
{
|
||||
enum ToneMapTransferFunction lutOutTf;
|
||||
|
||||
if (outputContainerGamma == TMG_TF_Linear ||
|
||||
outputContainerGamma == TMG_TF_PQ)
|
||||
lutOutTf = TMG_TF_PQ;
|
||||
else
|
||||
lutOutTf = outputContainerGamma;
|
||||
|
||||
return lutOutTf;
|
||||
}
|
||||
|
||||
struct ToneMapHdrMetaData ToneMapGenerator_GetColorContainerData(enum ToneMapColorPrimaries containerColor) {
|
||||
|
||||
switch (containerColor) {
|
||||
case (TMG_CP_BT601):
|
||||
return BT601Container;
|
||||
break;
|
||||
case (TMG_CP_BT709):
|
||||
return BT709Container;
|
||||
break;
|
||||
case (TMG_CP_BT2020):
|
||||
return BT2020Container;
|
||||
break;
|
||||
case (TMG_CP_DCIP3):
|
||||
return DCIP3Container;
|
||||
break;
|
||||
default:
|
||||
return BT2020Container;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsigned short ToneMapGenerator_GetInputNormFactor(const struct ToneMapHdrMetaData* streamMetaData) {
|
||||
|
||||
unsigned short normFactor;
|
||||
|
||||
if (streamMetaData->maxMasteringLuminance < INPUT_NORMALIZATION_FACTOR)
|
||||
normFactor = INPUT_NORMALIZATION_FACTOR;
|
||||
else
|
||||
normFactor = streamMetaData->maxMasteringLuminance;
|
||||
|
||||
return normFactor;
|
||||
}
|
||||
|
||||
bool ToneMapGenerator_ContentEqualsContainer(
|
||||
const struct ToneMapHdrMetaData* contentMetaData,
|
||||
const struct ToneMapHdrMetaData* containerPrimaries)
|
||||
{
|
||||
|
||||
if (abs(contentMetaData->bluePrimaryX - containerPrimaries->redPrimaryX) < 2 &&
|
||||
abs(contentMetaData->redPrimaryY - containerPrimaries->redPrimaryY) < 2 &&
|
||||
abs(contentMetaData->greenPrimaryX - containerPrimaries->greenPrimaryX) < 2 &&
|
||||
abs(contentMetaData->greenPrimaryY - containerPrimaries->greenPrimaryY) < 2 &&
|
||||
abs(contentMetaData->bluePrimaryX - containerPrimaries->bluePrimaryX) < 2 &&
|
||||
abs(contentMetaData->bluePrimaryY - containerPrimaries->bluePrimaryY) < 2)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Tone map generation consists of three steps:
|
||||
1. Container to content color space conversion.
|
||||
2. Tone mapping and gamut mapping operation.
|
||||
3. Content to output container color space conversion.
|
||||
|
||||
These operations are cascaded one after the other. The enable3DLUTMerge will tell each module
|
||||
whether or not to start from scratch, or use the previous blocks output as the nextbloack input.
|
||||
|
||||
The terminology "Content Color Space / Container Color Space" is used to distinguish
|
||||
between the color volume of the content and the color volume of the container.
|
||||
For example, the content color volume might be DCIP3 and the Container might be BT2020.
|
||||
CSC step changes the representation of the content to align with its color volume.
|
||||
*/
|
||||
enum TMGReturnCode ToneMapGenerator_GenerateLutData(
|
||||
struct ToneMapGenerator* p_tmGenerator,
|
||||
const struct ToneMapHdrMetaData* streamMetaData,
|
||||
const struct ToneMapHdrMetaData* dstMetaData,
|
||||
enum ToneMapAlgorithm tmAlgorithm,
|
||||
bool updateSrcParams,
|
||||
bool updateDstParams,
|
||||
struct ToneMappingParameters* tmParams)
|
||||
{
|
||||
|
||||
bool enable3DLUTMerge = false;
|
||||
struct ToneMapHdrMetaData lutContainer = ToneMapGenerator_GetColorContainerData(tmParams->lutColorIn);
|
||||
|
||||
if (!ToneMapGenerator_ContentEqualsContainer(streamMetaData, &lutContainer)) {
|
||||
lutContainer.maxMasteringLuminance = streamMetaData->maxMasteringLuminance;
|
||||
lutContainer.minMasteringLuminance = streamMetaData->minMasteringLuminance;
|
||||
|
||||
CSCGenerator_ApplyCSC(
|
||||
&lutContainer,
|
||||
tmParams->shaperTf,
|
||||
streamMetaData,
|
||||
tmParams->shaperTf,
|
||||
tmParams,
|
||||
enable3DLUTMerge);
|
||||
|
||||
enable3DLUTMerge = true;
|
||||
}
|
||||
|
||||
AGMGenerator_ApplyToneMap(
|
||||
&p_tmGenerator->agmGenerator,
|
||||
streamMetaData,
|
||||
dstMetaData,
|
||||
tmAlgorithm,
|
||||
tmParams,
|
||||
updateSrcParams,
|
||||
updateDstParams,
|
||||
enable3DLUTMerge);
|
||||
|
||||
enable3DLUTMerge = true;
|
||||
|
||||
lutContainer = ToneMapGenerator_GetColorContainerData(tmParams->lutColorOut);
|
||||
if (!ToneMapGenerator_ContentEqualsContainer(dstMetaData, &lutContainer)) {
|
||||
lutContainer.maxMasteringLuminance = dstMetaData->maxMasteringLuminance;
|
||||
lutContainer.minMasteringLuminance = dstMetaData->minMasteringLuminance;
|
||||
|
||||
CSCGenerator_ApplyCSC(
|
||||
dstMetaData,
|
||||
tmParams->lutOutTf,
|
||||
&lutContainer,
|
||||
tmParams->lutOutTf,
|
||||
tmParams,
|
||||
enable3DLUTMerge
|
||||
);
|
||||
}
|
||||
|
||||
return TMG_RET_OK;
|
||||
}
|
||||
|
||||
bool ToneMapGenerator_CacheSrcTmParams(
|
||||
struct ToneMapGenerator* p_tmGenerator,
|
||||
const struct ToneMapHdrMetaData* streamMetaData,
|
||||
enum ToneMapTransferFunction inputContainerGamma)
|
||||
{
|
||||
bool updateSrcParams = memcmp(streamMetaData, &p_tmGenerator->cachedSrcTmParams.streamMetaData, sizeof(struct ToneMapHdrMetaData)) ||
|
||||
inputContainerGamma != p_tmGenerator->cachedSrcTmParams.inputContainerGamma;
|
||||
|
||||
if (updateSrcParams) {
|
||||
memcpy(&p_tmGenerator->cachedSrcTmParams.streamMetaData, streamMetaData, sizeof(struct ToneMapHdrMetaData));
|
||||
p_tmGenerator->cachedSrcTmParams.inputContainerGamma = inputContainerGamma;
|
||||
}
|
||||
|
||||
return updateSrcParams;
|
||||
}
|
||||
|
||||
bool ToneMapGenerator_CacheDstTmParams(
|
||||
struct ToneMapGenerator* p_tmGenerator,
|
||||
const struct ToneMapHdrMetaData* dstMetaData,
|
||||
enum ToneMapTransferFunction outputContainerGamma,
|
||||
enum ToneMapColorPrimaries outputContainerPrimaries)
|
||||
{
|
||||
bool updateDstParams = memcmp(dstMetaData, &p_tmGenerator->cachedDstTmParams.dstMetaData, sizeof(struct ToneMapHdrMetaData)) ||
|
||||
outputContainerGamma != p_tmGenerator->cachedDstTmParams.outputContainerGamma ||
|
||||
outputContainerPrimaries != p_tmGenerator->cachedDstTmParams.outputContainerPrimaries;
|
||||
|
||||
if (updateDstParams){
|
||||
memcpy(&p_tmGenerator->cachedDstTmParams.dstMetaData, dstMetaData, sizeof(struct ToneMapHdrMetaData));
|
||||
p_tmGenerator->cachedDstTmParams.outputContainerGamma = outputContainerGamma;
|
||||
p_tmGenerator->cachedDstTmParams.outputContainerPrimaries = outputContainerPrimaries;
|
||||
p_tmGenerator->cachedDstTmParams.outputContainerPrimaries = outputContainerPrimaries;
|
||||
}
|
||||
|
||||
return updateDstParams;
|
||||
}
|
||||
|
||||
enum TMGReturnCode ToneMapGenerator_SetInternalAllocators(
|
||||
struct ToneMapGenerator* p_tmGenerator,
|
||||
TMGAlloc allocFunc,
|
||||
TMGFree freeFunc,
|
||||
void* memCtx)
|
||||
{
|
||||
enum TMGReturnCode ret = AGMGenerator_SetGMAllocator(
|
||||
&p_tmGenerator->agmGenerator,
|
||||
allocFunc,
|
||||
freeFunc,
|
||||
memCtx);
|
||||
|
||||
p_tmGenerator->memAllocSet = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
1418
src/amd/gmlib/gm/cs_funcs.c
Executable file
1418
src/amd/gmlib/gm/cs_funcs.c
Executable file
File diff suppressed because it is too large
Load diff
273
src/amd/gmlib/gm/cs_funcs.h
Executable file
273
src/amd/gmlib/gm/cs_funcs.h
Executable file
|
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
* File Name : cs_funcs.h
|
||||
* Purpose : Color Space functions
|
||||
* Author : Vladimir Lachine (vlachine@amd.com)
|
||||
* Date : September 20, 2023
|
||||
* Version : 1.4
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mat_funcs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CS_MAX_LUMINANCE 10000.0
|
||||
#define CS_SCALE_CCCS 125.0
|
||||
#define CS_CHAD_D65 0x01 /* apply chromatic adaptation */
|
||||
|
||||
static MATFLOAT cs_mat_709_2020[3][3] = { /* BT.2087 */
|
||||
{0.6274, 0.3293, 0.0433},
|
||||
{0.0691, 0.9195, 0.0114},
|
||||
{0.0164, 0.0880, 0.8956}
|
||||
};
|
||||
|
||||
enum cs_white_point_type {
|
||||
EWPT_NONE = 0, /* NATIVE */
|
||||
EWPT_A = 1,
|
||||
EWPT_B = 2,
|
||||
EWPT_C = 3,
|
||||
EWPT_D50 = 4,
|
||||
EWPT_D55 = 5,
|
||||
EWPT_D65 = 6, /* 709, sRRGB, ADOBE, APPLE */
|
||||
EWPT_D75 = 7,
|
||||
EWPT_9300 = 8,
|
||||
EWPT_E = 9,
|
||||
EWPT_F2 = 10,
|
||||
EWPT_F7 = 11,
|
||||
EWPT_F11 = 12,
|
||||
EWPT_DCIP3 = 13, /* DCI-P3 */
|
||||
EWPT_11000 = 14, /* 11000K */
|
||||
EWPT_NUM = 15 /* CUSTOM */
|
||||
};
|
||||
|
||||
enum cs_gamma_type {
|
||||
EGT_LINEAR = 0, /* LINEAR */
|
||||
EGT_709 = 1, /* 709 (SD/HD) */
|
||||
EGT_ADOBE = 2, /* ADOBE 1998 */
|
||||
EGT_DCIP3 = 3, /* DCI-P3 */
|
||||
EGT_APPLE = 4, /* APPLE */
|
||||
EGT_sRGB = 5, /* sRGB */
|
||||
EGT_PQ = 6, /* PQ */
|
||||
EGT_HLG = 7, /* HLG */
|
||||
EGT_2_2 = 8, /* 2.2 */
|
||||
EGT_2_4 = 9, /* 2.4 */
|
||||
EGT_CUSTOM = 10 /* CUSTOM */
|
||||
};
|
||||
|
||||
enum cs_color_space_type {
|
||||
ECST_709 = 0, /* 709(HD),sRGB */
|
||||
ECST_SMPTE = 1, /* SMPTE RP125 (SD) */
|
||||
ECST_ADOBE = 2, /* ADOBE 1998 */
|
||||
ECST_DCIP3 = 3, /* DCI-P3 */
|
||||
ECST_APPLE = 4, /* APPLE */
|
||||
ECST_EBU = 5, /* EBU 3213 (576i) */
|
||||
ECST_NTSC = 6, /* NTSC 1953 */
|
||||
ECST_CIE = 7, /* CIE */
|
||||
ECST_BT2020 = 8, /* BT.2020 */
|
||||
ECST_CUSTOM = 9 /* CUSTOM */
|
||||
};
|
||||
|
||||
enum cs_gamma_dir {
|
||||
EGD_NONLIN_2_LIN = 0,
|
||||
EGD_LIN_2_NONLIN = 1
|
||||
};
|
||||
|
||||
struct s_cs_opts {
|
||||
/* Color Space Type: [0,9]=0 : 0-709, 1-SMPTE, 2-ADOBE1998, 3-DCI-P3, 4-APPLE,
|
||||
5-EBU3213, 6-NTSC, 7-CIE, 8-BT2020, 9-CUSTOM */
|
||||
enum cs_color_space_type color_space_type;
|
||||
/* Gamma Type: [0,9]=1 : 0-LINEAR, 1-709, 2-ADOBE, 3-DCI-P3, 4-APPLE,
|
||||
5-sRGB, 6-PQ, 7-HLG, 8-G2.2, 9-G2.4, 10-CUSTOM */
|
||||
enum cs_gamma_type gamma_type;
|
||||
MATFLOAT luminance_limits[2]; /* luminance min/max in a range [0.0,10000.0]= {0.0,400.0} */
|
||||
MATFLOAT pq_norm; /* normalizatiion luminance for PQ: [0.0,10000.0] = 0.0 - no normalization */
|
||||
unsigned int mode; /* mode: {0,1}=0 : Enable/disable Chromatic adaptation */
|
||||
MATFLOAT rgbw_xy[8]; /* Chromaticity: Red, Green, Blue, White in xy */
|
||||
MATFLOAT gamma_parm[4]; /* Gamma parameters: (0.0,?,?,?) - PQ, (0.5,?,?,?) - HLG */
|
||||
};
|
||||
|
||||
struct s_color_space {
|
||||
/* input parameters */
|
||||
/* cs_color_space_type: [0,9]=9 : 0-709, 1-SMPTE, 2-ADOBE1998, 3-DCI-P3, 4-APPLE,
|
||||
5-EBU3213, 6-NTSC, 7-CIE, 8-BT2020, 9-CUSTOM */
|
||||
enum cs_color_space_type color_space_type;
|
||||
/* cs_gamma_type: [0,9]=9 : 0-LINEAR, 1-709, 2-ADOBE, 3-DCI-P3, 4-APPLE,
|
||||
5-sRGB, 6-PQ, 7-HLG, 8-Gamma2.2, 9-CUSTOM */
|
||||
enum cs_gamma_type gamma_type;
|
||||
/* luminances min/max/range normilized to 10000.0 in a range [0.0,1.0]=0.0,1.0,1.0 */
|
||||
MATFLOAT luminance_limits[3];
|
||||
MATFLOAT pq_norm; /* normalizatiion luminance for PQ: [0.0,10000.0] = 0.0 - no normalization */
|
||||
unsigned int mode; /* mode: {0,1}=0 : CS_CHAD_D65 - Enable Chromatic Adaptation */
|
||||
/* custom or initialized parameters based on input parameters */
|
||||
MATFLOAT rgbw_xy[8]; /* Red, Green, Blue, White in xy */
|
||||
MATFLOAT gamma_parm[4]; /* Gamma parameters: 0.0,?,?,? - PQ, 0.5,?,?,? - HLG */
|
||||
/* calculated variables */
|
||||
MATFLOAT luma_limits[3]; /* Min/max/range luma (PQ) normilized to 10000 : [0.0,1.0]=0,1,1 */
|
||||
MATFLOAT mat_rgb2xyz[3][3]; /* RGB to XYZ matrix */
|
||||
MATFLOAT mat_xyz2rgb[3][3]; /* XYZ to RGB matrix */
|
||||
MATFLOAT mat_rgb2lms[3][3]; /* RGB to LMS matrix */
|
||||
MATFLOAT mat_lms2rgb[3][3]; /* LMS to RGB matrix */
|
||||
MATFLOAT mat_lms2itp[3][3]; /* LMS to ITP matrix */
|
||||
MATFLOAT mat_itp2lms[3][3]; /* ITP to LMS matrix */
|
||||
MATFLOAT mat_chad[3][3]; /* Chromatic Adaptation matrix */
|
||||
MATFLOAT white_xyz[3]; /* White in XYZ */
|
||||
int cct; /* Correlated Color Temperature */
|
||||
MATFLOAT hlg_system_gamma; /* HLG OOTF system gamma for */
|
||||
MATFLOAT hlg_beta; /* user black level lift */
|
||||
};
|
||||
|
||||
/* get internal constants */
|
||||
const MATFLOAT *cs_get_gamma(enum cs_gamma_type gamma_type);
|
||||
const MATFLOAT *cs_get_color_space(enum cs_color_space_type color_space_type);
|
||||
const MATFLOAT *cs_get_white_point(enum cs_white_point_type white_point_type);
|
||||
|
||||
/* initilize color space functions */
|
||||
void cs_set_opts_def(struct s_cs_opts *ptr_cs_opts);
|
||||
void cs_init(struct s_cs_opts *ptr_cs_opts, struct s_color_space *ptr_color_space);
|
||||
void cs_init_private(struct s_color_space *ptr_color_space);
|
||||
void cs_copy(struct s_color_space *ptr_color_space_src, struct s_color_space *ptr_color_space_dst);
|
||||
void cs_luminance_to_luma_limits(MATFLOAT luminance_limits[2], MATFLOAT luma_limits[3]);
|
||||
|
||||
/* color formats conversion functions */
|
||||
void cs_xyy_to_xyz(MATFLOAT xyy_inp[3], MATFLOAT xyz_out[3]);
|
||||
void cs_xyz_to_xyy(MATFLOAT xyz_inp[3], MATFLOAT xyy_out[3]);
|
||||
|
||||
void cs_xyzc_to_xyz(MATFLOAT xyz_inp[3], MATFLOAT xyz_out[3]);
|
||||
void cs_xyz_to_xyzc(MATFLOAT xyz_inp[3], MATFLOAT xyz_out[3]);
|
||||
|
||||
void cs_rgb_to_itp(struct s_color_space *ptr_color_space, MATFLOAT rgb_inp[3], MATFLOAT itp_out[3]);
|
||||
void cs_itp_to_rgb(struct s_color_space *ptr_color_space, MATFLOAT itp_inp[3], MATFLOAT rgb_out[3]);
|
||||
|
||||
void cs_ich_to_itp(MATFLOAT ich_inp[3], MATFLOAT itp_out[3]);
|
||||
void cs_itp_to_ich(MATFLOAT itp_inp[3], MATFLOAT ich_out[3]);
|
||||
|
||||
void cs_rgb_to_yuv(MATFLOAT rgb_inp[3], MATFLOAT yuv_out[3]);
|
||||
void cs_yuv_to_rgb(MATFLOAT yuv_inp[3], MATFLOAT rgb_out[3]);
|
||||
|
||||
MATFLOAT cs_nlin_to_lin(struct s_color_space *ptr_color_space, MATFLOAT val_inp);
|
||||
void cs_nlin_to_lin_rgb(struct s_color_space *ptr_color_space, MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3]);
|
||||
|
||||
MATFLOAT cs_lin_to_nlin(struct s_color_space *ptr_color_space, MATFLOAT val_inp);
|
||||
void cs_lin_to_nlin_rgb(struct s_color_space *ptr_color_space, MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3]);
|
||||
|
||||
/* internal matrixes genereation functions */
|
||||
int cs_genmat_rgb_to_xyz(MATFLOAT rgbw_xy[8], MATFLOAT mat_rgb2xyz[3][3]);
|
||||
int cs_genmat_xyz_to_rgb(MATFLOAT rgbw_xy[8], MATFLOAT mat_xyz2rgb[3][3]);
|
||||
int cs_genmat_rgb_to_rgb(MATFLOAT rgbw_xy_src[8], MATFLOAT rgbw_xy_dst[8], MATFLOAT mat_rgb2rgb[3][3], int en_chad);
|
||||
int cs_genmat_chad(MATFLOAT white_xy_src[2], MATFLOAT white_xy_dst[2], MATFLOAT mat_chad[3][3]);
|
||||
|
||||
/* gamma curves generation functions */
|
||||
MATFLOAT cs_gamma(MATFLOAT val, MATFLOAT gamma_parm[4], enum cs_gamma_dir gamma_dir);
|
||||
MATFLOAT cs_gamma_pq(MATFLOAT val, enum cs_gamma_dir gamma_dir);
|
||||
MATFLOAT cs_gamma_1886(MATFLOAT val, MATFLOAT lb, MATFLOAT lw, MATFLOAT gamma);
|
||||
|
||||
void cs_pq_ootf(MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3]);
|
||||
|
||||
void cs_sdr_to_pq(MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3], MATFLOAT en_709_2020);
|
||||
|
||||
void cs_gamma_rgb(MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3], MATFLOAT gamma_parm[4], enum cs_gamma_dir gamma_dir);
|
||||
|
||||
/* signal clipping functions */
|
||||
int cs_min_rgb(MATFLOAT rgb[3], MATFLOAT val_min);
|
||||
int cs_max_rgb(MATFLOAT rgb[3], MATFLOAT val_max);
|
||||
|
||||
/* signal validation functions */
|
||||
int cs_is_valid_itp(struct s_color_space *ptr_color_space, MATFLOAT itp[3]);
|
||||
int cs_is_valid_ic(struct s_color_space *ptr_color_space, MATFLOAT pnt_ic[2], MATFLOAT hue_sin_cos[2]);
|
||||
int cs_is_valid_rgb(MATFLOAT rgb[3], MATFLOAT val_min, MATFLOAT val_max);
|
||||
int cs_clip_rgb(MATFLOAT rgb[3], MATFLOAT val_min, MATFLOAT val_max);
|
||||
void cs_clamp_rgb(MATFLOAT rgb[3], MATFLOAT val_min, MATFLOAT val_max);
|
||||
|
||||
/* signal normalization functions */
|
||||
void cs_norm_rgb(MATFLOAT rgb[3], MATFLOAT val_min, MATFLOAT val_rng);
|
||||
void cs_denorm_rgb(MATFLOAT rgb[3], MATFLOAT val_min, MATFLOAT val_rng);
|
||||
|
||||
/* signal format conversion functions */
|
||||
void cs_int2flt_rgb(int rgb_inp[3], MATFLOAT rgb_out[3], int val_max);
|
||||
void cs_flt2int_rgb(MATFLOAT rgb_inp[3], int rgb_out[3], int val_max);
|
||||
void cs_short2flt_rgb(unsigned short rgb_inp[3], MATFLOAT rgb_out[3], int val_max);
|
||||
void cs_flt2short_rgb(MATFLOAT rgb_inp[3], unsigned short rgb_out[3], int val_max);
|
||||
|
||||
void cs_genprim_itp(struct s_color_space *ptr_color_space,
|
||||
int num_prim, MATFLOAT *ptr_prim_rgb, MATFLOAT *ptr_prim_ich);
|
||||
|
||||
/* gamma curve handling functions */
|
||||
MATFLOAT cs_soft_clip(MATFLOAT val, MATFLOAT limits_src[3], MATFLOAT limits_dst[3]);
|
||||
MATFLOAT cs_gamma_to_gamma(MATFLOAT val, enum cs_gamma_type gamma_type_src, enum cs_gamma_type gamma_type_dst,
|
||||
MATFLOAT luminance_limits_dst[3], MATFLOAT luma_limits_src[3], MATFLOAT luma_limits_dst[3],
|
||||
MATFLOAT(*func_pq_to_pq)(MATFLOAT), int en_norm, int en_soft_clip);
|
||||
|
||||
/* CCT handling functions */
|
||||
#define CS_CCT_MIN 1000
|
||||
#define CS_CCT_MAX 20000
|
||||
#define CS_CCT_INC 100
|
||||
#define CS_CCT_SIZE ((CS_CCT_MAX - CS_CCT_MIN) / CS_CCT_INC + 1)
|
||||
|
||||
int cs_xy_to_cct(MATFLOAT white_xy[2]);
|
||||
void cs_cct_to_xy(int cct, MATFLOAT xy[2]);
|
||||
void cs_csc(struct s_color_space *ptr_cs_src, struct s_color_space *ptr_cs_dst,
|
||||
MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3], int en_chad);
|
||||
int cs_is_space(struct s_color_space *ptr_color_space,
|
||||
enum cs_color_space_type color_space_type, enum cs_gamma_type gamma_type);
|
||||
|
||||
void cs_init_type(MATFLOAT luminance_limits[2],
|
||||
enum cs_color_space_type color_space_type, enum cs_gamma_type gamma_type,
|
||||
struct s_color_space *ptr_color_space);
|
||||
void cs_init_BT709(MATFLOAT luminance_limits[2], struct s_color_space *ptr_color_space);
|
||||
void cs_init_BT2100(MATFLOAT luminance_limits[2], struct s_color_space *ptr_color_space);
|
||||
void cs_rgb_to_ycbcr2020(MATFLOAT rgb_inp[3], MATFLOAT ycbcr_out[3]);
|
||||
|
||||
MATFLOAT cs_ootf_gamma_peak(MATFLOAT gamma, MATFLOAT luminance_peak);
|
||||
MATFLOAT cs_ootf_gamma_amb(MATFLOAT gamma, MATFLOAT luminance_ambient);
|
||||
MATFLOAT cs_gamma_adjust_sdr(MATFLOAT gamma, MATFLOAT luminance_peak);
|
||||
MATFLOAT cs_gamma_adjust(MATFLOAT gamma, MATFLOAT luminance_peak, MATFLOAT luminance_amb);
|
||||
|
||||
void cs_chad_gains(MATFLOAT rgbw_xy[8], MATFLOAT w_xy[2], MATFLOAT rgb_gain[3]);
|
||||
void cs_genmat_cct(struct s_color_space *ptr_cs, int cct_shift, int norm, MATFLOAT mat_cct[3][3]);
|
||||
|
||||
/* HSV functions */
|
||||
int cs_rgb_to_vsh(MATFLOAT rgb[3], MATFLOAT vsh[3]);
|
||||
void cs_vsh_to_rgb(MATFLOAT vsh[3], MATFLOAT rgb[3]);
|
||||
|
||||
/* YUV functions */
|
||||
void cs_yuv_to_ysh(MATFLOAT yuv_inp[3], MATFLOAT ysh_out[3]);
|
||||
void cs_ysh_to_yuv(MATFLOAT ysh_inp[3], MATFLOAT yuv_out[3]);
|
||||
|
||||
/* CIELAB functions */
|
||||
#define CS_LAB_E 0.008856
|
||||
#define CS_LAB_K 903.3
|
||||
|
||||
void cs_rgb_to_lab(MATFLOAT rgb[3], MATFLOAT lab[3], struct s_color_space *ptr_color_space);
|
||||
void cs_lab_to_rgb(MATFLOAT lab[3], MATFLOAT rgb[3], struct s_color_space *ptr_color_space);
|
||||
void cs_xyz_to_lab(MATFLOAT xyz[3], MATFLOAT lab[3], MATFLOAT white_xyz[3]);
|
||||
void cs_lab_to_xyz(MATFLOAT lab[3], MATFLOAT xyz[3], MATFLOAT white_xyz[3]);
|
||||
MATFLOAT cs_de94(MATFLOAT lab0[3], MATFLOAT lab1[3]);
|
||||
|
||||
/* HLG functions */
|
||||
MATFLOAT cs_gamma_hlg(MATFLOAT val, enum cs_gamma_dir gamma_dir);
|
||||
void cs_hlg_ootf(MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3], MATFLOAT luminance_peak, MATFLOAT system_gamma);
|
||||
void cs_hlg_ootf_inv(MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3], MATFLOAT luminance_peak, MATFLOAT gamma);
|
||||
void cs_hlg_oetf(MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3], MATFLOAT luminance_peak, MATFLOAT system_gamma);
|
||||
void cs_hlg_eotf(MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3], MATFLOAT luminance_limits[3],
|
||||
MATFLOAT system_gamma, MATFLOAT beta);
|
||||
MATFLOAT cs_hlg_system_gamma(MATFLOAT peak_luminance);
|
||||
|
||||
#if 0
|
||||
void cs_pq_to_hlg(MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3], MATFLOAT luminance_peak, MATFLOAT system_gamma);
|
||||
void cs_hlg_to_pq(MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3], MATFLOAT vec_luminance[3],
|
||||
MATFLOAT system_gamma, MATFLOAT beta);
|
||||
void cs_sdr_to_hlg(MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3], MATFLOAT en_709_2020);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
75
src/amd/gmlib/gm/csc_api_funcs.c
Executable file
75
src/amd/gmlib/gm/csc_api_funcs.c
Executable file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
* File Name : csc_api_funcs.c
|
||||
* Purpose : Color Space Conversion 3DLUT functions
|
||||
* Author : Vladimir Lachine (vlachine@amd.com)
|
||||
* Date : June 09, 2023
|
||||
* Version : 1.2
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GM_SIM
|
||||
#pragma code_seg("PAGED3PC")
|
||||
#pragma data_seg("PAGED3PD")
|
||||
#pragma const_seg("PAGED3PR")
|
||||
#endif
|
||||
|
||||
#include "csc_api_funcs.h"
|
||||
|
||||
void csc_api_set_def(struct s_csc_api_opts *ptr_csc_api_opts)
|
||||
{
|
||||
cs_set_opts_def(&ptr_csc_api_opts->cs_opts_src);
|
||||
cs_set_opts_def(&ptr_csc_api_opts->cs_opts_dst);
|
||||
ptr_csc_api_opts->en_chad = 0;
|
||||
|
||||
/* 3DLUT */
|
||||
ptr_csc_api_opts->en_merge_3dlut = 0;
|
||||
ptr_csc_api_opts->num_pnts_3dlut = 17;
|
||||
ptr_csc_api_opts->bitwidth_3dlut = 12;
|
||||
ptr_csc_api_opts->ptr_3dlut_rgb = 0;
|
||||
}
|
||||
|
||||
int csc_api_gen_map(struct s_csc_api_opts *ptr_csc_api_opts, struct s_csc_map *ptr_csc_map)
|
||||
{
|
||||
cs_init(&ptr_csc_api_opts->cs_opts_src, &ptr_csc_map->color_space_src);
|
||||
cs_init(&ptr_csc_api_opts->cs_opts_dst, &ptr_csc_map->color_space_dst);
|
||||
|
||||
ptr_csc_map->en_chad = ptr_csc_api_opts->en_chad;
|
||||
|
||||
return csc_init_map(ptr_csc_map);
|
||||
}
|
||||
|
||||
int csc_api_gen_3dlut(struct s_csc_api_opts *ptr_csc_api_opts, struct s_csc_map *ptr_csc_map)
|
||||
{
|
||||
int index = 0;
|
||||
int value_max = (1 << ptr_csc_api_opts->bitwidth_3dlut) - 1;
|
||||
int nir, nig, nib;
|
||||
|
||||
if (ptr_csc_api_opts->ptr_3dlut_rgb == 0)
|
||||
return -1; /* something wrong */
|
||||
|
||||
for (nir = 0; nir < ptr_csc_api_opts->num_pnts_3dlut; nir++)
|
||||
for (nig = 0; nig < ptr_csc_api_opts->num_pnts_3dlut; nig++)
|
||||
for (nib = 0; nib < ptr_csc_api_opts->num_pnts_3dlut; nib++) {
|
||||
unsigned short rgb[3];
|
||||
MATFLOAT rgb_inp[3], rgb_out[3];
|
||||
|
||||
rgb[0] = ptr_csc_api_opts->en_merge_3dlut ? ptr_csc_api_opts->ptr_3dlut_rgb[index + 0] :
|
||||
(nir * value_max) / (ptr_csc_api_opts->num_pnts_3dlut - 1);
|
||||
rgb[1] = ptr_csc_api_opts->en_merge_3dlut ? ptr_csc_api_opts->ptr_3dlut_rgb[index + 1] :
|
||||
(nig * value_max) / (ptr_csc_api_opts->num_pnts_3dlut - 1);
|
||||
rgb[2] = ptr_csc_api_opts->en_merge_3dlut ? ptr_csc_api_opts->ptr_3dlut_rgb[index + 2] :
|
||||
(nib * value_max) / (ptr_csc_api_opts->num_pnts_3dlut - 1);
|
||||
|
||||
cs_short2flt_rgb(rgb, rgb_inp, value_max);
|
||||
csc_rgb_to_rgb(ptr_csc_map, rgb_inp, rgb_out);
|
||||
cs_flt2short_rgb(rgb_out, &ptr_csc_api_opts->ptr_3dlut_rgb[index], value_max);
|
||||
index += 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
41
src/amd/gmlib/gm/csc_api_funcs.h
Executable file
41
src/amd/gmlib/gm/csc_api_funcs.h
Executable file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
* File Name : csc_api_funcs.h
|
||||
* Purpose : Color Space Conversion 3DLUT functions
|
||||
* Author : Vladimir Lachine (vlachine@amd.com)
|
||||
* Date : June 09, 2023
|
||||
* Version : 1.2
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "csc_funcs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct s_csc_api_opts { /* csc parameters */
|
||||
int en_chad; /* enable/disable chromatic adaptation: {0,1}=0 */
|
||||
struct s_cs_opts cs_opts_src; /* Source color space */
|
||||
struct s_cs_opts cs_opts_dst; /* Destination color space */
|
||||
/* 3DLUT parameters */
|
||||
int en_merge_3dlut;
|
||||
int num_pnts_3dlut;
|
||||
int bitwidth_3dlut;
|
||||
unsigned short *ptr_3dlut_rgb;
|
||||
};
|
||||
|
||||
void csc_api_set_def(struct s_csc_api_opts *ptr_csc_api_opts);
|
||||
|
||||
int csc_api_gen_map(struct s_csc_api_opts *ptr_csc_api_opts, struct s_csc_map *ptr_csc_map);
|
||||
int csc_api_gen_3dlut(struct s_csc_api_opts *ptr_csc_api_opts, struct s_csc_map *ptr_csc_map);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
56
src/amd/gmlib/gm/csc_funcs.c
Executable file
56
src/amd/gmlib/gm/csc_funcs.c
Executable file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
* File Name : csc_funcs.c
|
||||
* Purpose : Color Space Conversion 3DLUT functions
|
||||
* Author : Vladimir Lachine (vlachine@amd.com)
|
||||
* Date : June 09, 2023
|
||||
* Version : 1.2
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GM_SIM
|
||||
#pragma code_seg("PAGED3PC")
|
||||
#pragma data_seg("PAGED3PD")
|
||||
#pragma const_seg("PAGED3PR")
|
||||
#endif
|
||||
|
||||
#include "csc_funcs.h"
|
||||
|
||||
void csc_ctor(struct s_csc_map *ptr_csc_map)
|
||||
{
|
||||
csc_set_def(ptr_csc_map);
|
||||
}
|
||||
|
||||
void csc_dtor(struct s_csc_map *ptr_csc_map)
|
||||
{
|
||||
}
|
||||
|
||||
void csc_set_def(struct s_csc_map *ptr_csc_map)
|
||||
{
|
||||
ptr_csc_map->en_chad = 0;
|
||||
mat_3x3_unity(ptr_csc_map->mat_csc);
|
||||
}
|
||||
|
||||
int csc_init_map(struct s_csc_map *ptr_csc_map)
|
||||
{
|
||||
cs_genmat_rgb_to_rgb(ptr_csc_map->color_space_src.rgbw_xy, ptr_csc_map->color_space_dst.rgbw_xy,
|
||||
ptr_csc_map->mat_csc, ptr_csc_map->en_chad);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int csc_rgb_to_rgb(struct s_csc_map *ptr_csc_map, MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3])
|
||||
{
|
||||
MATFLOAT rgb_tmp[3];
|
||||
|
||||
cs_nlin_to_lin_rgb(&ptr_csc_map->color_space_src, rgb_inp, rgb_tmp);
|
||||
mat_eval_3x3(ptr_csc_map->mat_csc, rgb_tmp, rgb_out);
|
||||
cs_clamp_rgb(rgb_out, 0.0, 1.0);
|
||||
cs_lin_to_nlin_rgb(&ptr_csc_map->color_space_dst, rgb_out, rgb_out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
41
src/amd/gmlib/gm/csc_funcs.h
Executable file
41
src/amd/gmlib/gm/csc_funcs.h
Executable file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
* File Name : csc_funcs.h
|
||||
* Purpose : Color Space Conversion 3DLUT functions
|
||||
* Author : Vladimir Lachine (vlachine@amd.com)
|
||||
* Date : June 09, 2023
|
||||
* Version : 1.2
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cs_funcs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct s_csc_map {
|
||||
int en_chad; /* enable/disable chromatic adaptation: {0,1}=0 */
|
||||
struct s_color_space color_space_src; /* Source color space */
|
||||
struct s_color_space color_space_dst; /* Destination color space */
|
||||
MATFLOAT mat_csc[3][3]; /* color space conversion matrix */
|
||||
};
|
||||
|
||||
/* constructor and destructor */
|
||||
void csc_ctor(struct s_csc_map *ptr_csc_map);
|
||||
void csc_dtor(struct s_csc_map *ptr_csc_map);
|
||||
|
||||
void csc_set_def(struct s_csc_map *ptr_csc_map);
|
||||
int csc_init_map(struct s_csc_map *ptr_csc_map);
|
||||
|
||||
int csc_rgb_to_rgb(struct s_csc_map *ptr_csc_map, MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
85
src/amd/gmlib/gm/cvd_api_funcs.c
Executable file
85
src/amd/gmlib/gm/cvd_api_funcs.c
Executable file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
* File Name : cvd_api_funcs.c
|
||||
* Purpose : Color Vision Deficiency functions
|
||||
* Author : Vladimir Lachine (vlachine@amd.com)
|
||||
* Date : January 21, 2020
|
||||
* Version : 1.0
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GM_SIM
|
||||
#pragma code_seg("PAGED3PC")
|
||||
#pragma data_seg("PAGED3PD")
|
||||
#pragma const_seg("PAGED3PR")
|
||||
#endif
|
||||
|
||||
#include "cvd_api_funcs.h"
|
||||
|
||||
void cvd_api_set_def(struct s_cvd_api_opts *ptr_api_cvd_opts)
|
||||
{
|
||||
int nk;
|
||||
|
||||
ptr_api_cvd_opts->mode = ECM_NONE;
|
||||
for (nk = 0; nk < 3; nk++)
|
||||
ptr_api_cvd_opts->gain[nk] = 0.0;
|
||||
|
||||
cs_set_opts_def(&ptr_api_cvd_opts->cs_opts);
|
||||
|
||||
ptr_api_cvd_opts->en_merge_3dlut = 0;
|
||||
ptr_api_cvd_opts->num_pnts_3dlut = 17;
|
||||
ptr_api_cvd_opts->bitwidth_3dlut = 12;
|
||||
ptr_api_cvd_opts->ptr_3dlut_rgb = 0;
|
||||
}
|
||||
|
||||
int cvd_api_gen_map(struct s_cvd_api_opts *ptr_api_cvd_opts, struct s_cvd_map *ptr_cvd_map)
|
||||
{
|
||||
int nk;
|
||||
|
||||
cvd_set_def(ptr_cvd_map);
|
||||
|
||||
ptr_cvd_map->mode = ptr_api_cvd_opts->mode;
|
||||
for (nk = 0; nk < 3; nk++)
|
||||
ptr_cvd_map->gain[nk] = ptr_api_cvd_opts->gain[nk];
|
||||
|
||||
cs_init(&ptr_api_cvd_opts->cs_opts, &ptr_cvd_map->color_space);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cvd_api_gen_3dlut(struct s_cvd_api_opts *ptr_api_cvd_opts, struct s_cvd_map *ptr_cvd_map)
|
||||
{
|
||||
int index = 0;
|
||||
int nir, nig, nib;
|
||||
int value_max;
|
||||
|
||||
if (ptr_api_cvd_opts->ptr_3dlut_rgb == 0)
|
||||
return -1; /* something wrong */
|
||||
|
||||
value_max = (1 << ptr_api_cvd_opts->bitwidth_3dlut) - 1;
|
||||
for (nir = 0; nir < ptr_api_cvd_opts->num_pnts_3dlut; nir++)
|
||||
for (nig = 0; nig < ptr_api_cvd_opts->num_pnts_3dlut; nig++)
|
||||
for (nib = 0; nib < ptr_api_cvd_opts->num_pnts_3dlut; nib++) {
|
||||
unsigned short rgb[3];
|
||||
MATFLOAT rgb_inp[3], rgb_out[3];
|
||||
|
||||
rgb[0] = ptr_api_cvd_opts->en_merge_3dlut ? ptr_api_cvd_opts->ptr_3dlut_rgb[index + 0] :
|
||||
(nir * value_max) / (ptr_api_cvd_opts->num_pnts_3dlut - 1);
|
||||
rgb[1] = ptr_api_cvd_opts->en_merge_3dlut ? ptr_api_cvd_opts->ptr_3dlut_rgb[index + 1] :
|
||||
(nig * value_max) / (ptr_api_cvd_opts->num_pnts_3dlut - 1);
|
||||
rgb[2] = ptr_api_cvd_opts->en_merge_3dlut ? ptr_api_cvd_opts->ptr_3dlut_rgb[index + 2] :
|
||||
(nib * value_max) / (ptr_api_cvd_opts->num_pnts_3dlut - 1);
|
||||
|
||||
cs_short2flt_rgb(rgb, rgb_inp, value_max);
|
||||
cvd_rgb_to_rgb(ptr_cvd_map, rgb_inp, rgb_out);
|
||||
cs_flt2short_rgb(rgb_out, &ptr_api_cvd_opts->ptr_3dlut_rgb[index], value_max);
|
||||
|
||||
index += 3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
42
src/amd/gmlib/gm/cvd_api_funcs.h
Executable file
42
src/amd/gmlib/gm/cvd_api_funcs.h
Executable file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
* File Name : cvd_api_funcs.h
|
||||
* Purpose : Color Vision Deficiency functions
|
||||
* Author : Vladimir Lachine (vlachine@amd.com)
|
||||
* Date : January 21, 2020
|
||||
* Version : 1.0
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cvd_funcs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct s_cvd_api_opts {
|
||||
/* cvd parameters */
|
||||
enum cvd_mode mode; /* CVD mode: 0 - NONE, 1 - 3 sliders, 2 - 1 slider*/
|
||||
MATFLOAT gain[3]; /* Compensation Gain: ([0] - Protanopia, [1] - Deuteranopia, [2] - Tritanopia: [0.0,2.0]=0.0 */
|
||||
struct s_cs_opts cs_opts; /* Color Space parameters */
|
||||
/* 3DLUT parameters */
|
||||
int en_merge_3dlut;
|
||||
int num_pnts_3dlut;
|
||||
int bitwidth_3dlut;
|
||||
unsigned short *ptr_3dlut_rgb;
|
||||
};
|
||||
|
||||
void cvd_api_set_def(struct s_cvd_api_opts *ptr_api_cvd_opts);
|
||||
|
||||
int cvd_api_gen_map(struct s_cvd_api_opts *ptr_api_cvd_opts, struct s_cvd_map *ptr_cvd_map);
|
||||
int cvd_api_gen_3dlut(struct s_cvd_api_opts *ptr_api_cvd_opts, struct s_cvd_map *ptr_cvd_map);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
132
src/amd/gmlib/gm/cvd_funcs.c
Executable file
132
src/amd/gmlib/gm/cvd_funcs.c
Executable file
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
* File Name : cvd_funcs.c
|
||||
* Purpose : Color Vision Deficiency functions
|
||||
* Author : Vladimir Lachine (vlachine@amd.com)
|
||||
* Date : January 21, 2020
|
||||
* Version : 1.0
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GM_SIM
|
||||
#pragma code_seg("PAGED3PC")
|
||||
#pragma data_seg("PAGED3PD")
|
||||
#pragma const_seg("PAGED3PR")
|
||||
#endif
|
||||
|
||||
#include "cvd_funcs.h"
|
||||
|
||||
void cvd_ctor(struct s_cvd_map *ptr_cvd_map)
|
||||
{
|
||||
cvd_set_def(ptr_cvd_map);
|
||||
}
|
||||
|
||||
void cvd_dtor(struct s_cvd_map *ptr_cvd_map)
|
||||
{
|
||||
cvd_set_def(ptr_cvd_map);
|
||||
}
|
||||
|
||||
void cvd_set_def(struct s_cvd_map *ptr_cvd_map)
|
||||
{
|
||||
int nk;
|
||||
|
||||
ptr_cvd_map->mode = ECM_NONE;
|
||||
|
||||
for (nk = 0; nk < 3; nk++)
|
||||
ptr_cvd_map->gain[nk] = 0.0;
|
||||
|
||||
}
|
||||
|
||||
int cvd_rgb_to_rgb(struct s_cvd_map *ptr_cvd_map, MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3])
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (ptr_cvd_map->mode != ECM_NONE)
|
||||
rc = cvd_rgb_to_rgb_dalton(ptr_cvd_map, rgb_inp, rgb_out);
|
||||
else
|
||||
mat_copy(rgb_inp, rgb_out, 3);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void cvd_model_rgb(struct s_color_space *ptr_color_space, MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3],
|
||||
enum cvd_type type)
|
||||
{
|
||||
static MATFLOAT cvd_mat_rgb2lms[3][3] = {
|
||||
{17.8824, 43.5161, 4.11935},
|
||||
{3.45565, 27.1554, 3.86714},
|
||||
{0.0299566, 0.184309, 1.46709}
|
||||
};
|
||||
static MATFLOAT cvd_mat_lms2rgb[3][3] = {
|
||||
{ 0.080944, -0.130504, 0.116721},
|
||||
{-0.0102485, 0.0540194, -0.113615},
|
||||
{-0.000365294, -0.00412163, 0.693513}
|
||||
};
|
||||
static MATFLOAT cvd_mat_model[ECVDT_NUM][3][3] = {
|
||||
{/* protanopia */ {0.0, 2.02324, -2.52581}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}},
|
||||
{/* deuteranopia */ {1.0, 0.0, 0.0}, {0.494207, 0.0, 1.24827}, {0.0, 0.0, 1.0}},
|
||||
// {/* tritanopia */ {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {-0.395913, 0.801109, 0.0}}
|
||||
{/* tritanopia */ {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {-0.012245, 0.0720345, 0.0}}
|
||||
};
|
||||
|
||||
MATFLOAT lms_inp[3], lms_out[3];
|
||||
|
||||
mat_eval_3x3(cvd_mat_rgb2lms, rgb_inp, lms_inp);
|
||||
mat_eval_3x3(cvd_mat_model[type], lms_inp, lms_out);
|
||||
mat_eval_3x3(cvd_mat_lms2rgb, lms_out, rgb_out);
|
||||
cs_clamp_rgb(rgb_out, 0.0, 1.0);
|
||||
}
|
||||
|
||||
int cvd_rgb_to_rgb_dalton(struct s_cvd_map *ptr_cvd_map, MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3])
|
||||
{
|
||||
static MATFLOAT cvd_mat_err[ECVDT_NUM][3][3] = {
|
||||
{/* protanopia */ {-0.5, 0.0, 0.0}, {1.0, 1.0, 0.0}, {1.0, 0.0, 1.0}},
|
||||
{/* deuteranopia */ { 1.0, 1.0, 0.0}, {0.0, -0.5, 0.0}, {0.0, 1.0, 1.0}},
|
||||
{/* tritanopia */ { 1.0, 0.0, 1.0}, {0.0, 1.0, 1.0}, {0.0, 0.0, -0.5}}
|
||||
};
|
||||
|
||||
MATFLOAT rgb_inp_lin[3], rgb_out_lin[3];
|
||||
MATFLOAT rgb_err_map[ECVDT_NUM][3];
|
||||
MATFLOAT err_map;
|
||||
MATFLOAT gain;
|
||||
int nc, nk;
|
||||
|
||||
cs_gamma_rgb(rgb_inp, rgb_inp_lin, ptr_cvd_map->color_space.gamma_parm, EGD_NONLIN_2_LIN);
|
||||
mat_copy(rgb_inp_lin, rgb_out_lin, 3);
|
||||
|
||||
for (nk = 0; nk < 3; nk++) {
|
||||
MATFLOAT rgb_cvd[3], rgb_err[3];
|
||||
|
||||
cvd_model_rgb(&ptr_cvd_map->color_space, rgb_inp_lin, rgb_cvd, nk);
|
||||
for (nc = 0; nc < 3; nc++)
|
||||
rgb_err[nc] = rgb_inp_lin[nc] - rgb_cvd[nc];
|
||||
mat_eval_3x3(cvd_mat_err[nk], rgb_err, rgb_err_map[nk]);
|
||||
}
|
||||
|
||||
if (ptr_cvd_map->mode == ECM_DALTON_SLD3) { /* ECM_DALTON_SLD3 */
|
||||
for (nk = 0; nk < 3; nk++) {
|
||||
gain = ptr_cvd_map->gain[nk] * 0.5;
|
||||
for (nc = 0; nc < 3; nc++)
|
||||
rgb_out_lin[nc] += rgb_err_map[nk][nc] * gain;
|
||||
}
|
||||
} else { /* ECM_DALTON_SLD1 */
|
||||
for (nc = 0; nc < 3; nc++) {
|
||||
if (ptr_cvd_map->gain[0] <= 1.0)
|
||||
err_map = ptr_cvd_map->gain[0] * rgb_err_map[0][nc];
|
||||
else if (ptr_cvd_map->gain[0] <= 2.0)
|
||||
err_map = rgb_err_map[0][nc] + (ptr_cvd_map->gain[0] - 1.0) * (rgb_err_map[1][nc] - rgb_err_map[0][nc]);
|
||||
else
|
||||
err_map = rgb_err_map[1][nc] + (ptr_cvd_map->gain[0] - 2.0) * (rgb_err_map[2][nc] - rgb_err_map[1][nc]);
|
||||
rgb_out_lin[nc] += err_map;
|
||||
}
|
||||
}
|
||||
|
||||
cs_clamp_rgb(rgb_out_lin, 0.0, 1.0);
|
||||
cs_gamma_rgb(rgb_out_lin, rgb_out, ptr_cvd_map->color_space.gamma_parm, EGD_LIN_2_NONLIN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
57
src/amd/gmlib/gm/cvd_funcs.h
Executable file
57
src/amd/gmlib/gm/cvd_funcs.h
Executable file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
* File Name : cvd_funcs.h
|
||||
* Purpose : Color Vision Deficiency functions
|
||||
* Author : Vladimir Lachine (vlachine@amd.com)
|
||||
* Date : January 21, 2020
|
||||
* Version : 1.0
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cs_funcs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum cvd_mode {
|
||||
ECM_NONE = 0, /* NONE */
|
||||
ECM_DALTON_SLD3 = 1, /* DALTONIZATION 3 control sliders */
|
||||
ECM_DALTON_SLD1 = 2, /* DALTONIZATION 1 control slider */
|
||||
ECM_NUM = 3
|
||||
};
|
||||
|
||||
enum cvd_type {
|
||||
ECVDT_PROTANOPIA = 0, /* protanopia */
|
||||
ECVDT_DEUTERANOPIA = 1, /* deuteranopia */
|
||||
ECVDT_TRITANOPIA = 2, /* tritanopia */
|
||||
ECVDT_NUM = 3
|
||||
};
|
||||
|
||||
struct s_cvd_map {
|
||||
/* input parameters */
|
||||
enum cvd_mode mode; /* Enable/disable CVD: {0,1,2}=0 */
|
||||
MATFLOAT gain[3]; /* Compensation Gain: ([0] - Protanopia, [1] - Deuteranopia, [2] - Tritanopia: [0.0,2.0]=0.0 */
|
||||
struct s_color_space color_space; /* Color Space (primary RGBW chromaticity, gamma, and Luminance min/max) */
|
||||
};
|
||||
|
||||
/* constructor and destructor */
|
||||
void cvd_ctor(struct s_cvd_map *ptr_cvd_map);
|
||||
void cvd_dtor(struct s_cvd_map *ptr_cvd_map);
|
||||
|
||||
void cvd_set_def(struct s_cvd_map *ptr_cvd_map);
|
||||
|
||||
int cvd_rgb_to_rgb(struct s_cvd_map *ptr_cvd_map, MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3]);
|
||||
void cvd_model_rgb(struct s_color_space *ptr_color_space, MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3],
|
||||
enum cvd_type type);
|
||||
int cvd_rgb_to_rgb_dalton(struct s_cvd_map *ptr_cvd_map, MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
194
src/amd/gmlib/gm/gm_api_funcs.c
Executable file
194
src/amd/gmlib/gm/gm_api_funcs.c
Executable file
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
* File Name : gm_api_funcs.c
|
||||
* Purpose : Gamut Mapping API functions
|
||||
* Author : Vladimir Lachine (vlachine@amd.com)
|
||||
* Date : November 12, 2024
|
||||
* Version : 3.1
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GM_SIM
|
||||
#pragma code_seg("PAGED3PC")
|
||||
#pragma data_seg("PAGED3PD")
|
||||
#pragma const_seg("PAGED3PR")
|
||||
#endif
|
||||
|
||||
#include "gm_api_funcs.h"
|
||||
|
||||
/* non library helper functions */
|
||||
/*
|
||||
// SESSION START
|
||||
struct s_gamut_map gamut_map;
|
||||
gm_ctor(&gamut_map, gm_api_alloc, gm_api_free); // constructor - once per session
|
||||
|
||||
struct s_gm_opts gm_opts;
|
||||
gm_api_set_def(&gm_opts); // set default mapping
|
||||
gm_api_gen_map(&gm_opts, &gamut_map); // generate default mapping
|
||||
|
||||
gm_opts.ptr_3dlut_rgb = (unsigned short *)gamut_map.ptr_func_alloc(
|
||||
3 * sizeof(unsigned short) * gm_opts.num_pnts_3dlut * gm_opts.num_pnts_3dlut * gm_opts.num_pnts_3dlut); // allocate 3DLUT memory
|
||||
|
||||
SOURCE OR TARGET GAMUT IS CHANGED EVENT
|
||||
{
|
||||
// ...................
|
||||
// set parameters of src gamut, dst gamut and gamut mapping
|
||||
// ...................
|
||||
gm_opts.update_msk = GM_UPDATE_SRC; // GM_UPDATE_SRC -
|
||||
update source gamut, GM_UPDATE_DST - update destination gamut or mapping parameters has been changed
|
||||
// or
|
||||
gm_opts.update_msk = GM_UPDATE_DST; // GM_UPDATE_SRC - u
|
||||
pdate source gamut, GM_UPDATE_DST - update destination gamut or mapping parameters has been changed
|
||||
|
||||
int rc = gm_api_gen_map(&gm_opts, &gamut_map);
|
||||
if (rc == 0) {
|
||||
rc = gm_api_gen_3dlut(&gm_opts, &gamut_map); // generate 3DLUT
|
||||
// .................
|
||||
// load 3DLUT to HW registers
|
||||
// .................
|
||||
}
|
||||
}
|
||||
|
||||
// SESSION END
|
||||
gamut_map.ptr_func_free(gm_opts.ptr_3dlut_rgb); // free 3DLUT memory
|
||||
gm_dtor(&gamut_map); // destructor - once per session
|
||||
*/
|
||||
|
||||
int gm_api_gen_map(struct s_gm_opts *ptr_gm_opts, struct s_gamut_map *ptr_gamut_map)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* initialize gamut mapping staructure from api gamut options */
|
||||
if (ptr_gm_opts->update_msk & GM_UPDATE_DST)
|
||||
gm_api_init(ptr_gm_opts, ptr_gamut_map);
|
||||
|
||||
/* init src and dst gamuts */
|
||||
rc = gm_init_gamuts(ptr_gamut_map, &ptr_gm_opts->cs_opts_src, &ptr_gm_opts->cs_opts_dst,
|
||||
ptr_gm_opts->mode, ptr_gm_opts->update_msk);
|
||||
|
||||
/* generate gamut edge and other internal data */
|
||||
if (rc == 0)
|
||||
gm_gen_map(ptr_gamut_map, ptr_gm_opts->update_msk);
|
||||
|
||||
ptr_gm_opts->update_msk = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int gm_api_gen_3dlut(struct s_gm_opts *ptr_gm_opts, struct s_gamut_map *ptr_gamut_map)
|
||||
{
|
||||
if (ptr_gm_opts->ptr_3dlut_rgb) {
|
||||
gm_gen_3dlut(ptr_gamut_map, ptr_gm_opts->num_pnts_3dlut,
|
||||
ptr_gm_opts->bitwidth_3dlut, ptr_gm_opts->en_merge_3dlut, ptr_gm_opts->ptr_3dlut_rgb);
|
||||
return 0;
|
||||
}
|
||||
return -1; /* something wrong */
|
||||
}
|
||||
|
||||
void gm_api_set_def(struct s_gm_opts *ptr_gm_opts)
|
||||
{
|
||||
int nk;
|
||||
|
||||
ptr_gm_opts->gamut_map_mode = EGMM_NONE;
|
||||
ptr_gm_opts->en_tm_scale_color = 1;
|
||||
ptr_gm_opts->hue_rot_mode = EHRM_NONE;
|
||||
ptr_gm_opts->mode = 0;
|
||||
ptr_gm_opts->step_samp = 0.0005;
|
||||
ptr_gm_opts->map_type = EMT_SEG;
|
||||
ptr_gm_opts->num_hue_pnts = 180;
|
||||
ptr_gm_opts->num_edge_pnts = 121;
|
||||
ptr_gm_opts->num_int_pnts = 33;
|
||||
ptr_gm_opts->org2_perc_c = GM_ORG2_PERC;
|
||||
|
||||
for (nk = 0; nk < GM_NUM_PRIM; nk++) {
|
||||
ptr_gm_opts->vec_org1_factor[nk] = gm_vec_org13_factor_def[nk][0];
|
||||
ptr_gm_opts->vec_org3_factor[nk] = gm_vec_org13_factor_def[nk][1];
|
||||
}
|
||||
|
||||
ptr_gm_opts->reserve = 0;
|
||||
ptr_gm_opts->show_pix_mode = ESPM_NONE;
|
||||
|
||||
for (nk = 0; nk < 2; nk++)
|
||||
ptr_gm_opts->show_pix_hue_limits[nk] = 0.0;
|
||||
|
||||
cs_set_opts_def(&ptr_gm_opts->cs_opts_src);
|
||||
cs_set_opts_def(&ptr_gm_opts->cs_opts_dst);
|
||||
|
||||
ptr_gm_opts->update_msk = GM_UPDATE_SRC | GM_UPDATE_DST;
|
||||
|
||||
ptr_gm_opts->en_merge_3dlut = 0;
|
||||
ptr_gm_opts->num_pnts_3dlut = 17;
|
||||
ptr_gm_opts->bitwidth_3dlut = 12;
|
||||
}
|
||||
|
||||
void gm_api_init(struct s_gm_opts *ptr_gm_opts, struct s_gamut_map *ptr_gamut_map)
|
||||
{
|
||||
int nk;
|
||||
|
||||
gm_set_def(ptr_gamut_map);
|
||||
|
||||
ptr_gamut_map->gamut_map_mode = ptr_gm_opts->gamut_map_mode;
|
||||
ptr_gamut_map->en_tm_scale_color = ptr_gm_opts->en_tm_scale_color;
|
||||
ptr_gamut_map->hue_rot_mode = ptr_gm_opts->hue_rot_mode;
|
||||
ptr_gamut_map->mode = ptr_gm_opts->mode;
|
||||
ptr_gamut_map->org2_perc_c = ptr_gm_opts->org2_perc_c;
|
||||
|
||||
for (nk = 0; nk < GM_NUM_PRIM; nk++) {
|
||||
/* Factor of Origin1 for M,R,Y,G,C,B = 1.3, 1.3, 1.3, 1.3, 1.2, 1.0 */
|
||||
ptr_gamut_map->vec_org1_factor[nk] = ptr_gm_opts->vec_org1_factor[nk];
|
||||
/* Factor of Origin3 for M,R,Y,G,C,B = 1.05, 1.1, 1.1, 1.05, 1.01, 1.06 */
|
||||
ptr_gamut_map->vec_org3_factor[nk] = ptr_gm_opts->vec_org3_factor[nk];
|
||||
}
|
||||
|
||||
ptr_gamut_map->step_samp = ptr_gm_opts->step_samp; /* default is 0.0005 */
|
||||
ptr_gamut_map->map_type = ptr_gm_opts->map_type; /* default is EMT_SEG */
|
||||
ptr_gamut_map->num_hue_pnts = ptr_gm_opts->num_hue_pnts; /* default is 181 */
|
||||
ptr_gamut_map->num_edge_pnts = ptr_gm_opts->num_edge_pnts; /* default is 121 */
|
||||
ptr_gamut_map->num_int_pnts = ptr_gm_opts->num_int_pnts; /* default is 33 */
|
||||
|
||||
ptr_gamut_map->reserve = ptr_gm_opts->reserve;
|
||||
ptr_gamut_map->show_pix_mode = ptr_gm_opts->show_pix_mode;
|
||||
|
||||
for (nk = 0; nk < 2; nk++)
|
||||
ptr_gamut_map->show_pix_hue_limits[nk] = ptr_gm_opts->show_pix_hue_limits[nk];
|
||||
}
|
||||
|
||||
#ifndef GM_SIM
|
||||
#ifndef LINUX_DM
|
||||
#include "dm_services.h"
|
||||
#else
|
||||
/* TBD: include for LINUX_DM */
|
||||
#endif /* LINUX_DM */
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#endif /* GM_SIM */
|
||||
|
||||
void *gm_api_alloc(unsigned int size_bytes, void* mem_ctx)
|
||||
{
|
||||
#ifndef GM_SIM
|
||||
#ifndef LINUX_DM
|
||||
return dm_alloc(size_bytes);
|
||||
#else
|
||||
/* TBD: alloc() for LINUX_DM */
|
||||
#endif /* LINUX_DM */
|
||||
#else
|
||||
return malloc(size_bytes);
|
||||
#endif /* GM_SIM */
|
||||
}
|
||||
|
||||
void gm_api_free(void *ptr_mem, void* mem_ctx)
|
||||
{
|
||||
#ifndef GM_SIM
|
||||
#ifndef LINUX_DM
|
||||
dm_free(ptr_mem);
|
||||
#else
|
||||
/* TBD: free() for LINUX_DM */
|
||||
#endif /* LINUX_DM */
|
||||
#else
|
||||
free(ptr_mem);
|
||||
#endif /* GM_SIM */
|
||||
}
|
||||
79
src/amd/gmlib/gm/gm_api_funcs.h
Executable file
79
src/amd/gmlib/gm/gm_api_funcs.h
Executable file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
* File Name : gm_api_funcs.h
|
||||
* Purpose : Gamut Mapping API functions
|
||||
* Author : Vladimir Lachine (vlachine@amd.com)
|
||||
* Date : November 12, 2024
|
||||
* Version : 3.1
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gm_funcs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct s_gm_opts {
|
||||
enum gm_gamut_map_mode gamut_map_mode;
|
||||
/* Gamut Map Mode: 0 - no gamut map, 1 - Tone Map BT2390-4, 2 - TM+CHTO, 3 - TM+CHSO, 4 - TM+CHCI */
|
||||
enum gm_hue_rot_mode hue_rot_mode;
|
||||
/* Hue Rotation Mode: 0 - none, 1 - hue rotation, 2 - chroma compression, 3 - hue rotation and chroma compression */
|
||||
int en_tm_scale_color;
|
||||
/* Enable/Disable Color Scaling (valid for Tone Mapping mode only): {0,1} = 1 */
|
||||
unsigned int mode;
|
||||
/* mode = 0 : Reserved for modifications of the Gamut Map algo */
|
||||
/* CHTO tuning parameters */
|
||||
MATFLOAT org2_perc_c;
|
||||
/* Origin2 percentage gap for chroma [0.7,095] = 0.9 */
|
||||
MATFLOAT vec_org1_factor[GM_NUM_PRIM];
|
||||
/* Factor of Origin1 for M,R,Y,G,C,B [1.0,1.4] = 1.3, 1.3, 1.3, 1.3, 1.2, 1.0 */
|
||||
MATFLOAT vec_org3_factor[GM_NUM_PRIM];
|
||||
/* Factor of Origin3 for M,R,Y,G,C,B [1.01,1,2] = 1.05, 1.2, 1.05, 1.05, 1.01, 1.05 */
|
||||
MATFLOAT step_samp;
|
||||
/* Sampling precision in IC space for edge search [0.00001,0.001]=0.0001 */
|
||||
enum gm_map_type map_type;
|
||||
/* Map type: {0,1,2} = 0 : 0 - segments intersection SEG, 1 - radius sampling RAD, 2 hybrid - SEG+RAD */
|
||||
int num_hue_pnts;
|
||||
/* Number of hue grid points: [90,360]=360 */
|
||||
int num_edge_pnts;
|
||||
/* Number of edge IC grid points: [91, 181] = 181 */
|
||||
int num_int_pnts;
|
||||
/* Number of intensity grid points for primary hues: [5,33] = 33 */
|
||||
/* show pixel parameters */
|
||||
int reserve;
|
||||
/* Reserved for debugging purpose = 0 */
|
||||
enum gm_show_pix_mode show_pix_mode;
|
||||
/* EShowPixMode: [0,8]=0 : show pixel debugging mode */
|
||||
MATFLOAT show_pix_hue_limits[2];
|
||||
/* Show Pixel mode hue ranges */
|
||||
/* color space parameters */
|
||||
struct s_cs_opts cs_opts_src;
|
||||
struct s_cs_opts cs_opts_dst;
|
||||
int update_msk;
|
||||
/* Update mask: GM_UPDATE_SRC - update source gamut, GM_UPDATE_DST - update destination gamut */
|
||||
/* 3DLUT parameters */
|
||||
int en_merge_3dlut;
|
||||
int num_pnts_3dlut;
|
||||
int bitwidth_3dlut;
|
||||
unsigned short *ptr_3dlut_rgb;
|
||||
};
|
||||
|
||||
int gm_api_gen_map(struct s_gm_opts *ptr_gm_opts, struct s_gamut_map *ptr_gamut_map);
|
||||
int gm_api_gen_3dlut(struct s_gm_opts *ptr_gm_opts, struct s_gamut_map *ptr_gamut_map);
|
||||
|
||||
void gm_api_set_def(struct s_gm_opts *ptr_gm_opts);
|
||||
void gm_api_init(struct s_gm_opts *ptr_gm_opts, struct s_gamut_map *ptr_gamut_map);
|
||||
|
||||
void *gm_api_alloc(unsigned int size_bytes, void* mem_ctx); /* alloc array */
|
||||
void gm_api_free(void *ptr_mem, void* mem_ctx); /* free array */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
1492
src/amd/gmlib/gm/gm_funcs.c
Executable file
1492
src/amd/gmlib/gm/gm_funcs.c
Executable file
File diff suppressed because it is too large
Load diff
299
src/amd/gmlib/gm/gm_funcs.h
Executable file
299
src/amd/gmlib/gm/gm_funcs.h
Executable file
|
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
* File Name : gm_funcs.h
|
||||
* Purpose : Gamut Mapping functions
|
||||
* Author : Vladimir Lachine (vlachine@amd.com)
|
||||
* Date : November 11, 2024
|
||||
* Version : 3.1
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mat_funcs.h"
|
||||
#include "cs_funcs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GM_NUM_PRIM 6 /* number of primary/secondary colors */
|
||||
#define GM_NUM_HUE 360 /* default number of hue slices in edge description grid */
|
||||
#define GM_NUM_EDGE 181 /* default number of egde points per hue in edge description grid */
|
||||
#define GM_NUM_INT 33 /* default number of intensity levels in HueRot grid */
|
||||
#define GM_STEP_SAMP 0.0001 /* default accuracy of edge detection procedures (for 14 bits signal) */
|
||||
#define GM_EDGE_ORG 0.5 /* default center point for edge description procedure */
|
||||
#define GM_ORG1_FACTOR 0.5 /* Origin1 default intensity */
|
||||
#define GM_ORG3_FACTOR 1.0 /* Origin3 default intensity */
|
||||
#define GM_ORG2_PERC 0.9
|
||||
|
||||
#define GM_CUSP_ADJUST 0x01 /* Adjust cusp points */
|
||||
#define GM_ZONE1_FLEX 0x02 /* Flexible zone 1 */
|
||||
#define GM_PQTAB_3DLUT 0x04
|
||||
#define GM_PQTAB_GBD 0x08
|
||||
#define GM_SCALE_LUMA 0x04 /* Luma scaling */
|
||||
|
||||
#define GM_UPDATE_SRC 0x01
|
||||
#define GM_UPDATE_DST 0x02
|
||||
|
||||
#define GM_HUE_SHIFT 0x01
|
||||
#define GM_CHROMA_GAIN 0x02
|
||||
|
||||
#define GM_PQTAB_NUMPNTS 4097
|
||||
|
||||
enum gm_gamut_map_mode {
|
||||
EGMM_NONE = 0, /* NONE */
|
||||
EGMM_TM = 1, /* Tone Map (BT2390-4) */
|
||||
EGMM_TM_CHTO = 2, /* Tone Map + CHTO (Constant Hue Triple Origin */
|
||||
EGMM_TM_CHSO = 3, /* Tone Map + CHSO (Constant Hue Single Origin */
|
||||
EGMM_TM_CHCI = 4 /* Tone Map + CHCI (Constant Hue Constant Intensity) */
|
||||
};
|
||||
|
||||
enum gm_hue_rot_mode {
|
||||
EHRM_NONE = 0, /* NONE */
|
||||
EHRM_HR = 1, /* Hue rotation */
|
||||
EHRM_CC = 2, /* Chroma compression */
|
||||
EHRM_HR_CC = 3 /* Hue rotation + Chroma compression */
|
||||
};
|
||||
|
||||
enum gm_map_type {
|
||||
EMT_SEG = 0, /* intensity segment */
|
||||
EMT_RAD = 1, /* arc segment */
|
||||
EMT_SEGRAD = 2 /* hybrid */
|
||||
};
|
||||
|
||||
enum gm_edge_type {
|
||||
EET_RAD = 0, /* elevation angle uniform */
|
||||
EET_CHROMA = 1 /* intensity uniform */
|
||||
};
|
||||
|
||||
enum gm_show_pix_mode {
|
||||
ESPM_NONE = 0, /* NONE */
|
||||
ESPM_NOMAP = 1, /* Show pixels inside gamut */
|
||||
ESPM_MAP = 2, /* Show pixels outside gamut */
|
||||
ESPM_MAPZ1 = 3, /* Show pixels outside gamut in zone1 */
|
||||
ESPM_MAPZ2 = 4, /* Show pixels outside gamut in zone2 */
|
||||
ESPM_MAPZ3 = 5, /* Show pixels outside gamut in zone3 */
|
||||
ESPM_NUMZ = 6, /* Show pixels zone number */
|
||||
ESPM_HUEINP = 7, /* Show input pixels with hue in range */
|
||||
ESPM_HUEOUT = 8 /* Show output pixels with hue in range */
|
||||
};
|
||||
|
||||
struct s_gamut_map {
|
||||
/* input parameters */
|
||||
enum gm_gamut_map_mode gamut_map_mode;
|
||||
/* Gamut Map Mode: 0 - no gamut map, 1 - Tone Map BT2390-4, 2 - TM+CHTO, 3 - TM+CHSO, 4 - TM+CHCI */
|
||||
enum gm_hue_rot_mode hue_rot_mode;
|
||||
/* Hue Rotation Mode: 0 - none, 1 - hue rotation, 2 - chroma compression, 3 - hue rotation and chroma compression */
|
||||
int en_tm_scale_color;
|
||||
/* Enable/Disable Color Scaling in Tone Mapping mode only: {0,1} = 1 */
|
||||
unsigned int mode;
|
||||
/* Reserved for modifications of the Gamut Map algo */
|
||||
struct s_color_space color_space_src;
|
||||
/* Source color space (primary RGBW chromaticity, gamma, and Luminance min/max) */
|
||||
struct s_color_space color_space_dst;
|
||||
/* Destination color space (primary RGBW chromaticity, gamma and Luminance min/max) */
|
||||
/* CHTO input tuning parameters */
|
||||
MATFLOAT org2_perc_c;
|
||||
/* Origin2 percentage gap for chroma [0.0,1.0] = 0.9 */
|
||||
MATFLOAT vec_org1_factor[GM_NUM_PRIM];
|
||||
/* Factor of Origin1 for M,R,Y,G,C,B [0.0,2.0] = 1.3, 1.3, 1.3, 1.3, 1.2, 1.0 */
|
||||
MATFLOAT vec_org3_factor[GM_NUM_PRIM];
|
||||
/* Factor of Origin3 for M,R,Y,G,C,B [1.0,1.5] = 1.05, 1.2, 1.05, 1.05, 1.01, 1.05 */
|
||||
/* GM input tuning parameters */
|
||||
int num_hue_pnts;
|
||||
/* Number of hue grid points: [90,360]=360 */
|
||||
int num_edge_pnts;
|
||||
/* Number of edge IC grid points: [91, 181] = 181 */
|
||||
int num_int_pnts;
|
||||
/* Number of intensity grid points for primary hues: [5,33] = 33 */
|
||||
enum gm_edge_type edge_type;/* Edge type: {0,1} = 0 : 0 - radius based EET_RAD, 1 - chroma based EET_CHROMA */
|
||||
enum gm_map_type map_type;
|
||||
/* Map type: {0,1,2} = 0 : 0 - segments intersection SEG, 1 - radius sampling RAD, 2 hybrid - SEG+RAD */
|
||||
MATFLOAT step_samp;
|
||||
/* Sampling precision in IC space for edge search [0.00001,0.001]=0.0001 */
|
||||
int reserve;
|
||||
/* Reserved for debugging purpose */
|
||||
enum gm_show_pix_mode show_pix_mode;
|
||||
/* SHow Pix Mode: [0,8]=0 : show pixel debugging mode */
|
||||
MATFLOAT show_pix_hue_limits[2]; /* Show Pixel mode hue ranges */
|
||||
/* calculated variables */
|
||||
MATFLOAT lum_min;
|
||||
/* minLum (BT2390-4) in PQ non-linear space */
|
||||
MATFLOAT lum_max;
|
||||
/* maxLum (BT2390-4) in PQ non-linear space */
|
||||
MATFLOAT vec_prim_src_ich[3 * GM_NUM_PRIM];
|
||||
/* ich for M,R,Y,G,C,B primaries of source gamut */
|
||||
MATFLOAT vec_prim_dst_ich[3 * GM_NUM_PRIM];
|
||||
/* ich for M,R,Y,G,C,B primaries of target gamut */
|
||||
MATFLOAT *ptr_cusp_src_ic;
|
||||
/* Intensity and chroma of Cusp num_hue_pnts points for source gamut */
|
||||
MATFLOAT *ptr_cusp_dst_ic;
|
||||
/* Intensity and chroma of Cusp num_hue_pnts points for target gamut */
|
||||
MATFLOAT *ptr_org2_ic;
|
||||
/* Intensity and chroma of Origin2 for num_hue_pnts points */
|
||||
MATFLOAT *ptr_org3_ic;
|
||||
/* Intensity and chroma of Origin3 for num_hue_pnts points */
|
||||
MATFLOAT *ptr_hr_src_hc;
|
||||
/* Source Primary Hue and Chroma for (GM_NUM_PRIM * num_int_pnts) points */
|
||||
MATFLOAT *ptr_hr_dst_hc;
|
||||
/* Target Primary Hue and Chroma for (GM_NUM_PRIM * num_int_pnts) points */
|
||||
MATFLOAT *ptr_edge_ic;
|
||||
/* Target gamut edge for (num_hue_pnts * num_edge_pnts) points */
|
||||
void *(*ptr_func_alloc)(unsigned int, void*);
|
||||
/* allocate memory function */
|
||||
void (*ptr_func_free)(void*, void*);
|
||||
/* deallocate memory function */
|
||||
void* memory_context;
|
||||
/*memory management context*/
|
||||
MATFLOAT hue_max;
|
||||
MATFLOAT org1;
|
||||
MATFLOAT org3;
|
||||
/* internally calculated constant */
|
||||
};
|
||||
|
||||
void gm_ctor(struct s_gamut_map *ptr_gamut_map,
|
||||
void*(*ptr_func_alloc)(unsigned int, void*),
|
||||
void(*ptr_func_free)(void*, void*),
|
||||
void* mem_context); /* constructor */
|
||||
void gm_dtor(struct s_gamut_map *ptr_gamut_map); /* destructor */
|
||||
void gm_alloc_mem(struct s_gamut_map *ptr_gamut_map);
|
||||
void gm_free_mem(struct s_gamut_map *ptr_gamut_map);
|
||||
|
||||
/* initialization functions */
|
||||
void gm_set_def(struct s_gamut_map *gamut_map);
|
||||
int gm_init_gamuts(struct s_gamut_map *ptr_gamut_map, struct s_cs_opts *ptr_cs_opts_src,
|
||||
struct s_cs_opts *ptr_cs_opts_dst, unsigned int gm_mode, int update_msk);
|
||||
int gm_check_gamut(struct s_gamut_map *ptr_gamut_map);
|
||||
void gm_gencusp_ic(struct s_gamut_map *ptr_gamut_map, int color_space); /* color_space : 0 - source, 1 - target */
|
||||
|
||||
/* gamut map description generation functions */
|
||||
void gm_gen_edge_hue(struct s_gamut_map* ptr_gamut_map, int hue_ind);
|
||||
|
||||
/* resampling functions */
|
||||
void gm_resample_hc(MATFLOAT vec_ich_inp[][3], MATFLOAT *ptr_hc_out,
|
||||
int num_int_pnts_src, int num_int_pnts_dst);
|
||||
void gm_resample_hue_ic(MATFLOAT *ptr_hue, MATFLOAT *ptr_ic_inp,
|
||||
MATFLOAT *ptr_ic_out, int num_hue_pnts_inp, int num_hue_pnts_out);
|
||||
void gm_genprim_hc(struct s_color_space *ptr_color_space, MATFLOAT *ptr_hr_hc,
|
||||
int num_int_pnts, MATFLOAT luma_limits[3], MATFLOAT lum_min, MATFLOAT lum_max);
|
||||
|
||||
/* Origin2 and Origin3 generation functions */
|
||||
void gm_genorg13_factor(struct s_gamut_map* ptr_gamut_map, MATFLOAT* ptr_org13_factor);
|
||||
void gm_genorigin23_hue(struct s_gamut_map* ptr_gamut_map, MATFLOAT* ptr_org13_factor, int hue_ind);
|
||||
void gm_getorigin23(struct s_color_space* ptr_color_space_src, struct s_color_space* ptr_color_space_dst,
|
||||
MATFLOAT hue, MATFLOAT org_13_factor[2], MATFLOAT org2_perc_c,MATFLOAT cusp_ic_src[2],
|
||||
MATFLOAT cusp_ic_dst[2], MATFLOAT origin2_ic[2], MATFLOAT origin3_ic[2], int en_pq_lut);
|
||||
|
||||
/* gamut map functions */
|
||||
int gm_rgb_to_rgb(struct s_gamut_map *ptr_gamut_map, MATFLOAT rgb_inp[3], MATFLOAT rgb_out[3]);
|
||||
MATFLOAT gm_tm_itp(MATFLOAT itp_inp[3], MATFLOAT itp_out[3], MATFLOAT luma_limits[3],
|
||||
MATFLOAT lum_min, MATFLOAT lum_max, int en_tm_scale_color, int en_tm_scale_luma);
|
||||
MATFLOAT gm_tm_luma(MATFLOAT luma, MATFLOAT luma_limits[3], MATFLOAT lum_min, MATFLOAT lum_max);
|
||||
MATFLOAT gm_scale_luma(MATFLOAT luma, MATFLOAT luma_limits[3], MATFLOAT lum_min, MATFLOAT lum_max);
|
||||
int gm_map_itp(struct s_gamut_map *ptr_gamut_map, MATFLOAT itp_inp[3], MATFLOAT itp_out[3]);
|
||||
int gm_map_chto_itp(struct s_gamut_map *ptr_gamut_map, MATFLOAT itp_inp[3], MATFLOAT itp_out[3]);
|
||||
int gm_map_chso_itp(struct s_gamut_map *ptr_gamut_map, MATFLOAT itp_inp[3], MATFLOAT itp_out[3]);
|
||||
int gm_map_chci_itp(struct s_gamut_map *ptr_gamut_map, MATFLOAT itp_inp[3], MATFLOAT itp_out[3]);
|
||||
|
||||
/* hue rotation functions */
|
||||
void gm_hr_itp(struct s_gamut_map *gamut_map, MATFLOAT itp_inp[3], MATFLOAT itp_out[3], int direction);
|
||||
void gm_hr_ich(struct s_gamut_map *ptr_gamut_map, MATFLOAT ich_inp[3], MATFLOAT ich_out[3], int direction);
|
||||
void gm_get_hr_parms(MATFLOAT ich[3], MATFLOAT luma_limits[3], MATFLOAT *ptr_hr_src_hc,
|
||||
MATFLOAT *ptr_hr_dst_hc, int num_int_pnts, MATFLOAT rot_hs_cg[2]);
|
||||
|
||||
/* segments intersection functions */
|
||||
int gm_map_seg_itp(struct s_gamut_map *ptr_gamut_map, MATFLOAT itp_inp[3],
|
||||
MATFLOAT itp_out[3], int zone, MATFLOAT origin2_ic[2], MATFLOAT origin3_ic[2], int vec_hue_ind[2], MATFLOAT hue_phs);
|
||||
int gm_map_rad_itp(struct s_gamut_map *ptr_gamut_map, MATFLOAT itp_inp[3],
|
||||
MATFLOAT itp_out[3], int zone, MATFLOAT origin2_ic[2], MATFLOAT origin3_ic[2], MATFLOAT hue);
|
||||
int gm_map_segrad_itp(struct s_gamut_map *ptr_gamut_map, MATFLOAT itp_inp[3],
|
||||
MATFLOAT itp_out[3], int zone, MATFLOAT origin2_ic[2],
|
||||
MATFLOAT origin3_ic[2], MATFLOAT hue, int vec_hue_ind[2], MATFLOAT hue_phs);
|
||||
|
||||
/* interpolate Ic between two hues */
|
||||
MATFLOAT gm_hue_to_index_phase(MATFLOAT hue, MATFLOAT hue_max, int num_hue_pnts, int vec_hue_ind[2]);
|
||||
void gm_interp_ic(int vec_hue_ind[2], MATFLOAT hue_phs,
|
||||
MATFLOAT vec_pnt_ic[], MATFLOAT pnt_ic[2]);
|
||||
void gm_getseg_ic(int vec_hue_ind[2], MATFLOAT hue_phs,
|
||||
int ind, int num_edge_pnts, MATFLOAT *ptr_edge_ic, MATFLOAT pnt_ic[2]);
|
||||
|
||||
/* Edge generation functions */
|
||||
void gm_genedge(struct s_color_space *ptr_color_space, MATFLOAT luma_limits[3],
|
||||
int num_edge_pnts, enum gm_edge_type edge_type, MATFLOAT step_samp, MATFLOAT hue,
|
||||
MATFLOAT *ptr_edge_ic, int en_pq_lut);
|
||||
void gm_genedge_int(struct s_color_space *ptr_color_space, MATFLOAT luma_limits[3],
|
||||
int num_edge_pnts, MATFLOAT hue, MATFLOAT step_samp, MATFLOAT *ptr_edge_ic,
|
||||
int en_pq_lut);
|
||||
void gm_genedge_rad(struct s_color_space *ptr_color_space, MATFLOAT luma_limits[3],
|
||||
int num_edge_pnts, MATFLOAT hue, MATFLOAT step_samp, MATFLOAT *ptr_edge_ic,
|
||||
int en_pq_lut);
|
||||
void gm_sample_edge_ic(struct s_color_space *ptr_color_space,
|
||||
MATFLOAT hue_cos_sin[2], MATFLOAT inc_ic[2], MATFLOAT pnt_ic[2],
|
||||
int en_pq_lut);
|
||||
void gm_edgecusp_adjust(MATFLOAT *ptr_edge_ic, int num_edge_pnts, MATFLOAT cusp_ic[2]);
|
||||
|
||||
/* Gamut Map related functions */
|
||||
int gm_get_zone(MATFLOAT itp[3], MATFLOAT origin2_ic[2], MATFLOAT origin3_ic[2], MATFLOAT luma_limits[3]);
|
||||
int gm_map_zone1_seg(MATFLOAT itp_inp[3], MATFLOAT itp_out[3], int vec_hue_ind[2],
|
||||
MATFLOAT hue_phs, MATFLOAT origin2_ic[2], int num_edge_pnts, MATFLOAT *ptr_edge_ic, int pnt_map, int pnt_inc);
|
||||
int gm_map_zone2_seg(MATFLOAT itp_inp[3], MATFLOAT itp_out[3], int vec_hue_ind[2],
|
||||
MATFLOAT hue_phs, MATFLOAT origin2_ic[2], int num_edge_pnts, MATFLOAT *ptr_edge_ic, int pnt_map, int pnt_inc);
|
||||
int gm_map_zone3_seg(MATFLOAT itp_inp[3], MATFLOAT itp_out[3], int vec_hue_ind[2],
|
||||
MATFLOAT hue_phs, MATFLOAT origin3_ic[2], int num_edge_pnts, MATFLOAT *ptr_edge_ic, int pnt_map, int pnt_inc);
|
||||
void gm_map_zone1_rad(struct s_color_space *ptr_color_space, MATFLOAT itp_inp[3],
|
||||
MATFLOAT itp_out[3], MATFLOAT step_samp, MATFLOAT origin2_ic[2], MATFLOAT hue, int num_itr);
|
||||
void gm_map_zone2_rad(struct s_color_space *ptr_color_space, MATFLOAT itp_inp[3],
|
||||
MATFLOAT itp_out[3], MATFLOAT step_samp, MATFLOAT origin2_ic[2], MATFLOAT hue, int num_itr);
|
||||
void gm_map_zone3_rad(struct s_color_space *ptr_color_space, MATFLOAT itp_inp[3],
|
||||
MATFLOAT itp_out[3], MATFLOAT step_samp, MATFLOAT origin3_ic[2], MATFLOAT hue, int num_itr);
|
||||
|
||||
/* Show Pixel debugging functions */
|
||||
void gm_show_pix(int zone, MATFLOAT itp_src[3], MATFLOAT itp_dst[3],
|
||||
MATFLOAT rgb[3], enum gm_show_pix_mode show_pix_mode, MATFLOAT hue_limits[2]);
|
||||
|
||||
void gm_rgb_to_itp(struct s_color_space* ptr_color_space, MATFLOAT rgb_inp[3], MATFLOAT itp_out[3], int en_pq_lut);
|
||||
void gm_itp_to_rgb(struct s_color_space* ptr_color_space, MATFLOAT itp_inp[3], MATFLOAT rgb_out[3], int en_pq_lut);
|
||||
|
||||
int gm_is_valid_itp(struct s_color_space* ptr_color_space, MATFLOAT itp[3], int en_pq_lut);
|
||||
int gm_is_valid_ic(struct s_color_space* ptr_color_space, MATFLOAT pnt_ic[2], MATFLOAT hue_sin_cos[2], int en_pq_lut);
|
||||
|
||||
void gm_gen_pq_lut(float* ptr_lut, int num_pnts, enum cs_gamma_dir gamma_dir);
|
||||
MATFLOAT gm_pq_lut(MATFLOAT val, enum cs_gamma_dir gamma_dir);
|
||||
int gm_seg_intersection(MATFLOAT p0_xy[2], MATFLOAT p1_xy[2], MATFLOAT s1_xy[2],
|
||||
MATFLOAT p2_xy[2], MATFLOAT p3_xy[2], MATFLOAT p_xy[2]);
|
||||
|
||||
|
||||
/* MULTI-THREADING */
|
||||
/* for multi-threading implementation the following function must be overwritten */
|
||||
void gm_gen_map(struct s_gamut_map* ptr_gamut_map, int update_msk);
|
||||
void gm_gen_3dlut(struct s_gamut_map* ptr_gamut_map, int num_pnts,
|
||||
int bitwidth, int en_merge, unsigned short* ptr_3dlut_rgb);
|
||||
/* end MULTI-THREADING */
|
||||
|
||||
/* global constants */
|
||||
static const MATFLOAT gm_vec_org13_factor_def[GM_NUM_PRIM][2] = {
|
||||
{1.3, 1.05}, /* M */
|
||||
{1.3, 1.10}, /* R */
|
||||
{1.3, 1.10}, /* Y */
|
||||
{1.3, 1.05}, /* G */
|
||||
{1.2, 1.01}, /* C */
|
||||
{1.0, 1.06} /* B */
|
||||
};
|
||||
|
||||
static const MATFLOAT gm_vec_cusp_rgb[GM_NUM_PRIM][3] = {
|
||||
{1.0, 0.0, 1.0}, /* M */
|
||||
{1.0, 0.0, 0.0}, /* R */
|
||||
{1.0, 1.0, 0.0}, /* Y */
|
||||
{0.0, 1.0, 0.0}, /* G */
|
||||
{0.0, 1.0, 1.0}, /* C */
|
||||
{0.0, 0.0, 1.0} /* B */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
918
src/amd/gmlib/gm/mat_funcs.c
Executable file
918
src/amd/gmlib/gm/mat_funcs.c
Executable file
|
|
@ -0,0 +1,918 @@
|
|||
/*
|
||||
* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
* File Name : mat_funcs.c
|
||||
* Purpose : Mathematical functions
|
||||
* Author : Vladimir Lachine (vlachine@amd.com)
|
||||
* Date : September 20, 2023
|
||||
* Version : 1.2
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef GM_SIM
|
||||
#pragma code_seg("PAGED3PC")
|
||||
#pragma data_seg("PAGED3PD")
|
||||
#pragma const_seg("PAGED3PR")
|
||||
#endif
|
||||
|
||||
#include "mat_funcs.h"
|
||||
#include <math.h>
|
||||
|
||||
float mat_fast_log(float x);
|
||||
|
||||
void mat_eval_3x3(MATFLOAT mat[3][3], MATFLOAT vec_inp[3], MATFLOAT vec_out[3])
|
||||
{
|
||||
int ni, nj;
|
||||
|
||||
mat_3x1_zero(vec_out);
|
||||
for (ni = 0; ni < 3; ni++)
|
||||
for (nj = 0; nj < 3; nj++)
|
||||
vec_out[ni] += mat[ni][nj] * vec_inp[nj];
|
||||
}
|
||||
|
||||
void mat_eval_3x3_off(MATFLOAT mat[3][3], MATFLOAT vec_off[3], MATFLOAT vec_inp[3], MATFLOAT vec_out[3])
|
||||
{
|
||||
int nc;
|
||||
|
||||
mat_eval_3x3(mat, vec_inp, vec_out);
|
||||
for (nc = 0; nc < 3; nc++)
|
||||
vec_out[nc] += vec_off[nc];
|
||||
}
|
||||
|
||||
void mat_eval_off_3x3_off(MATFLOAT vec_off_inp[3], MATFLOAT mat[3][3],
|
||||
MATFLOAT vec_off_out[3], MATFLOAT vec_inp[3], MATFLOAT vec_out[3])
|
||||
{
|
||||
MATFLOAT val_tmp[3];
|
||||
int nc;
|
||||
|
||||
for (nc = 0; nc < 3; nc++)
|
||||
val_tmp[nc] = vec_inp[nc] + vec_off_inp[nc];
|
||||
mat_eval_3x3(mat, val_tmp, vec_out);
|
||||
for (nc = 0; nc < 3; nc++)
|
||||
vec_out[nc] += vec_off_out[nc];
|
||||
}
|
||||
|
||||
void mat_mul3x3(MATFLOAT mat2[3][3], MATFLOAT mat1[3][3], MATFLOAT mat2x1[3][3])
|
||||
{
|
||||
int ni, nj, nk;
|
||||
|
||||
mat_3x3_zero(mat2x1);
|
||||
for (ni = 0; ni < 3; ni++)
|
||||
for (nj = 0; nj < 3; nj++)
|
||||
for (nk = 0; nk < 3; nk++)
|
||||
mat2x1[ni][nj] += mat2[ni][nk] * mat1[nk][nj];
|
||||
}
|
||||
|
||||
int mat_inv3x3(MATFLOAT mat_inp[3][3], MATFLOAT mat_out[3][3])
|
||||
{
|
||||
/*
|
||||
* Calculate the determinant of matrix A and determine if the
|
||||
* the matrix is singular as limited by the MATFLOAT precision
|
||||
* MATFLOATing-point data representation.
|
||||
*/
|
||||
MATFLOAT det = 0.0;
|
||||
MATFLOAT pos = 0.0;
|
||||
MATFLOAT neg = 0.0;
|
||||
MATFLOAT temp;
|
||||
|
||||
temp = mat_inp[0][0] * mat_inp[1][1] * mat_inp[2][2];
|
||||
if (temp >= 0.0)
|
||||
pos += temp;
|
||||
else
|
||||
neg += temp;
|
||||
temp = mat_inp[0][1] * mat_inp[1][2] * mat_inp[2][0];
|
||||
if (temp >= 0.0)
|
||||
pos += temp;
|
||||
else
|
||||
neg += temp;
|
||||
temp = mat_inp[0][2] * mat_inp[1][0] * mat_inp[2][1];
|
||||
if (temp >= 0.0)
|
||||
pos += temp;
|
||||
else
|
||||
neg += temp;
|
||||
temp = -mat_inp[0][2] * mat_inp[1][1] * mat_inp[2][0];
|
||||
if (temp >= 0.0)
|
||||
pos += temp;
|
||||
else
|
||||
neg += temp;
|
||||
temp = -mat_inp[0][1] * mat_inp[1][0] * mat_inp[2][2];
|
||||
if (temp >= 0.0)
|
||||
pos += temp;
|
||||
else
|
||||
neg += temp;
|
||||
temp = -mat_inp[0][0] * mat_inp[1][2] * mat_inp[2][1];
|
||||
if (temp >= 0.0)
|
||||
pos += temp;
|
||||
else
|
||||
neg += temp;
|
||||
det = pos + neg;
|
||||
|
||||
/* Is the submatrix A singular? */
|
||||
if ((det == 0.0) || (MAT_ABS(det / (pos - neg)) < PRECISION_LIMIT))
|
||||
return 0; /* Matrix M has no mat_inpverse */
|
||||
|
||||
/* Calculate inverse(A) = adj(A) / det(A) */
|
||||
mat_out[0][0] = (mat_inp[1][1] * mat_inp[2][2] - mat_inp[1][2] * mat_inp[2][1]) / det;
|
||||
mat_out[1][0] = -(mat_inp[1][0] * mat_inp[2][2] - mat_inp[1][2] * mat_inp[2][0]) / det;
|
||||
mat_out[2][0] = (mat_inp[1][0] * mat_inp[2][1] - mat_inp[1][1] * mat_inp[2][0]) / det;
|
||||
mat_out[0][1] = -(mat_inp[0][1] * mat_inp[2][2] - mat_inp[0][2] * mat_inp[2][1]) / det;
|
||||
mat_out[1][1] = (mat_inp[0][0] * mat_inp[2][2] - mat_inp[0][2] * mat_inp[2][0]) / det;
|
||||
mat_out[2][1] = -(mat_inp[0][0] * mat_inp[2][1] - mat_inp[0][1] * mat_inp[2][0]) / det;
|
||||
mat_out[0][2] = (mat_inp[0][1] * mat_inp[1][2] - mat_inp[0][2] * mat_inp[1][1]) / det;
|
||||
mat_out[1][2] = -(mat_inp[0][0] * mat_inp[1][2] - mat_inp[0][2] * mat_inp[1][0]) / det;
|
||||
mat_out[2][2] = (mat_inp[0][0] * mat_inp[1][1] - mat_inp[0][1] * mat_inp[1][0]) / det;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void mat_3x1_zero(MATFLOAT vec_out[3])
|
||||
{
|
||||
int nc;
|
||||
|
||||
for (nc = 0; nc < 3; nc++)
|
||||
vec_out[nc] = 0.0;
|
||||
}
|
||||
|
||||
void mat_3x3_zero(MATFLOAT mat_out[3][3])
|
||||
{
|
||||
int ni, nj;
|
||||
|
||||
for (ni = 0; ni < 3; ni++)
|
||||
for (nj = 0; nj < 3; nj++)
|
||||
mat_out[ni][nj] = 0.0;
|
||||
}
|
||||
|
||||
void mat_3x3_unity(MATFLOAT mat_out[3][3])
|
||||
{
|
||||
int ni, nj;
|
||||
|
||||
for (ni = 0; ni < 3; ni++)
|
||||
for (nj = 0; nj < 3; nj++)
|
||||
mat_out[ni][nj] = (ni == nj) ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
void mat_copy3x3(MATFLOAT mat_inp[3][3], MATFLOAT mat_out[3][3])
|
||||
{
|
||||
int ni, nj;
|
||||
|
||||
for (ni = 0; ni < 3; ni++)
|
||||
for (nj = 0; nj < 3; nj++)
|
||||
mat_out[ni][nj] = mat_inp[ni][nj];
|
||||
}
|
||||
|
||||
int mat_round(MATFLOAT val)
|
||||
{
|
||||
int sign = MAT_ZSGN(val);
|
||||
int val_out = (int)(MAT_ABS(val) + 0.5);
|
||||
|
||||
return sign * val_out;
|
||||
}
|
||||
|
||||
MATFLOAT mat_int2flt(int val, int val_max)
|
||||
{
|
||||
return (MATFLOAT)val / (MATFLOAT)val_max;
|
||||
}
|
||||
|
||||
int mat_flt2int(MATFLOAT val_inp, int val_max)
|
||||
{
|
||||
MATFLOAT val_tmp = val_inp * (MATFLOAT)val_max;
|
||||
int val_out = mat_round(val_tmp);
|
||||
|
||||
return MAT_CLAMP(val_out, 0, val_max);
|
||||
}
|
||||
|
||||
void mat_gen_mat_off(MATFLOAT mat_inp[3][3], MATFLOAT vec_off_inp[3],
|
||||
MATFLOAT vec_off_out[3], MATFLOAT mat_res[3][3], MATFLOAT vec_off_res[3])
|
||||
{
|
||||
int nc;
|
||||
|
||||
/* construct transform. The 'inoff' is merged into output offset. */
|
||||
if (vec_off_out)
|
||||
for (nc = 0; nc < 3; nc++)
|
||||
vec_off_res[nc] = vec_off_out[nc];
|
||||
else
|
||||
mat_3x1_zero(vec_off_res);
|
||||
|
||||
if (mat_inp)
|
||||
mat_copy3x3(mat_inp, mat_res);
|
||||
else
|
||||
mat_3x3_unity(mat_res);
|
||||
|
||||
if (vec_off_inp)
|
||||
for (nc = 0; nc < 3; nc++)
|
||||
vec_off_res[nc] -= (mat_res[nc][0] * vec_off_inp[0] + mat_res[nc][1] *
|
||||
vec_off_inp[1] + mat_res[nc][2] * vec_off_inp[2]);
|
||||
}
|
||||
|
||||
void mat_scl_off(MATFLOAT vec_off_inp[3], MATFLOAT vec_off_out[3], int bitwidth)
|
||||
{ /* output may be the same as input */
|
||||
int nc;
|
||||
|
||||
for (nc = 0; nc < 3; nc++)
|
||||
vec_off_out[nc] = vec_off_inp[nc] * (MATFLOAT)(1 << bitwidth);
|
||||
}
|
||||
|
||||
void mat_cvt_cs(int vec_inp[3], int vec_out[3], int bitwidth,
|
||||
MATFLOAT mat[3][3], MATFLOAT vec_off[3], int is_clip)
|
||||
{
|
||||
int nc, ni;
|
||||
|
||||
for (nc = 0; nc < 3; nc++) {
|
||||
MATFLOAT sum = vec_off[nc];
|
||||
|
||||
for (ni = 0; ni < 3; ni++)
|
||||
sum += mat[nc][ni] * (MATFLOAT)vec_inp[ni];
|
||||
int nValue = mat_round(sum);
|
||||
if (is_clip) {
|
||||
const int cnMaxValue = (1 << bitwidth) - 1;
|
||||
|
||||
MAT_CLAMP(nValue, 0, cnMaxValue);
|
||||
}
|
||||
vec_out[nc] = nValue;
|
||||
}
|
||||
}
|
||||
|
||||
MATFLOAT mat_norm_angle(MATFLOAT angle)
|
||||
{
|
||||
MATFLOAT pi2 = 2.0f * mat_get_pi();
|
||||
MATFLOAT angle_out = angle;
|
||||
|
||||
if (angle_out < 0.0f)
|
||||
angle_out += pi2;
|
||||
else if (angle_out >= pi2)
|
||||
angle_out -= pi2;
|
||||
|
||||
return angle_out;
|
||||
}
|
||||
|
||||
MATFLOAT mat_clamp(MATFLOAT val_inp, MATFLOAT val_min, MATFLOAT val_max)
|
||||
{
|
||||
return MAT_CLAMP(val_inp, val_min, val_max);
|
||||
}
|
||||
|
||||
int mat_is_valid(MATFLOAT val_inp, MATFLOAT val_min, MATFLOAT val_max)
|
||||
{
|
||||
return ((mat_is_number(val_inp) == 0) || (val_inp < val_min) || (val_inp > val_max)) ? 0 : 1;
|
||||
}
|
||||
|
||||
int mat_is_valid_vec(MATFLOAT vec_inp[], int size, MATFLOAT val_min, MATFLOAT val_max)
|
||||
{
|
||||
int ni;
|
||||
|
||||
for (ni = 0; ni < size; ni++)
|
||||
if (mat_is_valid(vec_inp[ni], val_min, val_max) == 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int mat_is_number(MATFLOAT val)
|
||||
{ /* Check if this is not NaN */
|
||||
return (val == val);
|
||||
}
|
||||
|
||||
MATFLOAT mat_norm(MATFLOAT val_inp, MATFLOAT val_min, MATFLOAT val_rng)
|
||||
{ /* map to [0.0,1.0] */
|
||||
return (val_inp - val_min) / val_rng;
|
||||
}
|
||||
|
||||
MATFLOAT mat_denorm(MATFLOAT val_inp, MATFLOAT val_min, MATFLOAT val_rng)
|
||||
{ /* map from [0.0,1.0] */
|
||||
return val_inp * val_rng + val_min;
|
||||
}
|
||||
|
||||
void mat_copy(MATFLOAT vec_inp[], MATFLOAT vec_out[], int size)
|
||||
{
|
||||
int nc;
|
||||
|
||||
for (nc = 0; nc < size; nc++)
|
||||
vec_out[nc] = vec_inp[nc];
|
||||
}
|
||||
|
||||
void mat_set(MATFLOAT val_inp, MATFLOAT vec_out[], int size)
|
||||
{
|
||||
int nc;
|
||||
|
||||
for (nc = 0; nc < size; nc++)
|
||||
vec_out[nc] = val_inp;
|
||||
}
|
||||
|
||||
int mat_flt_to_index(MATFLOAT val_inp, MATFLOAT val_max, int num_pnts)
|
||||
{
|
||||
MATFLOAT step = val_max / (MATFLOAT)(num_pnts - 1);
|
||||
|
||||
return (int)(val_inp / step);
|
||||
}
|
||||
|
||||
MATFLOAT mat_index_to_flt(int index, MATFLOAT val_max, int num_pnts)
|
||||
{
|
||||
MATFLOAT step = val_max / (MATFLOAT)(num_pnts - 1);
|
||||
|
||||
return (MATFLOAT)index * step;
|
||||
}
|
||||
|
||||
MATFLOAT mat_flt_to_index_phase(MATFLOAT val_inp, MATFLOAT val_max, int num_pnts, int vec_ind[2])
|
||||
{
|
||||
MATFLOAT step = val_max / (MATFLOAT)(num_pnts - 1);
|
||||
MATFLOAT tmp = val_inp / step;
|
||||
|
||||
vec_ind[0] = (int)tmp;
|
||||
vec_ind[1] = vec_ind[0] + 1;
|
||||
if (vec_ind[1] > num_pnts - 1)
|
||||
vec_ind[1] = num_pnts - 1;
|
||||
|
||||
return tmp - (MATFLOAT)vec_ind[0];
|
||||
}
|
||||
|
||||
MATFLOAT mat_vec_to_index_phase(MATFLOAT val_inp, MATFLOAT vec_val[], int num_pnts, int vec_ind[2])
|
||||
{
|
||||
int ind0, ind1;
|
||||
|
||||
/* calculate indexes */
|
||||
for (ind0 = num_pnts - 1; ind0 >= 0; ind0--) {
|
||||
if (val_inp >= vec_val[ind0])
|
||||
break;
|
||||
}
|
||||
ind1 = MAT_MIN(ind0 + 1, num_pnts - 1);
|
||||
|
||||
vec_ind[0] = ind0;
|
||||
vec_ind[1] = ind1;
|
||||
|
||||
return (vec_val[ind0] == vec_val[ind1]) ? 0.0 : (val_inp - vec_val[ind0]) / (vec_val[ind1] - vec_val[ind0]);
|
||||
}
|
||||
|
||||
int mat_int_to_index(int val_inp, int val_max, int num_indexes)
|
||||
{
|
||||
return val_inp * (num_indexes - 1) / val_max;
|
||||
}
|
||||
|
||||
int mat_index_to_int(int index, int val_max, int num_indexes)
|
||||
{
|
||||
return index * val_max / (num_indexes - 1);
|
||||
}
|
||||
|
||||
MATFLOAT mat_int_to_index_phase(int val_inp, int val_max, int num_indexes, int vec_val_ind[2])
|
||||
{
|
||||
MATFLOAT step = (MATFLOAT)val_max / (MATFLOAT)(num_indexes - 1);
|
||||
|
||||
vec_val_ind[0] = mat_int_to_index(val_inp, val_max, num_indexes);
|
||||
vec_val_ind[1] = MAT_MIN(vec_val_ind[0] + 1, num_indexes - 1);
|
||||
|
||||
return (val_inp - mat_index_to_int(vec_val_ind[0], val_max, num_indexes)) / step;
|
||||
}
|
||||
|
||||
int mat_get_hue_index_2pi(MATFLOAT vec_hue[], int num_hue_pnts)
|
||||
{ /* find a point crossing 2PI */
|
||||
int index_2pi;
|
||||
|
||||
for (index_2pi = num_hue_pnts - 1; index_2pi >= 1; index_2pi--)
|
||||
if (vec_hue[index_2pi] < vec_hue[index_2pi - 1])
|
||||
break;
|
||||
|
||||
return index_2pi;
|
||||
}
|
||||
|
||||
MATFLOAT mat_hue_to_index_phase(MATFLOAT val_inp, int num_hue_pnts,
|
||||
MATFLOAT vec_val[], MATFLOAT val_max, int index_max, int vec_ind_out[2])
|
||||
{
|
||||
int ind0, ind1;
|
||||
MATFLOAT step, delta;
|
||||
|
||||
/* calculate indexes */
|
||||
ind1 = index_max;
|
||||
while (val_inp >= vec_val[ind1]) {
|
||||
ind1 = (ind1 + 1) % num_hue_pnts;
|
||||
if (ind1 == index_max)
|
||||
break;
|
||||
}
|
||||
ind0 = (ind1 > 0) ? ind1 - 1 : num_hue_pnts - 1;
|
||||
|
||||
/* calculate phase */
|
||||
step = vec_val[ind1] - vec_val[ind0];
|
||||
if (step < 0.0)
|
||||
step += val_max;
|
||||
delta = val_inp - vec_val[ind0];
|
||||
if (delta < 0.0)
|
||||
delta += val_max;
|
||||
|
||||
vec_ind_out[0] = ind0;
|
||||
vec_ind_out[1] = ind1;
|
||||
|
||||
return delta / step;
|
||||
}
|
||||
|
||||
int mat_seg_intersection(MATFLOAT p0_xy[2], MATFLOAT p1_xy[2],
|
||||
MATFLOAT p2_xy[2], MATFLOAT p3_xy[2], MATFLOAT p_xy[2])
|
||||
{
|
||||
MATFLOAT s1_x = p1_xy[0] - p0_xy[0];
|
||||
MATFLOAT s1_y = p1_xy[1] - p0_xy[1];
|
||||
MATFLOAT s2_x = p3_xy[0] - p2_xy[0];
|
||||
MATFLOAT s2_y = p3_xy[1] - p2_xy[1];
|
||||
MATFLOAT denom = -s2_x * s1_y + s1_x * s2_y;
|
||||
MATFLOAT s0_x, s0_y, s, t;
|
||||
|
||||
if (denom == 0.0)
|
||||
return 0; /* no collision */
|
||||
|
||||
s0_x = p0_xy[0] - p2_xy[0];
|
||||
s0_y = p0_xy[1] - p2_xy[1];
|
||||
|
||||
s = (-s1_y * s0_x + s1_x * s0_y) / denom;
|
||||
if ((s < 0.0) || (s > 1.0))
|
||||
return 0; /* no collision */
|
||||
|
||||
t = (s2_x * s0_y - s2_y * s0_x) / denom;
|
||||
if ((t < 0.0) || (t > 1.0))
|
||||
return 0; /* no collision */
|
||||
|
||||
/* collision detected */
|
||||
p_xy[0] = p0_xy[0] + (t * s1_x);
|
||||
p_xy[1] = p0_xy[1] + (t * s1_y);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
MATFLOAT mat_linear(MATFLOAT vec_inp[2], MATFLOAT phs)
|
||||
{
|
||||
return vec_inp[0] + (vec_inp[1] - vec_inp[0]) * phs;
|
||||
}
|
||||
|
||||
MATFLOAT mat_bilinear(MATFLOAT vec_inp[2][2], MATFLOAT vec_phs[2])
|
||||
{
|
||||
int ni;
|
||||
MATFLOAT vec_tmp[2];
|
||||
|
||||
for (ni = 0; ni < 2; ni++)
|
||||
vec_tmp[ni] = mat_linear(vec_inp[ni], vec_phs[0]);
|
||||
|
||||
return mat_linear(vec_tmp, vec_phs[1]);
|
||||
}
|
||||
|
||||
MATFLOAT mat_trilinear(MATFLOAT vec_inp[2][2][2], MATFLOAT vec_phs[3])
|
||||
{
|
||||
int ni;
|
||||
MATFLOAT vec_tmp[2];
|
||||
|
||||
for (ni = 0; ni < 2; ni++)
|
||||
vec_tmp[ni] = mat_bilinear(vec_inp[ni], vec_phs);
|
||||
|
||||
return mat_linear(vec_tmp, vec_phs[2]);
|
||||
}
|
||||
|
||||
MATFLOAT mat_tetra(MATFLOAT vec_inp[2][2][2], MATFLOAT vec_phs[3])
|
||||
{
|
||||
MATFLOAT fx = vec_phs[2];
|
||||
MATFLOAT fy = vec_phs[1];
|
||||
MATFLOAT fz = vec_phs[0];
|
||||
MATFLOAT vec_c[3];
|
||||
MATFLOAT value;
|
||||
int nc;
|
||||
|
||||
if (fx > fy) {
|
||||
if (fy > fz) { /* T0: x > y > z */
|
||||
vec_c[0] = vec_inp[1][0][0] - vec_inp[0][0][0];
|
||||
vec_c[1] = vec_inp[1][1][0] - vec_inp[1][0][0];
|
||||
vec_c[2] = vec_inp[1][1][1] - vec_inp[1][1][0];
|
||||
} else if (fx > fz) { /* T5: x > z > y */
|
||||
vec_c[0] = vec_inp[1][0][0] - vec_inp[0][0][0];
|
||||
vec_c[1] = vec_inp[1][1][1] - vec_inp[1][0][1];
|
||||
vec_c[2] = vec_inp[1][0][1] - vec_inp[1][0][0];
|
||||
} else { /* T4: z > x > y */
|
||||
vec_c[0] = vec_inp[1][0][1] - vec_inp[0][0][1];
|
||||
vec_c[1] = vec_inp[1][1][1] - vec_inp[1][0][1];
|
||||
vec_c[2] = vec_inp[0][0][1] - vec_inp[0][0][0];
|
||||
}
|
||||
} else {
|
||||
if (fx > fz) { /* T1: y > x > z */
|
||||
vec_c[0] = vec_inp[1][1][0] - vec_inp[0][1][0];
|
||||
vec_c[1] = vec_inp[0][1][0] - vec_inp[0][0][0];
|
||||
vec_c[2] = vec_inp[1][1][1] - vec_inp[1][1][0];
|
||||
} else if (fy > fz) { /* T2: y > z > x */
|
||||
vec_c[0] = vec_inp[1][1][1] - vec_inp[0][1][1];
|
||||
vec_c[1] = vec_inp[0][1][0] - vec_inp[0][0][0];
|
||||
vec_c[2] = vec_inp[0][1][1] - vec_inp[0][1][0];
|
||||
} else { /* T3: z > y > x */
|
||||
vec_c[0] = vec_inp[1][1][1] - vec_inp[0][1][1];
|
||||
vec_c[1] = vec_inp[0][1][1] - vec_inp[0][0][1];
|
||||
vec_c[2] = vec_inp[0][0][1] - vec_inp[0][0][0];
|
||||
}
|
||||
}
|
||||
|
||||
value = vec_inp[0][0][0];
|
||||
for (nc = 0; nc < 3; nc++)
|
||||
value += vec_c[nc] * vec_phs[2 - nc];
|
||||
|
||||
return MAT_CLAMP(value, 0.0, 1.0);
|
||||
}
|
||||
|
||||
MATFLOAT mat_cubic(MATFLOAT vec_inp[4], MATFLOAT phs)
|
||||
{
|
||||
return vec_inp[1] + 0.5 * phs * (vec_inp[2] - vec_inp[0] +
|
||||
phs * (2.0 * vec_inp[0] - 5.0 * vec_inp[1] + 4.0 * vec_inp[2] - vec_inp[3] +
|
||||
phs * (3.0 * (vec_inp[1] - vec_inp[2]) + vec_inp[3] - vec_inp[0])));
|
||||
}
|
||||
|
||||
MATFLOAT mat_mse(MATFLOAT val1[], MATFLOAT val2[], int size)
|
||||
{
|
||||
MATFLOAT err = 0.0;
|
||||
int nc;
|
||||
|
||||
for (nc = 0; nc < size; nc++) {
|
||||
MATFLOAT err_tmp = val1[nc] - val2[nc];
|
||||
|
||||
err += err_tmp * err_tmp;
|
||||
}
|
||||
|
||||
return mat_sqrt(err);
|
||||
}
|
||||
|
||||
MATFLOAT mat_sshape(MATFLOAT val, MATFLOAT gamma)
|
||||
{
|
||||
MATFLOAT k = 0.5 * mat_pow(0.5, -gamma);
|
||||
MATFLOAT val_out = (val <= 0.5) ? k * mat_pow(val, gamma) : 1.0 - k * mat_pow((1.0 - val), gamma);
|
||||
|
||||
return val_out;
|
||||
}
|
||||
|
||||
MATFLOAT mat_radius_vec(MATFLOAT vec_val[], MATFLOAT vec_org[], int size)
|
||||
{
|
||||
MATFLOAT radius = 0.0;
|
||||
int ni;
|
||||
|
||||
for (ni = 0; ni < size; ni++)
|
||||
radius += (vec_val[ni] - vec_org[ni]) * (vec_val[ni] - vec_org[ni]);
|
||||
|
||||
return mat_sqrt(radius);
|
||||
}
|
||||
|
||||
void mat_gain_vec(MATFLOAT vec_inp[], MATFLOAT vec_out[], MATFLOAT vec_org[], int size, MATFLOAT gain)
|
||||
{
|
||||
int ni;
|
||||
|
||||
for (ni = 0; ni < 3; ni++)
|
||||
vec_out[ni] = vec_org[ni] + (vec_inp[ni] - vec_org[ni]) * gain;
|
||||
}
|
||||
|
||||
MATFLOAT mat_get_pi(void)
|
||||
{
|
||||
#ifdef GM_MAT_MATH
|
||||
return (MATFLOAT)acos(-1.0);
|
||||
#else
|
||||
return 3.14159265358979323;
|
||||
#endif
|
||||
}
|
||||
|
||||
MATFLOAT mat_angle(MATFLOAT y, MATFLOAT x)
|
||||
{
|
||||
return mat_norm_angle(mat_atan2(y, x));
|
||||
}
|
||||
|
||||
MATFLOAT mat_radius(MATFLOAT y, MATFLOAT x)
|
||||
{
|
||||
return mat_sqrt(y * y + x * x);
|
||||
}
|
||||
|
||||
MATFLOAT mat_pow(MATFLOAT val0, MATFLOAT val1)
|
||||
{
|
||||
return (MATFLOAT)pow(val0, val1);
|
||||
}
|
||||
|
||||
MATFLOAT mat_atan2(MATFLOAT y, MATFLOAT x)
|
||||
{
|
||||
return (MATFLOAT)atan2(y, x);
|
||||
}
|
||||
|
||||
MATFLOAT mat_cos(MATFLOAT val)
|
||||
{
|
||||
return (MATFLOAT)cos(val);
|
||||
}
|
||||
|
||||
MATFLOAT mat_sin(MATFLOAT val)
|
||||
{
|
||||
return (MATFLOAT)sin(val);
|
||||
}
|
||||
|
||||
MATFLOAT mat_log2(MATFLOAT val)
|
||||
{
|
||||
return (MATFLOAT)(mat_log(val) / mat_log(2.0));
|
||||
}
|
||||
|
||||
MATFLOAT mat_log10(MATFLOAT val)
|
||||
{
|
||||
return (MATFLOAT)(mat_log(val) / mat_log(10.0));
|
||||
}
|
||||
|
||||
MATFLOAT mat_frexp(MATFLOAT val, int *exponent)
|
||||
{
|
||||
return (MATFLOAT)frexp(val, exponent);
|
||||
}
|
||||
|
||||
#ifndef GM_MAT_MATH
|
||||
static const unsigned char root_recip_table[128] = {
|
||||
0x69, 0x66, 0x63, 0x61, 0x5E, 0x5B, 0x59, 0x57, /* for x =(2.0 ... 3.99)*(4^n) */
|
||||
0x54, 0x52, 0x50, 0x4D, 0x4B, 0x49, 0x47, 0x45, /* (exponent is even) */
|
||||
0x43, 0x41, 0x3F, 0x3D, 0x3B, 0x39, 0x37, 0x36,
|
||||
0x34, 0x32, 0x30, 0x2F, 0x2D, 0x2C, 0x2A, 0x28,
|
||||
0x27, 0x25, 0x24, 0x22, 0x21, 0x1F, 0x1E, 0x1D,
|
||||
0x1B, 0x1A, 0x19, 0x17, 0x16, 0x15, 0x14, 0x12,
|
||||
0x11, 0x10, 0x0F, 0x0D, 0x0C, 0x0B, 0x0A, 0x09,
|
||||
0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,
|
||||
0xFE, 0xFA, 0xF6, 0xF3, 0xEF, 0xEB, 0xE8, 0xE4, /* for x =(1.0 ... 1.99)*(4^n) */
|
||||
0xE1, 0xDE, 0xDB, 0xD7, 0xD4, 0xD1, 0xCE, 0xCB, /* (exponent is odd) */
|
||||
0xC9, 0xC6, 0xC3, 0xC0, 0xBE, 0xBB, 0xB8, 0xB6,
|
||||
0xB3, 0xB1, 0xAF, 0xAC, 0xAA, 0xA8, 0xA5, 0xA3,
|
||||
0xA1, 0x9F, 0x9D, 0x9B, 0x99, 0x97, 0x95, 0x93,
|
||||
0x91, 0x8F, 0x8D, 0x8B, 0x89, 0x87, 0x86, 0x84,
|
||||
0x82, 0x80, 0x7F, 0x7D, 0x7B, 0x7A, 0x78, 0x77,
|
||||
0x75, 0x74, 0x72, 0x71, 0x6F, 0x6E, 0x6C, 0x6B
|
||||
};
|
||||
|
||||
/*
|
||||
* find a reciprocal of square-root of x, using a similar method.
|
||||
* an approximation is found, using the 6 MSBs of the mantissa,
|
||||
* and the LSB of the exponent.
|
||||
* The exponent mapping is a bit tricker than in the RECIPS case:
|
||||
* we want
|
||||
* 125,126 -> 127
|
||||
* 127,128 -> 126
|
||||
* 129,130 -> 125
|
||||
* 131,132 -> 124
|
||||
*
|
||||
* So, we can take original exponent, add 131, then >>1, then
|
||||
* take the 1's complement.
|
||||
* The result is accurate +/- 1 lsb in float precision. I'm not
|
||||
* sure exactly what the full range of this is, it should
|
||||
* work for any values >0, except for denormals.
|
||||
*
|
||||
* iterative method:
|
||||
* Cavanagh, J. 1984. Digital Computer Arithmetic. McGraw-Hill. Page 278.
|
||||
*/
|
||||
float mat_fast_rsqrt(float val)
|
||||
{
|
||||
union {
|
||||
float fval;
|
||||
unsigned int uval;
|
||||
} u;
|
||||
unsigned int new_mant;
|
||||
float rsqa, rprod;
|
||||
|
||||
u.fval = val;
|
||||
u.uval &= 0x7FFFFFFF; /* can't have sign */
|
||||
val = u.fval * 0.5f;
|
||||
|
||||
new_mant = root_recip_table[(u.uval >> 17) & 0x7F];
|
||||
/*
|
||||
* create modified exponent ; drop in new mantissa
|
||||
*/
|
||||
u.uval = (~((u.uval + 0x41800000) >> 1) & 0x7F800000) + (new_mant << 15);
|
||||
rsqa = u.fval;
|
||||
/*
|
||||
* note: we could do
|
||||
* rsqa *= 1.5f - rsqa*rsqa * x
|
||||
* but there are cases where x is very small
|
||||
* (zero or denormal) and rsqa*rsqa could overflow. We generate
|
||||
* the wrong answer in these cases, but at least it isn't a NaN.
|
||||
*/
|
||||
rprod = val * rsqa;
|
||||
rsqa *= 1.5f - rprod * rsqa;
|
||||
rprod = val * rsqa;
|
||||
rsqa *= 1.5f - rprod * rsqa;
|
||||
rprod = val * rsqa;
|
||||
rsqa *= 1.5f - rprod * rsqa;
|
||||
|
||||
return rsqa;
|
||||
}
|
||||
|
||||
#define Declare_Special_Float(cnst) { union { unsigned int ui; float f; } u; u.ui = (cnst); return u.f; }
|
||||
float FLT_INF(void);
|
||||
float FLT_MINF(void);
|
||||
float FLT_NAN(void);
|
||||
float FLT_INF(void) Declare_Special_Float(0x7F800000);
|
||||
float FLT_MINF(void) Declare_Special_Float(0xFF800000);
|
||||
float FLT_NAN(void) Declare_Special_Float(0x7F800001);
|
||||
/*
|
||||
* table below is
|
||||
* a = log(x+1), b = exp(-a);
|
||||
* comment shows range of x to which each line applies.
|
||||
*/
|
||||
static const float log_tab[64] = {
|
||||
0.000000000f, 1.000000000f, /* 0 to 0.0111657 */
|
||||
0.022311565f, 0.977935498f, /* ... to 0.0340233 */
|
||||
0.044580154f, 0.956398938f, /* ... to 0.0572837 */
|
||||
0.066807851f, 0.935374915f, /* ... to 0.0810282 */
|
||||
0.089004092f, 0.914841830f, /* ... to 0.1052765 */
|
||||
0.111178130f, 0.894779348f, /* ... to 0.1300487 */
|
||||
0.133338988f, 0.875168370f, /* ... to 0.1553661 */
|
||||
0.155495435f, 0.855990985f, /* ... to 0.1812505 */
|
||||
0.177655950f, 0.837230423f, /* ... to 0.2077248 */
|
||||
0.199828684f, 0.818871027f, /* ... to 0.2348125 */
|
||||
0.222021341f, 0.800898272f, /* ... to 0.2625375 */
|
||||
0.244241118f, 0.783298744f, /* ... to 0.2909245 */
|
||||
0.266494602f, 0.766060139f, /* ... to 0.3199984 */
|
||||
0.288787603f, 0.749171310f, /* ... to 0.3497841 */
|
||||
0.311125100f, 0.732622219f, /* ... to 0.3803064 */
|
||||
0.333510906f, 0.716404086f, /* ... to 0.4115894 */
|
||||
0.355947524f, 0.700509379f, /* ... to 0.4436560 */
|
||||
0.378435910f, 0.684931867f, /* ... to 0.4765275 */
|
||||
0.400975198f, 0.669666670f, /* ... to 0.5102230 */
|
||||
0.423562229f, 0.654710433f, /* ... to 0.5447579 */
|
||||
0.446191430f, 0.640061233f, /* ... to 0.5801435 */
|
||||
0.468854219f, 0.625718795f, /* ... to 0.6163859 */
|
||||
0.491538733f, 0.611684450f, /* ... to 0.6534842 */
|
||||
0.514229417f, 0.597961196f, /* ... to 0.6914296 */
|
||||
0.536906660f, 0.584553682f, /* ... to 0.7302038 */
|
||||
0.559546530f, 0.571468149f, /* ... to 0.7697776 */
|
||||
0.582120657f, 0.558712272f, /* ... to 0.8101096 */
|
||||
0.604596078f, 0.546295042f, /* ... to 0.8511456 */
|
||||
0.626935601f, 0.534226378f, /* ... to 0.8928175 */
|
||||
0.649098098f, 0.522516823f, /* ... to 0.9350435 */
|
||||
0.671039402f, 0.511176983f, /* ... to 0.9777287 */
|
||||
0.693147182f, 0.500000000f, /* ....to 0.9999999 */
|
||||
};
|
||||
|
||||
/*
|
||||
* FAST LN function
|
||||
*
|
||||
* (1) split the number into its base-2 exponent 'e', and
|
||||
* a mantissa 'xm' in range 1.0 .. 1.99999
|
||||
*
|
||||
* (2) using a cubic, find y0 = approx. ln(xm)
|
||||
* (3) scale this, round it to a table index 0...31.
|
||||
* From the table, get a log value, (which will be added to the result)
|
||||
* and a scale factor.
|
||||
* Multiply xm by the scale factor, result xe is very close to 1.
|
||||
*
|
||||
* (4) find ye = log(xe) using a taylor series around xe=1
|
||||
* (5) result is is yt+ye+log(2)*exp, where yt is from the table (1st col)
|
||||
* and exp is the original exponent.
|
||||
* Note that multiplying the input by the second column of the the table,
|
||||
* and adding the 1st column of the table to the result, has no net effect.
|
||||
*/
|
||||
float mat_fast_log(float x)
|
||||
{
|
||||
union {
|
||||
float f;
|
||||
unsigned int ui;
|
||||
} u;
|
||||
float xm1, xe, ye;
|
||||
int tabind;
|
||||
int ex;
|
||||
|
||||
u.f = x;
|
||||
ex = ((u.ui >> 23) & 0x1FF) - 127;
|
||||
if ((ex <= -127) || (ex >= 128)) {
|
||||
if ((ex & 0xFF) == 1)
|
||||
return FLT_MINF(); /* was 0.0 or -0.0 (or denormal) */
|
||||
return FLT_NAN();
|
||||
}
|
||||
u.ui -= ex << 23;
|
||||
/*
|
||||
* now u.f is in range 1.0 ... 1.99999
|
||||
*/
|
||||
xm1 = u.f - 1.0f; /* 0. 1.0 */
|
||||
/*
|
||||
* The table above and the cubic below were generated together
|
||||
*/
|
||||
tabind = MAT_ROUND(((xm1 * 0.1328047513f - 0.4396575689f) * xm1 * xm1 + xm1) * 44.75f);
|
||||
/*
|
||||
* tabind is in range 0..31.
|
||||
* multiply u.f by the second value in the table, subtract 1
|
||||
*/
|
||||
xe = u.f * log_tab[2 * tabind + 1] - 1.0f; /* result is +/- .0114 */
|
||||
|
||||
/*
|
||||
* find the log(xe+1) using taylor series; add to (a) amount from exponent
|
||||
* (b) amount from table
|
||||
*/
|
||||
ye = ((-0.25f * xe + 0.333333333f) * xe - 0.5f) * xe * xe;
|
||||
ye += xe;
|
||||
return 0.693147182f * (float)ex + log_tab[2 * tabind] + ye;
|
||||
}
|
||||
|
||||
static const float exp_table[16] =
|
||||
{
|
||||
/* (1/6) * 2^(i/16.), to float precision */
|
||||
0.166666672f, 0.174045637f, 0.181751296f, 0.189798102f,
|
||||
0.198201180f, 0.206976309f, 0.216139928f, 0.225709260f,
|
||||
0.235702261f, 0.246137694f, 0.257035136f, 0.268415064f,
|
||||
0.280298799f, 0.292708695f, 0.305668026f, 0.319201082f
|
||||
};
|
||||
|
||||
/*
|
||||
* FAST_EXP does an exponential function.
|
||||
* This is done using a table lookup to
|
||||
* get close and a taylor series to
|
||||
* get accurate.
|
||||
*
|
||||
* if y = exp(x) = (2^m)*(P^n)*exp(f), where P = 2^(1/16),
|
||||
*
|
||||
* then x = ln(2^m) + ln(P^n) + f
|
||||
* = ln(P^(16*m+n)) + f
|
||||
* = ln(P) * [ 16*m +n ] +f
|
||||
* let k = ln(P) = ln(2)/16 = 0.043321698785
|
||||
*
|
||||
* so x = k*[16*m + n] + f
|
||||
*
|
||||
* For a given x, we find m,n,f such that:
|
||||
* m is an integer
|
||||
* n is in integer 0..15
|
||||
* f is as close to zero as possible: +/- k/2
|
||||
*
|
||||
* Then we find y = (2^m)*(P^n)*exp(f)
|
||||
*
|
||||
* where 2^m is an exponent adjustment, P^n is a table lookup
|
||||
* and exp(f) is calculated. The 4th term in the series
|
||||
* for exp(f) is at most k^4/(16*24) = 9.17e-9, so we only
|
||||
* need to do up to the 3rd order.
|
||||
*
|
||||
* One more quirk:
|
||||
* exp(f) is evaluated via
|
||||
* 6*exp(f) = ((f + 3)*f + 6)*f + 6
|
||||
*
|
||||
* To compensate, the numbers in the P^n table are really 1/6 as
|
||||
* big as they should be.
|
||||
*
|
||||
* Example: exp(13.2)
|
||||
* 13.2 * (1/k) = 304.697, round to 305 => m*16+n = 305
|
||||
* f = 13.2 - k * 305 = -0.013118
|
||||
* m = 19, n = 1
|
||||
*
|
||||
* 6*exp(f) = ((f + 3)*f + 6)*f + 6 = 5.921805
|
||||
* exp_table[n] * (6*exp(f)) = .174046 * 5.921805 = 1.030664
|
||||
* multiply that by 2^m (=5.24288e5) -> 5.40365e5
|
||||
*
|
||||
*/
|
||||
float mat_fast_exp(float x)
|
||||
{
|
||||
int m, n;
|
||||
union {
|
||||
unsigned ui;
|
||||
float f;
|
||||
} u;
|
||||
|
||||
n = MAT_ROUND(x * 23.08312065f); /* 16/log(2) */
|
||||
/*
|
||||
* range check on n now
|
||||
*/
|
||||
if ((n <= -2016) || (n >= 2048)) {
|
||||
if (n < 0)
|
||||
return 0.0f;
|
||||
else
|
||||
return FLT_INF();
|
||||
}
|
||||
x -= (float)n * 0.043321698785f; /* log(2)/16. */
|
||||
|
||||
m = (n >> 4);
|
||||
x = ((x + 3.0f) * x + 6.0f) * x + 6.0f;
|
||||
u.f = x * exp_table[n & 15];
|
||||
u.ui += (m << 23); /* exponent adjust */
|
||||
|
||||
return u.f;
|
||||
}
|
||||
#endif
|
||||
|
||||
MATFLOAT mat_sqrt(MATFLOAT val)
|
||||
{
|
||||
#ifndef GM_MAT_MATH
|
||||
return 1.0 / (MATFLOAT)mat_fast_rsqrt((float)val);
|
||||
#else
|
||||
return (MATFLOAT)sqrt(val);
|
||||
#endif
|
||||
}
|
||||
|
||||
MATFLOAT mat_log(MATFLOAT val)
|
||||
{ /* base e */
|
||||
#ifdef GM_MAT_MATH
|
||||
return (MATFLOAT)log(val);
|
||||
#else
|
||||
return (MATFLOAT)mat_fast_log((float)val);
|
||||
#endif
|
||||
}
|
||||
|
||||
MATFLOAT mat_exp(MATFLOAT val)
|
||||
{
|
||||
#ifdef GM_MAT_MATH
|
||||
return (MATFLOAT)exp(val);
|
||||
#else
|
||||
return (MATFLOAT)mat_fast_exp((float)val);
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int mat_index_3dlut(int ind_r, int ind_g, int ind_b, int num_pnts, enum mat_order_3dlut order)
|
||||
{
|
||||
unsigned int index;
|
||||
|
||||
switch (order) {
|
||||
case MAT_ORDER_RGB:
|
||||
index = (ind_b * num_pnts + ind_g) * num_pnts + ind_r;
|
||||
break;
|
||||
case MAT_ORDER_BGR:
|
||||
default:
|
||||
index = (ind_r * num_pnts + ind_g) * num_pnts + ind_b;
|
||||
break;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
143
src/amd/gmlib/gm/mat_funcs.h
Executable file
143
src/amd/gmlib/gm/mat_funcs.h
Executable file
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
* File Name : mat_funcs.h
|
||||
* Purpose : Mathematical functions
|
||||
* Author : Vladimir Lachine (vlachine@amd.com)
|
||||
* Date : September 20, 2023
|
||||
* Version : 1.2
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MATFLOAT double
|
||||
|
||||
/* precision for matrix inversion */
|
||||
#define PRECISION_LIMIT (1.0e-15)
|
||||
|
||||
/* absolute value of a */
|
||||
#define MAT_ABS(a) (((a) < 0) ? -(a) : (a))
|
||||
|
||||
/* find minimum of a and b */
|
||||
#define MAT_MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
/* find maximum of a and b */
|
||||
#define MAT_MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
/* clip to range */
|
||||
#define MAT_CLAMP(v, l, h) ((v) < (l) ? (l) : ((v) > (h) ? (h) : v))
|
||||
|
||||
/* round a to nearest int */
|
||||
#define MAT_ROUND(a) (int)((a) + 0.5f)
|
||||
|
||||
/* take sign of a, either -1, 0, or 1 */
|
||||
#define MAT_ZSGN(a) (((a) < 0) ? -1 : (a) > 0 ? 1 : 0)
|
||||
|
||||
/* take binary sign of a, either -1, or 1 if >= 0 */
|
||||
#define MAT_SGN(a) (((a) < 0) ? -1 : 1)
|
||||
|
||||
/* swap a and b (see Gem by Wyvill) */
|
||||
#define MAT_SWAP(a, b) { a ^ = b; b ^ = a; a ^= b; }
|
||||
|
||||
/* linear interpolation from l (when a=0) to h (when a=1) */
|
||||
/* (equal to (a*h)+((1-a)*l) */
|
||||
#define MAT_LERP(a, l, h) ((l) + (((h) - (l)) * (a)))
|
||||
|
||||
/* vector operations */
|
||||
void mat_eval_3x3(MATFLOAT mat[3][3], MATFLOAT vec_inp[3], MATFLOAT vec_out[3]);
|
||||
void mat_eval_3x3_off(MATFLOAT mat[3][3], MATFLOAT vec_off[3], MATFLOAT vec_inp[3], MATFLOAT vec_out[3]);
|
||||
void mat_eval_off_3x3_off(MATFLOAT vec_off_inp[3], MATFLOAT mat[3][3],
|
||||
MATFLOAT vec_off_out[3], MATFLOAT vec_inp[3], MATFLOAT vec_out[3]);
|
||||
void mat_mul3x3(MATFLOAT mat2[3][3], MATFLOAT mat1[3][3], MATFLOAT mat2x1[3][3]);
|
||||
int mat_inv3x3(MATFLOAT mat_inp[3][3], MATFLOAT mat_out[3][3]);
|
||||
|
||||
void mat_3x1_zero(MATFLOAT vec_out[3]);
|
||||
void mat_3x3_zero(MATFLOAT mat_out[3][3]);
|
||||
void mat_3x3_unity(MATFLOAT mat_out[3][3]);
|
||||
void mat_copy3x3(MATFLOAT mat_inp[3][3], MATFLOAT mat_out[3][3]);
|
||||
|
||||
int mat_round(MATFLOAT val);
|
||||
|
||||
MATFLOAT mat_int2flt(int val, int val_max);
|
||||
int mat_flt2int(MATFLOAT val, int val_max);
|
||||
|
||||
void mat_gen_mat_off(MATFLOAT mat_inp[3][3], MATFLOAT vec_off_inp[3],
|
||||
MATFLOAT vec_off_out[3], MATFLOAT mat_res[3][3], MATFLOAT vec_off_res[3]);
|
||||
void mat_scl_off(MATFLOAT vec_off_inp[3], MATFLOAT vec_off_out[3], int bitwidth);
|
||||
void mat_cvt_cs(int vec_inp[3], int vec_out[3], int bitwidth, MATFLOAT mat[3][3], MATFLOAT vec_off[3], int is_clip);
|
||||
|
||||
MATFLOAT mat_norm_angle(MATFLOAT angle);
|
||||
|
||||
MATFLOAT mat_clamp(MATFLOAT val_inp, MATFLOAT val_min, MATFLOAT val_max);
|
||||
int mat_is_valid(MATFLOAT val_inp, MATFLOAT val_min, MATFLOAT val_max);
|
||||
int mat_is_valid_vec(MATFLOAT val_inp[], int size, MATFLOAT val_min, MATFLOAT val_max);
|
||||
int mat_is_number(MATFLOAT val);
|
||||
MATFLOAT mat_norm(MATFLOAT val_inp, MATFLOAT val_min, MATFLOAT val_rng);
|
||||
MATFLOAT mat_denorm(MATFLOAT val_inp, MATFLOAT val_min, MATFLOAT val_rng);
|
||||
|
||||
void mat_copy(MATFLOAT vec_inp[], MATFLOAT vec_out[], int size);
|
||||
void mat_set(MATFLOAT val_inp, MATFLOAT vec_out[], int size);
|
||||
|
||||
int mat_flt_to_index(MATFLOAT val_inp, MATFLOAT val_max, int num_pnts);
|
||||
MATFLOAT mat_index_to_flt(int index, MATFLOAT val_max, int num_pnts);
|
||||
MATFLOAT mat_flt_to_index_phase(MATFLOAT val_inp, MATFLOAT val_max, int num_pnts, int vec_ind[2]);
|
||||
MATFLOAT mat_vec_to_index_phase(MATFLOAT val_inp, MATFLOAT vec_val[], int num_pnts, int vec_ind[2]);
|
||||
|
||||
int mat_int_to_index(int val_inp, int val_max, int num_indexes);
|
||||
int mat_index_to_int(int index, int val_max, int num_indexes);
|
||||
MATFLOAT mat_int_to_index_phase(int val_inp, int val_max, int num_indexes, int vec_val_ind[2]);
|
||||
int mat_get_hue_index_2pi(MATFLOAT vec_hue[], int num_hue_pnts);
|
||||
MATFLOAT mat_hue_to_index_phase(MATFLOAT val_inp, int num_hue_pnts,
|
||||
MATFLOAT vec_val[], MATFLOAT val_max, int index_max, int vec_ind_out[2]);
|
||||
|
||||
int mat_seg_intersection(MATFLOAT p0_xy[2], MATFLOAT p1_xy[2],
|
||||
MATFLOAT p2_xy[2], MATFLOAT p3_xy[2], MATFLOAT p_xy[2]);
|
||||
|
||||
MATFLOAT mat_linear(MATFLOAT vec_inp[2], MATFLOAT phs);
|
||||
MATFLOAT mat_bilinear(MATFLOAT vec_inp[2][2], MATFLOAT vec_phs[2]);
|
||||
MATFLOAT mat_trilinear(MATFLOAT vec_inp[2][2][2], MATFLOAT vec_phs[3]);
|
||||
MATFLOAT mat_tetra(MATFLOAT vec_inp[2][2][2], MATFLOAT vec_phs[3]);
|
||||
MATFLOAT mat_cubic(MATFLOAT vec_inp[4], MATFLOAT phs);
|
||||
|
||||
MATFLOAT mat_mse(MATFLOAT val1[], MATFLOAT val2[], int size);
|
||||
MATFLOAT mat_sshape(MATFLOAT val, MATFLOAT gamma);
|
||||
MATFLOAT mat_get_pi(void);
|
||||
|
||||
MATFLOAT mat_angle(MATFLOAT y, MATFLOAT x);
|
||||
MATFLOAT mat_radius(MATFLOAT y, MATFLOAT x);
|
||||
MATFLOAT mat_radius_vec(MATFLOAT val[], MATFLOAT org[], int size);
|
||||
void mat_gain_vec(MATFLOAT vec_inp[], MATFLOAT vec_out[], MATFLOAT vec_org[], int size, MATFLOAT gain);
|
||||
|
||||
MATFLOAT mat_pow(MATFLOAT val0, MATFLOAT val1);
|
||||
MATFLOAT mat_atan2(MATFLOAT y, MATFLOAT x);
|
||||
MATFLOAT mat_cos(MATFLOAT val);
|
||||
MATFLOAT mat_sin(MATFLOAT val);
|
||||
MATFLOAT mat_sqrt(MATFLOAT val);
|
||||
MATFLOAT mat_log(MATFLOAT val);
|
||||
MATFLOAT mat_log2(MATFLOAT val);
|
||||
MATFLOAT mat_log10(MATFLOAT val);
|
||||
MATFLOAT mat_frexp(MATFLOAT val, int *exponent);
|
||||
|
||||
#ifndef GM_MAT_MATH
|
||||
float mat_fast_rsqrt(float val);
|
||||
float mat_fast_exp(float x);
|
||||
#endif
|
||||
|
||||
MATFLOAT mat_exp(MATFLOAT val);
|
||||
|
||||
enum mat_order_3dlut {
|
||||
MAT_ORDER_RGB = 0,
|
||||
MAT_ORDER_BGR = 1
|
||||
};
|
||||
|
||||
unsigned int mat_index_3dlut(int ind_r, int ind_g, int ind_b, int num_pnts, enum mat_order_3dlut order);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
65
src/amd/gmlib/meson.build
Executable file
65
src/amd/gmlib/meson.build
Executable file
|
|
@ -0,0 +1,65 @@
|
|||
# Copyright 2022 Advanced Micro Devices, Inc.
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
c_args_gm = cc.get_supported_arguments([
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Wno-unused',
|
||||
'-Wno-unused-parameter',
|
||||
'-Wno-unused-command-line-argument',
|
||||
'-Wno-ignored-qualifiers',
|
||||
'-Wno-missing-field-initializers',
|
||||
'-Wno-self-assign',
|
||||
'-Wno-implicit-fallthrough',
|
||||
'-Werror=comment',
|
||||
'-Werror=missing-braces',
|
||||
'-Werror=override-init',
|
||||
'-Werror=enum-conversion',
|
||||
'-Werror=enum-compare',
|
||||
'-Werror=maybe-uninitialized',
|
||||
])
|
||||
|
||||
c_args_gm += [
|
||||
'-DGM_SIM',
|
||||
]
|
||||
|
||||
gm_files = files(
|
||||
'tonemap_adaptor.h',
|
||||
'tonemap_adaptor.c',
|
||||
'gm/csc_api_funcs.c',
|
||||
'gm/csc_api_funcs.h',
|
||||
'gm/csc_funcs.c',
|
||||
'gm/csc_funcs.h',
|
||||
'gm/cs_funcs.c',
|
||||
'gm/cs_funcs.h',
|
||||
'gm/cvd_api_funcs.c',
|
||||
'gm/cvd_api_funcs.h',
|
||||
'gm/cvd_funcs.c',
|
||||
'gm/cvd_funcs.h',
|
||||
'gm/gm_api_funcs.c',
|
||||
'gm/gm_api_funcs.h',
|
||||
'gm/gm_funcs.c',
|
||||
'gm/gm_funcs.h',
|
||||
'gm/mat_funcs.c',
|
||||
'gm/mat_funcs.h',
|
||||
'ToneMapGenerator/inc/ToneMapGenerator.h',
|
||||
'ToneMapGenerator/inc/ToneMapTypes.h',
|
||||
'ToneMapGenerator/src/inc/AGMGenerator.h',
|
||||
'ToneMapGenerator/src/inc/CSCGenerator.h',
|
||||
'ToneMapGenerator/src/src/AGMGenerator.c',
|
||||
'ToneMapGenerator/src/src/ToneMapGenerator.c',
|
||||
)
|
||||
|
||||
inc_amd_gm = include_directories(
|
||||
'gm',
|
||||
'ToneMapGenerator/inc',
|
||||
'ToneMapGenerator/src/inc',
|
||||
)
|
||||
|
||||
libgm = static_library(
|
||||
'libgm.a',
|
||||
gm_files,
|
||||
install : false,
|
||||
c_args : c_args_gm,
|
||||
include_directories : inc_amd_gm
|
||||
)
|
||||
78
src/amd/gmlib/tonemap_adaptor.c
Executable file
78
src/amd/gmlib/tonemap_adaptor.c
Executable file
|
|
@ -0,0 +1,78 @@
|
|||
/* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "ToneMapGenerator.h"
|
||||
#include "AGMGenerator.h"
|
||||
#include "tonemap_adaptor.h"
|
||||
|
||||
static void VPEFree3DLut(void* memToFree, void* pDevice)
|
||||
{
|
||||
free(memToFree);
|
||||
}
|
||||
|
||||
static void* VPEAlloc3DLut(unsigned int allocSize, void* pDevice)
|
||||
{
|
||||
return calloc(1, allocSize);
|
||||
}
|
||||
|
||||
void* tm_create(void)
|
||||
{
|
||||
struct ToneMapGenerator* p_tmGenerator = (struct ToneMapGenerator*)calloc(1, sizeof(struct ToneMapGenerator));
|
||||
if (!p_tmGenerator)
|
||||
return NULL;
|
||||
|
||||
p_tmGenerator->tmAlgo = TMG_A_AGM;
|
||||
p_tmGenerator->memAllocSet = false;
|
||||
p_tmGenerator->agmGenerator.initalized = false;
|
||||
|
||||
return (void*)p_tmGenerator;
|
||||
}
|
||||
|
||||
void tm_destroy(void** pp_tmGenerator)
|
||||
{
|
||||
struct ToneMapGenerator* p_tmGenerator;
|
||||
|
||||
if (!pp_tmGenerator || ((*pp_tmGenerator) == NULL))
|
||||
return;
|
||||
|
||||
p_tmGenerator = *pp_tmGenerator;
|
||||
AGMGenerator_Exit(&p_tmGenerator->agmGenerator);
|
||||
|
||||
free(p_tmGenerator);
|
||||
*pp_tmGenerator = NULL;
|
||||
}
|
||||
|
||||
int tm_generate3DLut(struct tonemap_param* pInparam, void* pformattedLutData)
|
||||
{
|
||||
enum TMGReturnCode result;
|
||||
struct ToneMappingParameters tmParams;
|
||||
|
||||
tmParams.lutData = (uint16_t *)pformattedLutData;
|
||||
|
||||
ToneMapGenerator_SetInternalAllocators(
|
||||
(struct ToneMapGenerator*)pInparam->tm_handle,
|
||||
(TMGAlloc)(VPEAlloc3DLut),
|
||||
(TMGFree)(VPEFree3DLut),
|
||||
(void*)(NULL));
|
||||
|
||||
result = ToneMapGenerator_GenerateToneMappingParameters(
|
||||
(struct ToneMapGenerator*)pInparam->tm_handle,
|
||||
&pInparam->streamMetaData,
|
||||
&pInparam->dstMetaData,
|
||||
pInparam->inputContainerGamma,
|
||||
pInparam->outputContainerGamma,
|
||||
pInparam->outputContainerPrimaries,
|
||||
pInparam->lutDim,
|
||||
&tmParams
|
||||
);
|
||||
|
||||
return (int)result;
|
||||
}
|
||||
33
src/amd/gmlib/tonemap_adaptor.h
Executable file
33
src/amd/gmlib/tonemap_adaptor.h
Executable file
|
|
@ -0,0 +1,33 @@
|
|||
/* Copyright 2025 Advanced Micro Devices, Inc.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ToneMapGenerator/inc/ToneMapTypes.h"
|
||||
|
||||
struct tonemap_param
|
||||
{
|
||||
void* tm_handle;
|
||||
struct ToneMapHdrMetaData streamMetaData;
|
||||
struct ToneMapHdrMetaData dstMetaData;
|
||||
enum ToneMapTransferFunction inputContainerGamma;
|
||||
enum ToneMapTransferFunction outputContainerGamma;
|
||||
enum ToneMapColorPrimaries outputContainerPrimaries;
|
||||
unsigned short lutDim;
|
||||
};
|
||||
|
||||
void* tm_create(void);
|
||||
void tm_destroy(void** pp_tmGenerator);
|
||||
int tm_generate3DLut(struct tonemap_param* pInparam, void* pformattedLutData);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -27,4 +27,5 @@ endif
|
|||
|
||||
if with_gallium_radeonsi
|
||||
subdir('vpelib')
|
||||
subdir('gmlib')
|
||||
endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue