/**
 * @brief       PGP Manager (CSC Preset)
 * @author      AXELL CORPORATION
 * @description PGP Manager Layer.
 * @note        none
 * @history     2017_02_22  初版
 * @history     2017_10_26  Ver2.0
*/
/* DOM-IGNORE-BEGIN */
/*
 * This program was created by AXELL CORPORATION.
 * Copyright (C) 2017 AXELL CORPORATION, all rights reserved.
 */
/* DOM-IGNORE-END */

#include "pgp/pgpmgr.h"

/* 色空間変換プリセットのリミット */
static const uint32_t pgp_csc_limit[8] = {
    AG903_PGP_MGR_LIMIT_0_255,
    AG903_PGP_MGR_LIMIT_0_255,
    AG903_PGP_MGR_LIMIT_16_235_AND_240,
    AG903_PGP_MGR_LIMIT_16_235_AND_240,
    AG903_PGP_MGR_LIMIT_0_255,
    AG903_PGP_MGR_LIMIT_0_255,
    AG903_PGP_MGR_LIMIT_16_235_AND_240,
    AG903_PGP_MGR_LIMIT_16_235_AND_240,
};

/* 色空間変換プリセットのシフト */
static const uint32_t pgp_csc_shift[8] = {
    9,
    9,
    9,
    9,
    9,
    9,
    9,
    9,
};

/* 色空間変換プリセットのマトリックス */
static const float pgp_csc_mtx[8][12] = {
    /* AG903_PGP_MGR_CSC_YUV_BT_601_FULL_TO_RGB */
    {   0.0f,  1.772f,  1.000f, -226.816f,
     -0.714f, -0.344f,  1.000f,  135.424f,
      1.402f,    0.0f,  1.000f, -179.456f},
    /* AG903_PGP_MGR_CSC_RGB_TO_YUV_BT_601_FULL */
    {-0.081f,  -0.419f,    0.5f, 128.0f,
      0.500f,  -0.331f, -0.169f, 128.0f,
      0.114f,   0.587f,  0.299f,   0.0f},
    /* AG903_PGP_MGR_CSC_YUV_BT_601_LIMIT_TO_RGB */
    {   0.0f,  2.017f, 1.164f, -276.800f,
     -0.813f, -0.392f, 1.164f,  135.616f,
      1.596f,    0.0f, 1.164f, -222.912f},
    /* AG903_PGP_MGR_CSC_RGB_TO_YUV_BT_601_LIMIT */
    {-0.071f, -0.368f,  0.439f, 128.0f,
      0.439f, -0.291f, -0.148f, 128.0f,
      0.098f,  0.504f,  0.257f,  16.0f},
    /* AG903_PGP_MGR_CSC_YUV_BT_709_FULL_TO_RGB */
    {   0.0f,  1.856f, 1.000f, -237.568f,
     -0.468f, -0.187f, 1.000f,   83.840f,
      1.575f,    0.0f, 1.000f, -201.600f},
    /* AG903_PGP_MGR_CSC_RGB_TO_YUV_BT_709_FULL */
    {-0.046f, -0.454f,  0.500f, 128.0f,
      0.500f, -0.385f, -0.115f, 128.0f,
      0.072f,  0.715f,  0.213f,   0.0f},
    /* AG903_PGP_MGR_CSC_YUV_BT_709_LIMIT_TO_RGB */
    {   0.0f,  2.112f, 1.164f, -288.960f,
     -0.533f, -0.213f, 1.164f,   76.864f,
      1.793f,    0.0f, 1.164f, -248.128f},
    /* AG903_PGP_MGR_CSC_RGB_TO_YUV_BT_709_LIMIT */
    {-0.040f, -0.399f,  0.439f, 128.0f,
      0.439f, -0.339f, -0.101f, 128.0f,
      0.062f,  0.614f,  0.183f,  16.0f},
};

#define CSC_FP2INT(f, s)  ((int32_t)((f) * (0x1 << (s))))

/* 色空間係数のマスク値 */
#define CSC_MUL_MASK        0xFFF
#define CSC_ADD_MASK        0xFFFFF

/**
 * @brief   色空間変換のプリセットの値を取得します。
 * @param   format [in] プリセットのフォーマットを取得します。
 * @param   limit [out] 出力時のリミット値を格納するポインタを指定します。
 * @param   shift [out] 出力時の右シフト量の値を格納するポインタを指定します。
 * @param   mtx [out] 色空間変換係数を格納するポインタを指定します。
 * @return  none
 * @note    本関数はAG903_PgpMgrSetConfigPresetColorSpace関数から呼び出されることを前堤とし不正な入力値が指定されることは想定していません。<p>
 *          本関数はユーザー側が直接使用することはありません。
*/
void PgpMgrGetPresetColorSpaceParameter(uint32_t format, uint32_t *limit, uint32_t *shift, int32_t *mtx)
{
    int32_t i;

    *limit = pgp_csc_limit[format];
    *shift = pgp_csc_shift[format];
    for (i = 0; i < 3; i++) {
        mtx[i * 4 + 0] = CSC_FP2INT(pgp_csc_mtx[format][i * 4 + 0], pgp_csc_shift[format]) & CSC_MUL_MASK;
        mtx[i * 4 + 1] = CSC_FP2INT(pgp_csc_mtx[format][i * 4 + 1], pgp_csc_shift[format]) & CSC_MUL_MASK;
        mtx[i * 4 + 2] = CSC_FP2INT(pgp_csc_mtx[format][i * 4 + 2], pgp_csc_shift[format]) & CSC_MUL_MASK;
        mtx[i * 4 + 3] = CSC_FP2INT(pgp_csc_mtx[format][i * 4 + 3], pgp_csc_shift[format]) & CSC_ADD_MASK;
    }
}
