/**
 * @brief       PGP Manager
 * @author      AXELL CORPORATION
 * @description PGP Manager Layer.
 * @note        none
 * @history     2017_02_22  初版
 * @history     2017_10_26  Ver2.0
 * @history     2018_01_24  [SDK2.1] 画像前処理の制限項目によるエラーチェックと説明文の追加 (#1773)
 * @history     2018_01_24  [SDK2.1] パイプライン入力ポートに指定するデジタルビデオ入力ポートハンドルの型に誤り (#1757)
 * @history     2019_12_27  [SDK3.0] PGPのラベリング解析関数が確保したリソースを解放する関数を追加 (#1951)
 * @history     2024_03_22  [SDK3.6] PGPのソースがVIDであることを確認するときの型キャストの不具合を修正 (#4940)
*/
/* DOM-IGNORE-BEGIN */
/*
 * This program was created by AXELL CORPORATION.
 * Copyright (C) 2017-2024 AXELL CORPORATION, all rights reserved.
 */
/* DOM-IGNORE-END */

#include <stdio.h>
#include "pgpmgr_common.h"
#include "pgp/pgpprm.h"
#include "via/viamgr.h"
#include "vid/vidmgr.h"

/* 前処理のコンテキスト
   ハンドルの初期化はハンドル取得時に行ないます。*/
static PgpMgrContext PgpContext = {
#ifdef AG903_PGP_MGR_TS_FORCE_DISABLE
               false,
#else
               true,
#endif /* AG903_PGP_MGR_TS_FORCE_DISABLE */
               false, 0,
               0, {{0}},
               0, {{0}},
               0, {{0}},
               0, {{0}},
               {NULL}, {NULL}, {NULL}, {NULL},
               {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL}, {NULL},
               {0},
};

/*
 * @brief   Manager Layerのコンテキスト情報取得します。Manager Layer内部で使用する関数です。
 * @param   none
 * @return  コンテキストのポインタ
 * @note    本関数はユーザー側が直接使用することはありません。
*/
PgpMgrContext *PgpGetContext(void)
{
    return &PgpContext;
}


/* 色空間係数のマスク値 */
#define CSC_MUL_MASK        0xFFF
#define CSC_ADD_MASK        0xFFFFF
/* 空間フィルタのマスク値 */
#define SPF1_COEFF_MASK     0xFF
#define SPF1_OFFSET_MASK    0x1FF
/* 閾値処理のマスク生成パラメータの有効ビットのマスク値 */
#define THR_MSK_L_MASK      0x1
#define THR_MSK_H_MASK      0x1
#define THR_MSK_X_MASK      0x1
#define THR_MSK_HMAX_MASK   0xFF
#define THR_MSK_HMIN_MASK   0xFF
#define THR_MSK_LMAX_MASK   0xFF
#define THR_MSK_LMIN_MASK   0xFF
/* 閾値処理の8bit閾値処理パラメータの有効ビットのマスク値 */
#define THR_8THR_MAXV_MASK  0xFF
#define THR_8THR_MAXTH_MASK 0xFF
#define THR_8THR_MINTH_MASK 0xFF
/* 閾値処理の1bit空間フィルタパラメータの有効ビットのマスク値 */
#define THR_SPF1_COEFF_MASK 0x1
#define THR_SPF1_THR_MASK   0x3F
/* フレーム間演算におけるゲインの有効ビットのマスク値 */
#define IFC_GAIN_MASK       0xFF

#ifndef AG903_PGP_MGR_TS_FORCE_DISABLE

/**
 * @brief         前処理の時分割動作の有効無効指定
 * @param         enable [in] 時分割動作の有効無効を指定します。
 * @return        指定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL 既にパイプラインハンドルが取得された状態で有効無効を切り替えた場合
 * @description   パイプラインの時分割動作の有効/無効を設定します。
 * @note          全てのパイプラインハンドル、VRAM入力ハンドルが解放された状態で実行してください。<p>
 *                実行中の場合、AG903_PGP_MGR_TS_FORCE_DISABLE が設定されている場合は設定しません。 <p>
 *                現時点では、無効(AG903_PGP_MGR_TS_FORCE_DISABLE)で使用して下さい。
*/
int32_t AG903_PgpMgrEnableTimeSharingPipeline(_Bool enable)
{
    if ((PgpContext.num_pipeline_handles != 0) ||
        (PgpContext.num_vram_input_handles != 0) ||
        (PgpContext.num_frame_calc_handles != 0) ||
        (PgpContext.num_dgc_lut != 0)) {
        return -AG903_EINVAL;
    }

    PgpContext.pipeline_time_sharing_enable = enable;

    return AG903_ENONE;
}
#endif /* AG903_PGP_MGR_TS_FORCE_DISABLE */


/**
 * @brief         指定数のパイプラインハンドル取得
 * @param         num [in] 取得するパイプラインハンドルの数を指定します。
 * @param         handles [out] 取得したパイプラインハンドルを格納するポインタを指定します。
 * @return        取得結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL numに指定した数と、取得済のパイプラインハンドル数の合計値が最大ハンドル数を超える場合<p>handlesにNULLが指定された場合
 * @description   パイプラインハンドルを取得します。
 * @note          none
*/
int32_t AG903_PgpMgrGetPipelineHandle(int32_t num, AG903_PgpMgrPipelineHandle **handles)
{
    int i, j;

    /* 時分割動作有効、無効により取得可能な最大ハンドル数は異ります */
    if (PgpContext.pipeline_time_sharing_enable == true) {
        if ((num + PgpContext.num_pipeline_handles) > AG903_PGP_MGR_MAX_PIPELINE_HANDLE) {
            return -AG903_EINVAL;
        }
    } else {
        if ((num + PgpContext.num_pipeline_handles) > AG903_PGP_MGR_PIPELINE_NUM) {
            return -AG903_EINVAL;
        }
    }

    if (handles == NULL) {
        return -AG903_EINVAL;
    }

    /* 使用可能なパイプラインハンドルを検索し、handlesに格納します */
    for (i = 0; i < num; i++) {
        for (j = 0; j < AG903_PGP_MGR_MAX_PIPELINE_HANDLE; j++) {
            if (PgpContext.pipeline_handles[j].is_used == false) {
                /* ハンドルの設定値を初期化します。 */
                PgpMgrInitPipelineHandle(&PgpContext.pipeline_handles[j]);

                PgpContext.pipeline_handles[j].is_used = true;
                PgpContext.pipeline_handles[j].id = AG903_PGP_MGR_PIPELINE_HANDLE_ID;
                handles[i] = &PgpContext.pipeline_handles[j];
                break;
            }
        }
    }

    /* パイプラインハンドルが0から変化するタイミングで割り込みハンドラの設定を行ないます */
    if (PgpContext.num_pipeline_handles == 0) {
        PgpMgrSetIntr();
    }
    PgpContext.num_pipeline_handles += num;
    return AG903_ENONE;
}


/**
 * @brief         パイプラインハンドルの解放
 * @param         handle [in] 解放するパイプラインハンドルを指定します。
 * @return        解放結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>指定されたパイプラインハンドルが現在実行中の場合
 * @description   指定されたパイプラインハンドルを解放します。
 * @note          none
*/
int32_t AG903_PgpMgrReleasePipelineHandle(AG903_PgpMgrPipelineHandle *handle)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }
    /* パイプラインハンドルがフレーム間演算のマスタ、スレーブに指定されている場合はエラーとします */
    if (handle->is_used_frame_calc == true) {
        return -AG903_EINVAL;
    }

    /* パイプラインの割り当てが行なわれている場合に以下の処理を行ないます */
    if (handle->pipeline_no != -1) {
        /* パイプラインハンドルが使用中での場合はエラーとします */
        if (PgpContext.exec_pipeline[handle->pipeline_no] == handle) {
            PGPPrmParamPGPnSTATE state;
            AG903_PgpPrmGetPGPnSTATE(handle->pipeline_no, &state);
            if (state.st != AG903_PGP_MGR_STATE_IDLE) {
                return -AG903_EBUSY;
            }
            PgpContext.exec_pipeline[handle->pipeline_no] = NULL;
        }
        if (PgpContext.assign_pipeline[handle->pipeline_no] == handle) {
            PgpContext.assign_pipeline[handle->pipeline_no] = NULL;
        }
    }
    if (handle->input_handle != NULL) {
        AG903_PgpMgrVRAMInputHandle *vram_handle = (AG903_PgpMgrVRAMInputHandle *)handle->input_handle;
        /* 入力ソースがVRAM入力の場合にリファレンスカウントをデクリメントします */
        if (vram_handle->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID) {
            vram_handle->ref_cnt--;
            /* 時分割動作無効かつ、リファレンスカウントが0かつ、VRAM入力が割り当て済の場合は割り当てを解放します */
            if (PgpContext.pipeline_time_sharing_enable == false) {
                if ((vram_handle->ref_cnt == 0) && (vram_handle->port_no != -1)) {
                    if (PgpContext.assign_vram[vram_handle->port_no] == vram_handle) {
                        PgpContext.assign_vram[vram_handle->port_no] = NULL;
                    }
                }
            }
        }
    }
    /* 濃度変換テーブルが関連付けされている場合、濃度変換テーブルのリファレンスカウントをデクリメントします */
    if (handle->dgc_lut != NULL) {
        handle->dgc_lut->ref_cnt--;
    }
    handle->is_used = false;
    handle->id = 0;
    PgpContext.num_pipeline_handles--;

    /* パイプラインハンドルが全て破棄されたタイミングで割り込みハンドラの設定をリセットします */
    if (PgpContext.num_pipeline_handles == 0) {
        PgpMgrResetIntr();
    }
    return AG903_ENONE;
}


/**
 * @brief         パイプラインハンドルまたはフレーム間演算ハンドルを物理的なパイプラインに割り当て
 * @param         handle [in] 割り当てを行なうパイプラインハンドルまたはフレーム間演算ハンドルを指定します。
 * @return        パイプライン番号、もしくはエラー
 * @retval        パイプライン番号 割り当て成功時
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>割り当てに失敗した場合<p>入力ソースが未設定のハンドルが指定された場合
 * @description   指定されたパイプラインハンドル、またはフレーム間演算ハンドルの設定値を確認して実行可能なパイプラインを割り当てます。 <p>
 *                パイプラインの割り当ては、「レーム保存パイプライン」 > 「入力画像処理パイプライン」 >
 *                「演算処理パイプライン」の順に行われます。<p>
 *                詳しくは「PGPパイプライン番号」を参照してください。<p>
 *                入力ソースがVRAMの場合は、VRAM入力の割り当ても行います。<p>VRAMのポートは2本ありますので、空いているポートをアサインします。<p>
 *                指定されたハンドルがフレーム間演算ハンドルの場合、マスタ/スレーブで処理が異なります。<p>
 *                マスタ : 通常のパイプライン割り当てを行います。<p>
 *                スレーブ : 必ず演算処理パイプラインを割り当てます。<p>
 *                また、スレーブがVRAM入力の場合は、マスタ側のパイプラインハンドルの割り当てにより決定されます。
 * @note          時分割動作無効時は同じ物理パイプラインに対して複数のハンドルを割り当てることは出来ません。
*/
int32_t AG903_PgpMgrAssignPipeline(void *handle)
{
    uint32_t id;

    if (handle == NULL) {
        return -AG903_EINVAL;
    }

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    id = ((AG903_PgpMgrPipelineHandle *)handle)->id;
    if ((id != AG903_PGP_MGR_PIPELINE_HANDLE_ID) && (id != AG903_PGP_MGR_FRAME_CALC_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    if (id == AG903_PGP_MGR_PIPELINE_HANDLE_ID) {
        AG903_PgpMgrPipelineHandle *p = (AG903_PgpMgrPipelineHandle *)handle;
        /* 既に割り当て済の場合は処理を終えます */
        if (p->is_assign == true) {
            return -AG903_EINVAL;
        }
        /* 入力ソースが未設定の場合エラーとします */
        if (p->input_handle == NULL) {
            return -AG903_EINVAL;
        }
        /* パイプラインハンドルの割り当てを行ないます */
        return PgpMgrAssignPipelineHandle(p);
    } else {
        AG903_PgpMgrFrameCalcHandle *f = (AG903_PgpMgrFrameCalcHandle *)handle;
        /* 既に割り当て済の場合は処理を終えます(割り当てはマスタ、スレーブ同時に行なわれるためマスタ側で確認します) */
        if (f->master_handle->is_assign == true) {
            return -AG903_EINVAL;
        }
        /* マスタ側パイプラインハンドルの入力ソースが未設定の場合エラーとします */
        if (f->master_handle->input_handle == NULL) {
            return -AG903_EINVAL;
        }
        /* スレーブ側がパイプラインハンドルの場合、入力ソースが未設定の場合エラーとします */
        if (f->slave_pipeline == true) {
            AG903_PgpMgrPipelineHandle *slave = (AG903_PgpMgrPipelineHandle *)f->slave_handle;
            if (slave->input_handle == NULL) {
                return -AG903_EINVAL;
            }
        }
        /* フレーム間演算ハンドルの割り当てを行ないます */
        return PgpMgrAssignFrameCalcHandle(f);
    }
}


/**
 * @brief         パイプラインハンドルまたはフレーム間演算ハンドルを指定したパイプラインに強制割り当て
 * @param         handle [in] 割り当てを行なうパイプラインハンドルまたはフレーム間演算ハンドルを指定します。
 * @param         pipeline [in] 割り当て先の PGPパイプライン番号 を指定します。
 * @return        PGPパイプライン番号、もしくはエラー
 * @retval        PGPパイプライン番号 割り当て成功時
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>割り当てに失敗した場合<p>入力ソースが未設定のハンドルが指定された場合<p>pipelineに不正な値が指定された場合
 * @description   指定されたパイプラインに対してパイプラインハンドル、またはフレーム間演算ハンドルを強制的に割り当てます。
 * @note          指定したパイプラインに他のハンドルが割り当て済の場合は割り当て失敗と判定されます。<p>
 *                パイプラインハンドルの設定が割り当て先のパイプラインで実行可能であるかのチェックは行ないません。<p>
 *                あらかじめ AG903_PgpMgrCheckFunctionValidation 関数にて実行可能であるかチェックして下さい。
*/
int32_t AG903_PgpMgrForceAssignPipeline(void *handle, uint32_t pipeline)
{
    uint32_t id;

    if (handle == NULL) {
        return -AG903_EINVAL;
    }
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    id = ((AG903_PgpMgrPipelineHandle *)handle)->id;
    if ((id != AG903_PGP_MGR_PIPELINE_HANDLE_ID) && (id != AG903_PGP_MGR_FRAME_CALC_HANDLE_ID)) {
        return -AG903_EINVAL;
    }
    switch (pipeline) {
        case AG903_PGP_MGR_CALC_PIPELINE0:
        case AG903_PGP_MGR_CALC_PIPELINE1:
        case AG903_PGP_MGR_INPUT_PIPELINE0:
        case AG903_PGP_MGR_INPUT_PIPELINE1:
        case AG903_PGP_MGR_FRAME_PIPELINE0:
        case AG903_PGP_MGR_FRAME_PIPELINE1:
            break;
        default:
            return -AG903_EINVAL;
    }

    if (id == AG903_PGP_MGR_PIPELINE_HANDLE_ID) {
        AG903_PgpMgrPipelineHandle *p = (AG903_PgpMgrPipelineHandle *)handle;
        /* 既に割り当て済の場合は処理を終えます */
        if (p->is_assign == true) {
            return -AG903_EINVAL;
        }
        /* 入力ソースが未設定の場合エラーとします */
        if (p->input_handle == NULL) {
            return -AG903_EINVAL;
        }
        /* フレーム間演算ハンドルとして使用されている場合エラーとします */
        if (p->is_used_frame_calc == true) {
            return -AG903_EINVAL;
        }
        /* パイプラインハンドルの割り当てを行ないます */
        return PgpMgrForceAssignPipelineHandle(p, pipeline);
    } else {
        AG903_PgpMgrFrameCalcHandle *f = (AG903_PgpMgrFrameCalcHandle *)handle;
        /* 既に割り当て済の場合は処理を終えます(割り当てはマスタ、スレーブ同時に行なわれるためマスタ側で確認します) */
        if (f->master_handle->is_assign == true) {
            return -AG903_EINVAL;
        }
        /* マスタ側パイプラインハンドルの入力ソースが未設定の場合エラーとします */
        if (f->master_handle->input_handle == NULL) {
            return -AG903_EINVAL;
        }
        /* スレーブ側がパイプラインハンドルの場合、入力ソースが未設定の場合エラーとします */
        if (f->slave_pipeline == true) {
            AG903_PgpMgrPipelineHandle *slave = (AG903_PgpMgrPipelineHandle *)f->slave_handle;
            if (slave->input_handle == NULL) {
                return -AG903_EINVAL;
            }
        }
        /* フレーム間演算ハンドルの割り当てを行ないます */
        return PgpMgrForceAssignFrameCalcHandle(f, pipeline);
    }
}


/**
 * @brief         パイプラインハンドルの物理パイプラインに対する割り当て解放
 * @param         handle [in]  割り当てを解除するパイプラインハンドルまたはフレーム間演算ハンドルを指定します。
 * @return        解放結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>割り当て前のハンドルが指定された場合<p>指定されたパイプラインハンドルが現在実行中の場合
 * @description   指定したパイプラインハンドル、またはフレーム間演算ハンドルの物理パイプラインの割り当てを解放します。
 * @note          指定したパイプラインハンドルの入力ソースの設定も解除されます。<p>
 *                再度割り当てを行なう場合 AG903_PgpMgrSetInputPort 関数で入力ソースを指定して下さい。
*/
int32_t AG903_PgpMgrReleaseAssignment(void *handle)
{
    uint32_t id;
    AG903_PgpMgrVRAMInputHandle *vram_handle;

    if (handle == NULL) {
        return -AG903_EINVAL;
    }
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    id = ((AG903_PgpMgrPipelineHandle *)handle)->id;
    if ((id != AG903_PGP_MGR_PIPELINE_HANDLE_ID) && (id != AG903_PGP_MGR_FRAME_CALC_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    if (id == AG903_PGP_MGR_PIPELINE_HANDLE_ID) {
        AG903_PgpMgrPipelineHandle *p = (AG903_PgpMgrPipelineHandle *)handle;
        /* 割り当て前の場合はエラーとします */
        if (p->is_assign == false) {
            return -AG903_EINVAL;
        }
        if (PgpContext.exec_pipeline[p->pipeline_no] == p) {
            /* 現在実行中の場合はエラーとします */
            PGPPrmParamPGPnSTATE state;
            AG903_PgpPrmGetPGPnSTATE(p->pipeline_no, &state);
            if (state.st != AG903_PGP_MGR_STATE_IDLE) {
                return -AG903_EBUSY;
            }
            PgpContext.exec_pipeline[p->pipeline_no] = NULL;
        }
        /* 割り当て解除の状態に設定します */
        if (PgpContext.assign_pipeline[p->pipeline_no] == handle) {
            PgpContext.assign_pipeline[p->pipeline_no] = NULL;
        }
        /* 入力ソースがVRAM入力の場合にリファレンスカウントをデクリメントします */
        vram_handle = (AG903_PgpMgrVRAMInputHandle *)p->input_handle;
        if ((vram_handle != NULL) && (vram_handle->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
            vram_handle->ref_cnt--;
        }
        p->is_assign = false;
        p->pipeline_no = -1;
        p->input_handle = NULL;
    } else {
        AG903_PgpMgrFrameCalcHandle *f = (AG903_PgpMgrFrameCalcHandle *)handle;
        AG903_PgpMgrPipelineHandle *master = (AG903_PgpMgrPipelineHandle *)f->master_handle;
        AG903_PgpMgrPipelineHandle *slave = (AG903_PgpMgrPipelineHandle *)f->slave_handle;
        /* 割り当て前の場合はエラーとします(割り当てはマスタ、スレーブ同時に行なわれるためマスタ側で確認します) */
        if (master->is_assign == false) {
            return -AG903_EINVAL;
        }
        if (PgpContext.exec_pipeline[master->pipeline_no] == master) {
            /* 現在実行中の場合はエラーとします */
            PGPPrmParamPGPnSTATE state;
            AG903_PgpPrmGetPGPnSTATE(master->pipeline_no, &state);
            if (state.st != AG903_PGP_MGR_STATE_IDLE) {
                return -AG903_EBUSY;
            }
            PgpContext.exec_pipeline[master->pipeline_no] = NULL;
        }
        /* 割り当て解除の状態に設定します */
        if (PgpContext.assign_pipeline[master->pipeline_no] == master) {
            PgpContext.assign_pipeline[master->pipeline_no] = NULL;
        }
        /* 入力ソースがVRAM入力の場合にリファレンスカウントをデクリメントします */
        vram_handle = (AG903_PgpMgrVRAMInputHandle *)master->input_handle;
        if ((vram_handle != NULL) && (vram_handle->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
            vram_handle->ref_cnt--;
        }
        master->is_assign = false;
        master->pipeline_no = -1;
        master->input_handle = NULL;
        /* スレーブ側がパイプラインハンドルの場合、スレーブ側の割り当ても解除します */
        if (slave->id == AG903_PGP_MGR_PIPELINE_HANDLE_ID) {
            if (PgpContext.assign_pipeline[slave->pipeline_no] == slave) {
                PgpContext.assign_pipeline[slave->pipeline_no] = NULL;
            }
            if (PgpContext.exec_pipeline[slave->pipeline_no] == slave) {
                PgpContext.exec_pipeline[slave->pipeline_no] = NULL;
            }
            /* 入力ソースがVRAM入力の場合にリファレンスカウントをデクリメントします */
            vram_handle = (AG903_PgpMgrVRAMInputHandle *)slave->input_handle;
            if ((vram_handle != NULL) && (vram_handle->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
               vram_handle->ref_cnt--;
            }
            slave->is_assign = false;
            slave->pipeline_no = -1;
            slave->input_handle = NULL;
        }
    }

    return AG903_ENONE;
}


/**
 * @brief         パイプラインハンドルが指定した物理パイプラインへの割り当て可否チェック
 * @param         handle [in] チェックするパイプラインハンドルを指定します。
 * @param         pipeline [in] 割り当て先の PGPパイプライン番号 を指定します。
 * @return        チェック結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>割り当て不可能な場合<p>pipelineに不正な値が指定された場合
 * @description   指定されたパイプラインハンドルが、指定された物理パイプラインで処理可能かどうかチェックします。
*/
int32_t AG903_PgpMgrCheckFunctionValidation(AG903_PgpMgrPipelineHandle *handle, uint32_t pipeline)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (pipeline) {
        case AG903_PGP_MGR_CALC_PIPELINE0:
        case AG903_PGP_MGR_CALC_PIPELINE1:
        case AG903_PGP_MGR_INPUT_PIPELINE0:
        case AG903_PGP_MGR_INPUT_PIPELINE1:
        case AG903_PGP_MGR_FRAME_PIPELINE0:
        case AG903_PGP_MGR_FRAME_PIPELINE1:
            break;
        default:
            return -AG903_EINVAL;
    }

    return PgpMgrCheckAssignPipelineHandle(handle, pipeline);
}


/**
 * @brief         パイプラインの実行制御
 * @param         handle [in] 実行するパイプラインハンドルまたはフレーム間演算ハンドルを指定します。
 * @param         cmd [in] PGPパイプラインコマンド を指定します。
 * @return        実行結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>cmdに不正な値が指定された場合<p>パイプラインが物理的なパイプラインに割り当てられていない場合
 * @retval        -AG903_EBUSY 他のパイプラインハンドルが実行するパイプラインで現在処理中の場合<p>パイプラインのコマンドキューに空きが無い場合、コマンドを受けつける状態では無い場合
 * @description   パイプラインの実行制御を行います。 <p>
 *                以下のエラーチェックが問題無い場合、実行します。<p>
 *                ・割り当てが行われていないパイプラインハンドルが指定されているかどうか<p>
 *                ・フレーム間演算ハンドルの場合は、マスタ側のパイプラインハンドルとスレーブ側パイプラインハンドルが共に割り当てられているか<p>
 *                ・実行するパイプラインが現在処理中かどうか<p>
 *                ・1ショットコマンドの場合、パイプラインのコマンドキューに空きがあるかどうか
 * @note          入力ソースがVRAM入力の場合、本関数実行後に AG903_PgpMgrExecVRAMInput 関数を実行してください。<p>
 *                ヒストグラムを使用する場合、本関数実行前に AG903_PgpMgrExecHistogram 関数を実行してください。<p>
 *                ラベリングを使用する場合、本関数実行前に AG903_PgpMgrExecLabeling 関数を実行してください。
*/
int32_t AG903_PgpMgrExecPipeline(void *handle, uint32_t cmd)
{
    uint32_t id;

    if (handle == NULL) {
        return -AG903_EINVAL;
    }

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    id = ((AG903_PgpMgrPipelineHandle *)handle)->id;
    if ((id != AG903_PGP_MGR_PIPELINE_HANDLE_ID) && (id != AG903_PGP_MGR_FRAME_CALC_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    switch (cmd) {
        case AG903_PGP_MGR_CMD_NONE:
        case AG903_PGP_MGR_CMD_EXEC:
        case AG903_PGP_MGR_CMD_EXEC_CONTINUE:
        case AG903_PGP_MGR_CMD_TRIG:
        case AG903_PGP_MGR_CMD_TRIG_CONTINUE:
        case AG903_PGP_MGR_CMD_IDLE:
        case AG903_PGP_MGR_CMD_RESET_TIMESTAMP_CNT:
        case AG903_PGP_MGR_CMD_RESET_FRAME_CNT:
        case AG903_PGP_MGR_CMD_RESET_INTR_CNT:
        case AG903_PGP_MGR_CMD_FORCE_QUIT:
            break;
        default:
            return -AG903_EINVAL;
    }

    if (id == AG903_PGP_MGR_PIPELINE_HANDLE_ID) {
        AG903_PgpMgrPipelineHandle *p = (AG903_PgpMgrPipelineHandle *)handle;
        /* 割り当て前の場合はエラーとします */
        if (p->is_assign == false) {
            return -AG903_EINVAL;
        }
        /* パイプラインを実行します */
        return PgpMgrExecPipelineHandle(p, cmd);
    } else {
        AG903_PgpMgrFrameCalcHandle *f = (AG903_PgpMgrFrameCalcHandle *)handle;
        AG903_PgpMgrPipelineHandle *master = (AG903_PgpMgrPipelineHandle *)f->master_handle;
        /* 割り当て前の場合はエラーとします(割り当てはマスタ、スレーブ同時に行なわれるためマスタ側で確認します) */
        if (master->is_assign == false) {
            return -AG903_EINVAL;
        }
        /* パイプラインを実行します */
        return PgpMgrExecFrameCalcHandle(f, cmd);
    }
}


/**
 * @brief         割り込みのコールバック関数登録
 * @param         handle [in] 割り込み登録するパイプラインハンドルを指定します。
 * @param         type [in] 「PGP割り込み種別」を指定します。
 * @param         func [in] コールバック関数を指定します。
 * @return        登録結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>typeに不正な値が指定された場合
 * @description   パイプラインの実行結果を受けるためのコールバック関数を登録します。<p>
 *                また、func=NULL を指定することでコールバック関数の削除も行います。
*/
int32_t AG903_PgpMgrSetIntrCallbackFunc(AG903_PgpMgrPipelineHandle *handle, uint32_t type, void (*func)(int32_t id, void *handle))
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    switch (type) {
        case AG903_PGP_MGR_INTR_INPUT:
            handle->intr_vsynci_enable = (func == NULL) ? false : true;
            handle->intr_input_func = func;
            break;
        case AG903_PGP_MGR_INTR_OUTPUT:
            handle->intr_vsynco_enable = (func == NULL) ? false : true;
            handle->intr_output_func = func;
            break;
        case AG903_PGP_MGR_INTR_DONE:
            handle->intr_vsynco_enable = (func == NULL) ? false : true;
            handle->intr_done_func = func;
            break;
        case AG903_PGP_MGR_INTR_VRAM_ERROR:
            handle->intr_voicpl_enable = handle->intr_vooflw_enable = (func == NULL) ? false : true;
            handle->intr_vram_error_func = func;
            break;
        case AG903_PGP_MGR_INTR_LBL_ERROR:
            handle->intr_lblcrpt_enable = (func == NULL) ? false : true;
            handle->intr_lbl_error_func = func;
            break;
        case AG903_PGP_MGR_INTR_HGM_ERROR:
            handle->intr_hgmicpl_enable = (func == NULL) ? false : true;
            handle->intr_hgm_error_func = func;
            break;
        case AG903_PGP_MGR_INTR_ND:
            handle->intr_nd_enable = (func == NULL) ? false : true;
            handle->intr_nd_func = func;
            break;
        case AG903_PGP_MGR_INTR_IFC_OVF:
            handle->intr_ifcofs_enable = handle->intr_ifcofm_enable = (func == NULL) ? false : true;
            handle->intr_ifc_ovf_func = func;
            break;
        case AG903_PGP_MGR_INTR_INPUT_LINE:
            handle->intr_vlinei_enable = (func == NULL) ? false : true;
            handle->intr_input_line_func = func;
            break;
        case AG903_PGP_MGR_INTR_OUTPUT_LINE:
            handle->intr_vlineo_enable = (func == NULL) ? false : true;
            handle->intr_output_line_func = func;
            break;
        case AG903_PGP_MGR_INTR_LBL_DONE:
            handle->intr_lblcpl_enable = (func == NULL) ? false : true;
            handle->intr_lbl_done_func = func;
            break;
        case AG903_PGP_MGR_INTR_HGM_DONE:
            handle->intr_hgmcpl_enable = (func == NULL) ? false : true;
            handle->intr_hgm_done_func = func;
            break;
        default:
            return -AG903_EINVAL;
    }

    handle->is_dirty = true;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_INTR_ENABLE] = true;
    return AG903_ENONE;
}


/**
 * @brief         パイプラインの入出力割り込み設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         input_field [in] 入力割り込みにおけるVSYNC割り込みを出力するフィールド「PGP発生フィールド」を指定します。
 * @param         input_fcnt [in] 入力割り込みにおけるフレームカウンタの最大値を指定します。
 * @param         input_line [in] 入力割り込みにおけるライン割り込み発生のライン番号を指定します。
 * @param         output_field [in] 出力割り込みにおけるVSYNC割り込みを出力するフィールド「PGP発生フィールド」を指定します。
 * @param         output_fcnt [in] 出力割り込みにおけるフレームカウンタの最大値を指定します。
 * @param         output_line [in] 出力割り込みにおけるライン割り込み発生のライン番号を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL
 *                handleに不正な値が指定された場合<p>input_fieldに不正な値が指定された場合<p>input_fcntに不正な値が指定された場合<p>
 *                input_lineに不正な値が指定された場合<p>output_fieldに不正な値が指定された場合<p>output_fcntに不正な値が指定された場合<p>output_lineに不正な値が指定された場合
 * @description   パイプラインの入出力割込みの条件設定を行います。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>指定可能範囲</th></tr>
 *                <tr><td>input_field</td><td>PGP発生フィールド</td></tr>
 *                <tr><td>input_fcnt</td><td>1 ~ AG903_PGP_MGR_INTR_CTRL_MAX_FRAME_CNT</td></tr>
 *                <tr><td>input_line</td><td>1 ~ AG903_PGP_MGR_INTR_CTRL_MAX_INPUT_LINE</td></tr>
 *                <tr><td>output_field</td><td>PGP発生フィールド</td></tr>
 *                <tr><td>output_fcnt</td><td>1 ~ AG903_PGP_MGR_INTR_CTRL_MAX_FRAME_CNT</td></tr>
 *                <tr><td>output_line</td><td>1 ~ AG903_PGP_MGR_INTR_CTRL_MAX_OUTPUT_LINE</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigIntrCtrl(AG903_PgpMgrPipelineHandle *handle, uint32_t input_field, uint32_t input_fcnt, uint32_t input_line, uint32_t output_field, uint32_t output_fcnt, uint32_t output_line)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (input_field) {
        case AG903_PGP_MGR_INTR_CTRL_FIELD_ODD:
        case AG903_PGP_MGR_INTR_CTRL_FIELD_EVEN:
        case AG903_PGP_MGR_INTR_CTRL_FIELD_ODD_EVEN:
            break;
        default:
            return -AG903_EINVAL;
    }
    if ((input_fcnt == 0) || (input_fcnt > AG903_PGP_MGR_INTR_CTRL_MAX_FRAME_CNT)) {
        return -AG903_EINVAL;
    }
    if (input_line > AG903_PGP_MGR_INTR_CTRL_MAX_INPUT_LINE) {
        return -AG903_EINVAL;
    }
    switch (output_field) {
        case AG903_PGP_MGR_INTR_CTRL_FIELD_ODD:
        case AG903_PGP_MGR_INTR_CTRL_FIELD_EVEN:
        case AG903_PGP_MGR_INTR_CTRL_FIELD_ODD_EVEN:
            break;
        default:
            return -AG903_EINVAL;
    }
    if ((output_fcnt == 0) || (output_fcnt > AG903_PGP_MGR_INTR_CTRL_MAX_FRAME_CNT)) {
        return -AG903_EINVAL;
    }
    if (output_line > AG903_PGP_MGR_INTR_CTRL_MAX_OUTPUT_LINE) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->input_intr_field = input_field;
    handle->input_intr_fcnt = input_fcnt;
    handle->input_intr_line = input_line;
    handle->output_intr_field = output_field;
    handle->output_intr_fcnt = output_fcnt;
    handle->output_intr_line = output_line;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_INTR_CTRL] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         パイプラインのステータス取得
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         blank [out] VBLANK の入力値を格納するポインタを指定します。
 * @param         is_vram_out [out] VRAM 出力中であることを示すフラグを格納するポインタを指定します。
 * @param         queue_cnt [out] キューに溜めたコマンド数を格納するポインタを指定します。
 * @param         sub_status [out] パイプラインのサブステータスを格納するポインタを指定します。
 * @param         status [out] パイプラインの現在実行中コマンドを格納するポインタを指定します。
 * @return        取得結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>パイプラインが物理的に割り当てられていない場合<p>割り当て先の物理パイプラインが他のパイプラインハンドルによって使用されている場合
 * @description   パイプラインのステータスを取得します。<p>
 *                詳しくは「PGPステータス」を参照してください。
 * @note          NULL が指定された引数に対してステータス値の取得は行ないません。
*/
int32_t AG903_PgpMgrGetPipelineStatus(AG903_PgpMgrPipelineHandle *handle, uint32_t *blank, _Bool *is_vram_out, uint32_t *queue_cnt, uint32_t *sub_status, uint32_t *status)
{
    PGPPrmParamPGPnSTATE state;

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }
    /* パイプラインの割り当てが完了していない場合はエラーとします */
    if (handle->is_assign != true) {
        return -AG903_EINVAL;
    }

    /* Primitive Layerから値をリードします ※リードした値はAG903_PGP_MGR_STATE_IDLE等と同じ値を指します */
    AG903_PgpPrmGetPGPnSTATE(handle->pipeline_no, &state);

    /* 割り当て先の物理パイプラインが他のパイプラインハンドルに使用されている場合はエラーとします */
    if ((PgpContext.exec_pipeline[handle->pipeline_no] != handle) && (state.st != AG903_PGP_MGR_STATE_IDLE)) {
        return -AG903_EINVAL;
    }
    /* NULL以外の引数のみ値を格納します */
    if (blank != NULL) {
        *blank = state.blank;
    }
    if (is_vram_out != NULL) {
        *is_vram_out = state.vrmacc;
    }
    if (queue_cnt != NULL) {
        *queue_cnt = state.queue;
    }
    if (sub_status != NULL) {
        *sub_status = state.sst;
    }
    if (status != NULL) {
        *status = state.st;
    }
    return AG903_ENONE;
}


/**
 * @brief         ビデオ入力、フレーム出力トリガの有効/無効設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         vlinei_enable [in] ビデオ入力のライントリガの有効/無効を指定します。
 * @param         vsynci_enable [in] ビデオ入力の垂直同期トリガの有効/無効を指定します。
 * @param         vlineo_enable [in] フレーム出力のライントリガの有効/無効を指定します。
 * @param         vsynco_enable [in] フレーム出力の垂直同期トリガの有効/無効を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   ビデオ入力、フレーム出力トリガの有効/無効の設定を行います。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrEnableParamTrigCtrl(AG903_PgpMgrPipelineHandle *handle, _Bool vlinei_enable, _Bool vsynci_enable, _Bool vlineo_enable, _Bool vsynco_enable)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->trig_vlinei_enable = vlinei_enable;
    handle->trig_vsynci_enable = vsynci_enable;
    handle->trig_vlineo_enable = vlineo_enable;
    handle->trig_vsynco_enable = vsynco_enable;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         ビデオ入力、フレーム出力トリガ設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         input_field [in] ビデオ入力トリガにおけるVSYNCトリガを出力するフィールドを指定します。
 * @param         input_fcnt [in] ビデオ入力トリガにおけるフレームカウンタの最大値を指定します。
 * @param         input_line [in] ビデオ入力トリガにおけるライン割り込み発生のライン番号を指定します。
 * @param         output_field [in] フレーム出力トリガにおけるVSYNCトリガを出力するフィールドを指定します。
 * @param         output_fcnt [in] フレーム出力トリガにおけるフレームカウンタの最大値を指定します。
 * @param         output_line [in] フレーム出力トリガにおけるライン割り込み発生のライン番号を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>
 *                input_fieldに不正な値が指定された場合<p>input_fcntに不正な値が指定された場合<p>input_lineに不正な値が指定された場合<p>
 *                output_fieldに不正な値が指定された場合<p>output_fcntに不正な値が指定された場合<p>output_lineに不正な値が指定された場合
 * @description   ビデオ入力、フレーム出力トリガの条件設定を行います。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>指定可能範囲</th></tr>
 *                <tr><td>input_field</td><td>PGPトリガ</td></tr>
 *                <tr><td>input_fcnt</td><td>1 ~ AG903_PGP_MGR_TRIG_CTRL_MAX_FRAME_CNT</td></tr>
 *                <tr><td>input_line</td><td>1 ~ AG903_PGP_MGR_TRIG_CTRL_MAX_INPUT_LINE</td></tr>
 *                <tr><td>output_field</td><td>PGPトリガ</td></tr>
 *                <tr><td>output_fcnt</td><td>1 ~ AG903_PGP_MGR_TRIG_CTRL_MAX_FRAME_CNT</td></tr>
 *                <tr><td>output_line</td><td>1 ~ AG903_PGP_MGR_TRIG_CTRL_MAX_OUTPUT_LINE</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigTrigCtrl(AG903_PgpMgrPipelineHandle *handle, uint32_t input_field, uint32_t input_fcnt, uint32_t input_line, uint32_t output_field, uint32_t output_fcnt, uint32_t output_line)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (input_field) {
        case AG903_PGP_MGR_TRIG_CTRL_FIELD_ODD:
        case AG903_PGP_MGR_TRIG_CTRL_FIELD_EVEN:
        case AG903_PGP_MGR_TRIG_CTRL_FIELD_ODD_EVEN:
            break;
        default:
            return -AG903_EINVAL;
    }
    if ((input_fcnt == 0) || (input_fcnt > AG903_PGP_MGR_TRIG_CTRL_MAX_FRAME_CNT)) {
        return -AG903_EINVAL;
    }
    if (input_line > AG903_PGP_MGR_TRIG_CTRL_MAX_INPUT_LINE) {
        return -AG903_EINVAL;
    }
    switch (output_field) {
        case AG903_PGP_MGR_TRIG_CTRL_FIELD_ODD:
        case AG903_PGP_MGR_TRIG_CTRL_FIELD_EVEN:
        case AG903_PGP_MGR_TRIG_CTRL_FIELD_ODD_EVEN:
            break;
        default:
            return -AG903_EINVAL;
    }
    if ((output_fcnt == 0) || (output_fcnt > AG903_PGP_MGR_TRIG_CTRL_MAX_FRAME_CNT)) {
        return -AG903_EINVAL;
    }
    if (output_line > AG903_PGP_MGR_TRIG_CTRL_MAX_OUTPUT_LINE) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->input_trig_field = input_field;
    handle->input_trig_fcnt = input_fcnt;
    handle->input_trig_line = input_line;
    handle->output_trig_field = output_field;
    handle->output_trig_fcnt = output_fcnt;
    handle->output_trig_line = output_line;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_TRIG_CTRL] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         キャプチャ入力のHSYNCに対する遅延設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         h_delay [in] キャプチャ入力のHSYNCの遅延を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>h_delayに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   キャプチャ入力の　HSYNC に対する遅延を設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>指定可能範囲</th></tr>
 *                <tr><td>h_delay</td><td>0 ~ AG903_PGP_MGR_MAX_INPUT_HSYNC_DELAY</td></tr>
 *                </table>
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamInputHSyncDelay(AG903_PgpMgrPipelineHandle *handle, uint32_t h_delay)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if (h_delay > AG903_PGP_MGR_MAX_INPUT_HSYNC_DELAY) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->input_hsync_delay = h_delay;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         キャプチャ入力の動作モード設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         md [in] キャプチャ入力の動作モードを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>mdに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   キャプチャ入力の動作モードを設定します。<p>
 *                詳しくは「PGPキャプチャ動作モード」を参照してください。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamInputMode(AG903_PgpMgrPipelineHandle *handle, uint32_t md)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (md) {
        case AG903_PGP_MGR_INPUT_MD_VSYNC:
        case AG903_PGP_MGR_INPUT_MD_ODD_VSYNC:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->input_mode = md;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         キャプチャ入力のタイプスタンプ生成に使用するクロックソース設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         tick [in] キャプチャ入力のタイプスタンプ生成に使用するクロックソースを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>tickに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   キャプチャ入力のタイムスタンプ生成に使用するクロックソースを設定します。<p>
 *                詳しくは「PGPタイムスタンプ生成クロック」を参照してください。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamInputTimeCLK(AG903_PgpMgrPipelineHandle *handle, uint32_t tick)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (tick) {
        case AG903_PGP_MGR_INPUT_TIME_CLK0:
        case AG903_PGP_MGR_INPUT_TIME_CLK1:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->input_timer_clk = tick;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         トリガ起動のタイマモジュールのチャンネル番号設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         timer_ch [in] タイマモジュールのチャンネル番号を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>timer_chに不正な値が指定された場合
 * @description   トリガ起動のタイマモジュールのチャンネル番号を設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>指定可能範囲</th></tr>
 *                <tr><td>timer_ch</td><td>0 ~ AG903_PGP_MGR_MAX_TRIG_TIMER_CHANNEL</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigInputTrigChannel(AG903_PgpMgrPipelineHandle *handle, uint32_t timer_ch)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if (timer_ch > AG903_PGP_MGR_MAX_TRIG_TIMER_CHANNEL) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->input_trig_timer_ch = timer_ch;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_INPUT_TRIG_CH] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         パイプラインの入力ポート設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         src [in] 入力ハンドルを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>srcに不正なハンドルが指定された場合
 * @description   パイプラインの入力ポートを指定します。<p>
 *                入力ハンドルが何のハンドルかは、ポインタの先頭4Byteで識別します。<p>
 *                指定可能なハンドルは以下の通りです。
 *                <table>
 *                <tr><th>ハンドル名</th><th>型</th></tr>
 *                <tr><td>アナログビデオ入力ハンドル</td><td>AG903_ViaMgrInputHandle</td></tr>
 *                <tr><td>デジタルビデオ入力ハンドル</td><td>AG903_VidMgrInputHandle</td></tr>
 *                <tr><td>VRAM入力ハンドル</td><td>AG903_PgpMgrVRAMInputHandle</td></tr>
 *                </table>
 * @note          src=NULL の場合、現在設定されている入力ポートの設定を解除します。
*/
int32_t AG903_PgpMgrSetInputPort(AG903_PgpMgrPipelineHandle *handle, void *src)
{
    const uint32_t via_port[4] = {
        AG903_PGP_MGR_INPUT_PORT_VIA_0,
        AG903_PGP_MGR_INPUT_PORT_VIA_1,
        AG903_PGP_MGR_INPUT_PORT_VIA_2,
        AG903_PGP_MGR_INPUT_PORT_VIA_3,
    };
    const uint32_t vid_port[4] = {
        AG903_PGP_MGR_INPUT_PORT_VID_0,
        AG903_PGP_MGR_INPUT_PORT_VID_1,
        AG903_PGP_MGR_INPUT_PORT_VID_2,
        AG903_PGP_MGR_INPUT_PORT_VID_3,
    };

    AG903_ViaMgrInputHandle *via_h = (AG903_ViaMgrInputHandle *)src;
	AG903_VidMgrOutputHandle *vid_h = (AG903_VidMgrOutputHandle *)src;
    AG903_PgpMgrVRAMInputHandle *vram_h = (AG903_PgpMgrVRAMInputHandle *)src;

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    if (src != NULL) {
        if (via_h->id == AG903_VIA_MGR_INPUT_HANDLE_ID) {
            handle->input_port = via_port[via_h->port_no];
        } else if (vid_h->id == AG903_VID_MGR_OUTPUT_HANDLE_ID) {
            handle->input_port = vid_port[vid_h->port_no];
        } else if (vram_h->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID) {
            /* VRAM入力の場合はポートの割り当てが完了していないケースがあるため、input_portへの設定は割り当て時に行ないます */
            vram_h->ref_cnt++;
        } else {
            return -AG903_EINVAL;
        }
    }

    /* 既に他のVRAM入力ハンドルが入力ポートに設定されている場合は、そのVRAM入力ハンドルのリファレンスカウントデクリメントします */
    vram_h = (AG903_PgpMgrVRAMInputHandle *)handle->input_handle;
    if ((vram_h != NULL) && (vram_h->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        vram_h->ref_cnt--;
    }

    /* 入力ハンドルを保持します */
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_INPUT_TRIG_CH] = true;
    handle->input_handle = src;
    return AG903_ENONE;
}


/**
 * @brief         パイプラインの入力フォーマット設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         format [in] 入力フォーマットを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>formatに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプラインの入力フォーマットを設定します。<p>
 *                詳しくは「PGP入力フォーマット」を参照してください。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamInputFormat(AG903_PgpMgrPipelineHandle *handle, uint32_t format)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (format) {
        case AG903_PGP_MGR_INPUT_FMT_RGB888:
        case AG903_PGP_MGR_INPUT_FMT_RGB565:
        case AG903_PGP_MGR_INPUT_FMT_YCBCR444:
        case AG903_PGP_MGR_INPUT_FMT_YCBCR422_WO_IP:
        case AG903_PGP_MGR_INPUT_FMT_YCBCR422_W_IP:
        case AG903_PGP_MGR_INPUT_FMT_CLUT8:
        case AG903_PGP_MGR_INPUT_FMT_CLUT1:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->input_format = format;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         パイプラインのキャプチャサイズ設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         vsize [in] キャプチャ垂直サイズを指定します。
 * @param         hsize [in] キャプチャ水平サイズを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>vsizeに不正な値が指定された場合<p>hsizeに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプラインのキャプチャサイズを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>vsize</td><td>1 ~ AG903_PGP_MGR_MAX_INPUT_SIZE</td></tr>
 *                <tr><td>hsize</td><td>1 ~ AG903_PGP_MGR_MAX_INPUT_SIZE</td></tr>
 *                </table>
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamInputSize(AG903_PgpMgrPipelineHandle *handle, uint32_t vsize, uint32_t hsize)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if ((vsize == 0) || (vsize > AG903_PGP_MGR_MAX_INPUT_SIZE)) {
        return -AG903_EINVAL;
    }
    if ((hsize == 0) || (hsize > AG903_PGP_MGR_MAX_INPUT_SIZE)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->input_vsize = vsize;
    handle->input_hsize = hsize;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         パイプラインのキャプチャ開始座標設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         vpos [in] キャプチャ開始座標垂直位置を指定します。
 * @param         hpos [in] キャプチャ開始座標水平位置を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>vposに不正な値が指定された場合<p>hposに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプラインのキャプチャ開始座標を設定します。
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>vpos</td><td>0 ~ AG903_PGP_MGR_MAX_INPUT_POS</td></tr>
 *                <tr><td>hpos</td><td>0 ~ AG903_PGP_MGR_MAX_INPUT_POS</td></tr>
 *                </table>
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamInputPosition(AG903_PgpMgrPipelineHandle *handle, uint32_t vpos, uint32_t hpos)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if (vpos > AG903_PGP_MGR_MAX_INPUT_POS) {
        return -AG903_EINVAL;
    }
    if (hpos > AG903_PGP_MGR_MAX_INPUT_POS) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->input_vpos = vpos;
    handle->input_hpos = hpos;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         パイプラインのキャプチャ時のフレーム走査方法設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         scan [in] フレーム走査方法を指定します。
 * @param         epos [in] インタレースモードでのEVENフレームのvpos調整の有効/無効を指定します。
 * @param         opos [in] インタレースモードでのODDフレームのvpos調整の有効/無効を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>scanに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプラインのキャプチャ時のフレーム走査パラメータを設定します。<p>
 *                詳しくは、「PGPフレーム走査方法」を参照してください。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamInputScan(AG903_PgpMgrPipelineHandle *handle, uint32_t scan, _Bool epos, _Bool opos)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (scan) {
        case AG903_PGP_MGR_SCAN_PROGRESSIVE:
        case AG903_PGP_MGR_SCAN_INTERLACE:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->input_scan = scan;
    handle->input_epos = epos;
    handle->input_opos = opos;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         フレーム保存時のパディング値設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         pad [in] フレーム保存のパディング値を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>padに不正な値が指定された場合
 * @description   パイプラインのフレーム保存時のパディング値を設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>vpos</td><td>0 ~ AG903_PGP_MGR_MAX_OUTPUT_PAD</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigOutputFramePadding(AG903_PgpMgrPipelineHandle *handle, uint32_t pad)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if (pad > AG903_PGP_MGR_MAX_OUTPUT_PAD) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->output_pad = pad;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_OUTPUT_CTRL] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         24bit入力値のリミット動作設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         limit [in] 24bit入力のリミット動作を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>limitに不正な値が指定された場合
 * @description   パイプラインの 24bit 入力値のリミット動作を設定します。<p>
 *                詳しくは、「PGPリミット」を参照して下さい。<p>
 *                このうち limit では、 AG903_PGP_MGR_LIMIT_0_255 / AG903_PGP_MGR_LIMIT_16_235_AND_240 の指定が可能です。
*/
int32_t AG903_PgpMgrSetConfigOutputLimit(AG903_PgpMgrPipelineHandle *handle, uint32_t limit)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (limit) {
        case AG903_PGP_MGR_LIMIT_0_255:
        case AG903_PGP_MGR_LIMIT_16_235_AND_240:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->output_limit = limit;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_OUTPUT_CTRL] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         フレーム付加情報出力の有効/無効設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         enable [in] フレーム付加情報出力の有効無効フラグを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @description   パイプラインのフレーム付加情報出力の有効/無効を設定します。
*/
int32_t AG903_PgpMgrEnableConfigOutputFrameInfo(AG903_PgpMgrPipelineHandle *handle, _Bool enable)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->output_fai_enable = enable;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_OUTPUT_CTRL] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         減色処理時のディザリングの有効/無効設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         enable [in] 減色処理時のディザリングの有効無効フラグを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @description   パイプラインの減色処理時のディザリングの有効/無効を設定します。
*/
int32_t AG903_PgpMgrEnableConfigOutputDither(AG903_PgpMgrPipelineHandle *handle, _Bool enable)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->output_dither_enable = enable;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_OUTPUT_CTRL] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         パイプライン出力時のフレーム走査方法設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         scan [in] フレーム捜査方法を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>scanに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプライン出力時のフレーム走査方法のパラメータを設定します。<p>
 *                詳しくは、「PGPフレーム走査方法」を参照してください。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamOutputScan(AG903_PgpMgrPipelineHandle *handle, uint32_t scan)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (scan) {
        case AG903_PGP_MGR_SCAN_PROGRESSIVE:
        case AG903_PGP_MGR_SCAN_INTERLACE:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->output_scan = scan;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         パイプライン出力時のアドレス指定方法設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         dim [in] アドレス指定方法を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>dimに不正な値が指定された場合
 * @description   パイプライン出力時のアドレス指定方法のパラメータを設定します。<p>
 *                詳しくは、「PGPアドレス指定方法」を参照してください。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamOutputAddrDim(AG903_PgpMgrPipelineHandle *handle, uint32_t dim)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (dim) {
        case AG903_PGP_MGR_ADDR_DIMENTION_1:
        case AG903_PGP_MGR_ADDR_DIMENTION_2:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->output_dim = dim;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         パイプライン出力時のデータスワップ設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         word [in] ワードデータのスワップの有効/無効フラグを指定します。
 * @param         hword [in] ハーフワードデータのスワップの有効/無効フラグを指定します。
 * @param         four_bit [in] 4bitデータのスワップの有効/無効フラグを指定します。
 * @param         ont_bit [in] 1bitデータのスワップの有効/無効フラグを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @description   パイプライン出力時のデータスワップを設定します。
*/
int32_t AG903_PgpMgrSetConfigOutputDataSwap(AG903_PgpMgrPipelineHandle *handle, _Bool word, _Bool hword, _Bool four_bit, _Bool one_bit)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->output_word_swap_enable = word;
    handle->output_hword_swap_enable = hword;
    handle->output_4bit_swap_enable = four_bit;
    handle->output_1bit_swap_enable = one_bit;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_OUTPUT_CTRL] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         インタレース入力のフレーム保存方法設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         frame_save [in] インタレース入力のフレーム保存方法を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>frame_saveに不正な値が指定された場合
 * @description   インタレース入力のフレーム保存方法を設定します。<p>
 *                詳しくは、「PGPフレーム保存方法」を参照してください。
*/
int32_t AG903_PgpMgrSetConfigOutputInterlaceFrame(AG903_PgpMgrPipelineHandle *handle, uint32_t frame_save)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (frame_save) {
        case AG903_PGP_MGR_OUTPUT_FRAME_SAVE_ODD:
        case AG903_PGP_MGR_OUTPUT_FRAME_SAVE_EVEN:
        case AG903_PGP_MGR_OUTPUT_FRAME_SAVE_IGNORE_FIELD:
        case AG903_PGP_MGR_OUTPUT_FRAME_SAVE_FIELD:
        case AG903_PGP_MGR_OUTPUT_FRAME_SAVE_WEAVE:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->output_md = frame_save;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_OUTPUT_CTRL] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         バッファ管理ユニット設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         bmu [in] バッファ管理ユニットを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>bmuに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   バッファ管理ユニットを設定します。<p>
 *                フレーム操作方法をプログレッシブ、またはインターレス入力のフレーム保存で奇数フレームのみ、
 *                もしくは偶数フレームのみを指定した場合、AG903_PGP_MGR_OUTPUT_BMU_ENABLE_EVENは指定できません。<p>
 *                詳しくは、「PGPBMU設定」を参照してください。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamOutputBMU(AG903_PgpMgrPipelineHandle *handle, uint32_t bmu)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (bmu) {
        case AG903_PGP_MGR_OUTPUT_BMU_NONE:
        case AG903_PGP_MGR_OUTPUT_BMU_ENABLE:
        case AG903_PGP_MGR_OUTPUT_BMU_ENABLE_EVEN:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->output_bmu = bmu;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         パイプライン出力時のフォーマット設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         format [in] 出力フォーマットを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>formatに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプライン出力時のフォーマットを設定します。<p>
 *                詳しくは、「PGP出力フォーマット」を参照してください。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamOutputFormat(AG903_PgpMgrPipelineHandle *handle, uint32_t format)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (format) {
        case AG903_PGP_MGR_OUTPUT_FMT_RGB888_TO_RGB888_32BIT:
        case AG903_PGP_MGR_OUTPUT_FMT_RGB888_TO_RGB888_24BIT:
        case AG903_PGP_MGR_OUTPUT_FMT_RGB888_TO_RGB565:
        case AG903_PGP_MGR_OUTPUT_FMT_RGB888_TO_ARGB1555:
        case AG903_PGP_MGR_OUTPUT_FMT_RGB888_TO_ARGB4444:
        case AG903_PGP_MGR_OUTPUT_FMT_RGB888_TO_RGB888_SEP:
        case AG903_PGP_MGR_OUTPUT_FMT_YCBCR444_TO_YCBCR444_32BIT:
        case AG903_PGP_MGR_OUTPUT_FMT_YCBCR444_TO_YCBCR444_24BIT:
        case AG903_PGP_MGR_OUTPUT_FMT_YCBCR444_TO_YCBCR422:
        case AG903_PGP_MGR_OUTPUT_FMT_YCBCR444_TO_YCBCR444_SEP:
        case AG903_PGP_MGR_OUTPUT_FMT_CLUT8_TO_CLUT8:
        case AG903_PGP_MGR_OUTPUT_FMT_CLUT1_TO_CLUT1:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->output_format = format;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         RGB分離出力によるパイプライン出力時のカラーマスク設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         red [in] Red要素の有効/無効フラグを指定します。(1:出力する、0:出力しない)
 * @param         green [in] Green要素の有効/無効フラグを指定します。(1:出力する、0:出力しない)
 * @param         blue [in] Blue要素の有効/無効フラグを指定します。(1:出力する、0:出力しない)
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>red,green,blueの全ての要素で無効が指定された場合
 * @description   パイプライン出力時のカラーマスクを設定します。<p>
 *                Red,Green,Blue全ての要素の無効は禁止です。
*/
int32_t AG903_PgpMgrEnableConfigOutputColorMask(AG903_PgpMgrPipelineHandle *handle, _Bool red, _Bool green, _Bool blue)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID) || ((red == false) && (green == false) && (blue == false))) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->output_red_enable = red;
    handle->output_green_enable = green;
    handle->output_blue_enable = blue;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_OUTPUT_COLOR_MASK] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         パイプラインの出力先ベースアドレス設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         addr [in] 出力先ベースアドレスをポインタで指定します。(8バイトアライン必要)
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>addrにNULLが指定された場合
 * @description   パイプラインの出力先ベースアドレスを設定します。
*/
int32_t AG903_PgpMgrSetConfigOutputBaseAddr(AG903_PgpMgrPipelineHandle *handle, void *addr)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if (addr == NULL) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->output_base_addr = (uint32_t)addr;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_OUTPUT_BASE_ADDR] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         パイプラインの出力先が2次元の場合のストライドバイト設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         stride [in] 2次元で出力する場合のストライドバイトを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>strideに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプラインの出力先が2次元の場合、ストライドバイトを設定します。<p>
 *                出力フォーマットがYCbCr422の時、ストライドバイトは偶数に設定してください。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>stride</td><td>1 ~ AG903_PGP_MGR_OUTPUT_MAX_STRIDE_BYTE</td></tr>
 *                </table>
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamOutputStride(AG903_PgpMgrPipelineHandle *handle, uint32_t stride)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if ((stride == 0) || (stride > AG903_PGP_MGR_OUTPUT_MAX_STRIDE_BYTE)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->output_vram_stride = stride;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         パイプラインのフレーム付加情報の値取得
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         tmstmp [out] タイムスタンプ用内部カウンタの値を保持するポインタを指定します。
 * @param         field [out] 入力フィールドの値を保持するポインタを指定します。
 * @param         port [out] ポート番号の値を保持するポインタを指定します。
 * @param         fnum [out] フレーム番号の内部カウンタの値を保持するポインタを指定します。
 * @return        取得結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>パイプラインが物理的に割り当てられていない場合<p>割り当て先の物理パイプラインが他のパイプラインハンドルで使用されている場合
 * @description   パイプラインのフレーム付加情報の値を取得します。<p>
 *                引数とレジスタの対応は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>対象レジスタ</th></tr>
 *                <tr><td>tmstmp</td><td>AG903_PGPn_FAIVAL0 の TMSTMPフィールド</td></tr>
 *                <tr><td>field</td><td>AG903_PGPn_FAIVAL1 の FIELDフィールド</td></tr>
 *                <tr><td>port</td><td>AG903_PGPn_FAIVAL1 の PORTフィールド</td></tr>
 *                <tr><td>fnum</td><td>AG903_PGPn_FAIVAL1 の FNUMフィールド</td></tr>
 *                </table>
 * @note          引数=NULL の場合、当該引数のパラメータは取得しません。
*/
int32_t AG903_PgpMgrGetFrameInfo(AG903_PgpMgrPipelineHandle *handle, uint32_t *tmstmp, uint32_t *field, uint32_t *port, uint32_t *fnum)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられていない場合はエラーとします */
    if (handle->is_assign == false) {
        return -AG903_EINVAL;
    }
    /* 割り当て先の物理パイプラインが他のパイプラインハンドルに使用されている場合はエラーとします */
    if (PgpContext.exec_pipeline[handle->pipeline_no] != handle) {
        return -AG903_EINVAL;
    }

    /* Primitive Layerを通して値を取得します */
    if (tmstmp != NULL) {
        AG903_PgpPrmGetPGPnFAIVAL0(handle->pipeline_no, tmstmp);
    }
    if (field != NULL || port != NULL || fnum != NULL) {
        uint32_t tmp_field, tmp_port, tmp_fnum;
        AG903_PgpPrmGetPGPnFAIVAL1(handle->pipeline_no, &tmp_field, &tmp_port, &tmp_fnum);
        if (field != NULL) {
            *field = tmp_field;
        }
        if (port != NULL) {
            *port = tmp_port;
        }
        if (fnum != NULL) {
            *fnum = tmp_fnum;
        }
    }
    return AG903_ENONE;
}


/**
 * @brief         フレーム間演算とその他の演算の処理順序設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         order [in] 演算の処理順序を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>orderに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプライン機能のフレーム間演算とその他演算の処理順序を設定します。<p>
 *                詳しくは、「PGP演算順序」を参照してください。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamFrameCalcOrder(AG903_PgpMgrPipelineHandle *handle, uint32_t order)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (order) {
        case AG903_PGP_MGR_IFCODR_FRAME_TO_OTHER:
        case AG903_PGP_MGR_IFCODR_OTHER_TO_FRAME:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->ifc_order = order;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         閾値処理の有効/無効設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         enable [in] 閾値演算処理の有効/無効を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプライン機能の閾値処理の有効/無効を設定します。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrEnableParamThresholdOp(AG903_PgpMgrPipelineHandle *handle, _Bool enable)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->thr_enable = enable;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         濃度変換処理の有効/無効設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         enable [in] 濃度変換演算処理の有効/無効を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプライン機能の濃度変換の有効/無効を設定します。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrEnableParamDGC(AG903_PgpMgrPipelineHandle *handle, _Bool enable)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->dgc_enable = enable;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         HSV、HLS変換処理の有効/無効設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         enable [in] HSV、HLS変換処理の有効/無効を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプライン機能の HSV/HLS 変換の有効/無効を設定します。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrEnableParamHSV(AG903_PgpMgrPipelineHandle *handle, _Bool enable)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->hsv1_enable = enable;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         空間フィルタ処理の有効/無効設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         enable [in] 空間フィルタ処理の有効/無効を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された
 * @description   パイプライン機能の空間フィルタの有効/無効を設定します。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrEnableParamSpatialFilter(AG903_PgpMgrPipelineHandle *handle, _Bool enable)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->spf_enable = enable;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         スケーリング処理の有効/無効設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         enable [in] スケーリング処理の有効/無効を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプライン機能のスケーリングの有効/無効を設定します。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrEnableParamScaling(AG903_PgpMgrPipelineHandle *handle, _Bool enable)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->scale_enable = enable;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         色空間変換処理の有効/無効設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         enable [in] 色空間変換処理の有効/無効を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプライン機能の色空間変換の有効/無効を設定します。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrEnableParamColorSpace(AG903_PgpMgrPipelineHandle *handle, _Bool enable)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->csc1_enable = enable;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         3タップノイズフィルタ処理の有効/無効設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         enable [in] 3タップノイズフィルタ処理の有効無効を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプライン機能の 3タップノイズフィルタの有効/無効を設定します。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrEnableParamNRF(AG903_PgpMgrPipelineHandle *handle, _Bool enable)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->nrf_enable = enable;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         ヒストグラム処理の有効/無効設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         enable [in] ヒストグラム処理の有効/無効を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプライン機能のヒストグラム処理の有効/無効を設定します。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。<p>
 *                本関数の設定値はパイプラインの割り当て時にヒストグラム機能を使用するか判定するためのみに使用します。<p>
 *                実際にヒストグラム機能を使用する場合はヒストグラムの実行コマンドを発行する必要があります。
*/
int32_t AG903_PgpMgrEnableParamHistogram(AG903_PgpMgrPipelineHandle *handle, _Bool enable)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->hgm_enable = enable;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         ラベリング処理の有効/無効設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         enable [in] ラベリング処理の有効無効を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   パイプライン機能のラベリング処理の有効/無効を設定します。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。<p>
 *                本関数の設定値はパイプラインの割り当て時にラベリング機能を使用するか判定するためのみに使用します。<p>
 *                実際にラベリング機能を使用する場合はラベリングの実行コマンドを発行する必要があります。
*/
int32_t AG903_PgpMgrEnableParamLabeling(AG903_PgpMgrPipelineHandle *handle, _Bool enable)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->lbl_enable = enable;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         I/P変換回路のパラメータ設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         limit [in] 出力時のリミット動作を指定します。
 * @param         blky [in] ブランク期間のY出力値を指定します。
 * @param         blkc [in] ブランク期間のY出力値を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>
 *                limitに不正な値が指定された場合<p>blkyに不正な値が指定された場合<p>blkcに不正な値が指定された場合
 * @description   I/P変換回路のパラメータを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>limit</td><td>PGPリミット</td></tr>
 *                <tr><td>blky</td><td>0 ~ AG903_PGP_MGR_MAX_IP_BLANK</td></tr>
 *                <tr><td>blkc</td><td>0 ~ AG903_PGP_MGR_MAX_IP_BLANK</td></tr>
 *                </table>
 *                PGPリミット のうち、AG903_PGP_MGR_LIMIT_0_255 / AG903_PGP_MGR_LIMIT_16_235_AND_240 が指定可能です。
*/
int32_t AG903_PgpMgrSetConfigIPConversion(AG903_PgpMgrPipelineHandle *handle, uint32_t limit, uint32_t blky, uint32_t blkc)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (limit) {
        case AG903_PGP_MGR_LIMIT_0_255:
        case AG903_PGP_MGR_LIMIT_16_235_AND_240:
            break;
        default:
            return -AG903_EINVAL;
    }
    if (blky > AG903_PGP_MGR_MAX_IP_BLANK) {
        return -AG903_EINVAL;
    }
    if (blkc > AG903_PGP_MGR_MAX_IP_BLANK) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->ipc_limit = limit;
    handle->ipc_blk_y = blky;
    handle->ipc_blk_c = blkc;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_IP_CONV] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         色空間変換を制御するパラメータ設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         limit [in] 出力時のリミット動作を指定します。
 * @param         shift [in] 出力時の右シフト量を指定します。
 * @param         mtx [in] 色空間変換係数を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>limitに不正な値が指定された場合<p>shiftに不正な値が指定された場合<p>mtxにNULLが指定された場合
 * @description   色空間変換を制御するパラメータを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>limit</td><td>PGPリミット</td></tr>
 *                <tr><td>shift</td><td>0 ~ AG903_PGP_MGR_MAX_COLOR_SPACE_SHIFT</td></tr>
 *                <tr><td>mtx</td><td>3x4マトリクスの符号付き整数<p>加算要素:20bit<p>それ以外:12bit</td></tr>
 *                </table>
 *                PGPリミット のうち、AG903_PGP_MGR_LIMIT_0_255 / AG903_PGP_MGR_LIMIT_16_235_AND_240 が指定可能です。
 * @note          マトリクスの3x4の要素は下位12bitが有効となり、加算要素は下位19bitが有効となります。
*/
int32_t AG903_PgpMgrSetConfigColorSpace(AG903_PgpMgrPipelineHandle *handle, uint32_t limit, uint32_t shift, int32_t mtx[3][4])
{
    int32_t i;

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (limit) {
        case AG903_PGP_MGR_LIMIT_0_255:
        case AG903_PGP_MGR_LIMIT_16_235_AND_240:
            break;
        default:
            return -AG903_EINVAL;
    }
    if (shift > AG903_PGP_MGR_MAX_COLOR_SPACE_SHIFT) {
        return -AG903_EINVAL;
    }
    if (mtx == NULL) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->csc1_limit = limit;
    handle->csc1_shift = shift;
    for (i = 0; i < 3; i++) {
        handle->csc1_matrix[i][0] = mtx[i][0] & CSC_MUL_MASK;
        handle->csc1_matrix[i][1] = mtx[i][1] & CSC_MUL_MASK;
        handle->csc1_matrix[i][2] = mtx[i][2] & CSC_MUL_MASK;
        handle->csc1_matrix[i][3] = mtx[i][3] & CSC_ADD_MASK;
    }
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_COLOR_SPACE] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         色空間変換のプリセット設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         format [in] 色空間変換のプリセットを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>formatに不正な値が指定された場合
 * @description   色空間変換のプリセットを設定します。<p>
 *                詳しくは、「PGP色空間プリセット」を参照してください。
*/
int32_t AG903_PgpMgrSetConfigPresetColorSpace(AG903_PgpMgrPipelineHandle *handle, uint32_t format)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (format) {
        case AG903_PGP_MGR_CSC_YUV_BT_601_FULL_TO_RGB:
        case AG903_PGP_MGR_CSC_RGB_TO_YUV_BT_601_FULL:
        case AG903_PGP_MGR_CSC_YUV_BT_601_LIMIT_TO_RGB:
        case AG903_PGP_MGR_CSC_RGB_TO_YUV_BT_601_LIMIT:
        case AG903_PGP_MGR_CSC_YUV_BT_709_FULL_TO_RGB:
        case AG903_PGP_MGR_CSC_RGB_TO_YUV_BT_709_FULL:
        case AG903_PGP_MGR_CSC_YUV_BT_709_LIMIT_TO_RGB:
        case AG903_PGP_MGR_CSC_RGB_TO_YUV_BT_709_LIMIT:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    PgpMgrGetPresetColorSpaceParameter(format, &handle->csc1_limit, &handle->csc1_shift, &handle->csc1_matrix[0][0]);
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_COLOR_SPACE] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         スケーリングのパラメータ設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         limit [in] 出力時のリミット動作を指定します。
 * @param         filter [in] 縮小時のフィルタモードを指定します。
 * @param         nmr_v [in] 垂直方向縮小率の分子を指定します。
 * @param         dnm_v [in] 垂直方向縮小率の分母を指定します。
 * @param         nmr_h [in] 水平方向縮小率の分子を指定します。
 * @param         dnm_h [in] 水平方向縮小率の分母を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>
 *                limitに不正な値が指定された場合<p>nmr_vに不正な値が指定された場合<p>dnm_vに不正な値が指定された場合<p>nmr_hに不正な値が指定された場合<p>dnm_hに不正な値が指定された場合
 * @description   スケーリングのパラメータを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>limit</td><td>PGPリミット</td></tr>
 *                <tr><td>filter</td><td>PGP縮小フィルター</td></tr>
 *                <tr><td>nmr_v</td><td>1 ~ AG903_PGP_MGR_MAX_SCALING_VALUE</td></tr>
 *                <tr><td>dnm_v</td><td>1 ~ AG903_PGP_MGR_MAX_SCALING_VALUE</td></tr>
 *                <tr><td>nmr_h</td><td>1 ~ AG903_PGP_MGR_MAX_SCALING_VALUE</td></tr>
 *                <tr><td>dnm_h</td><td>1 ~ AG903_PGP_MGR_MAX_SCALING_VALUE</td></tr>
 *                </table>
 *                PGPリミット のうち、AG903_PGP_MGR_LIMIT_0_255 / AG903_PGP_MGR_LIMIT_16_235_AND_240 が指定可能です。
*/
int32_t AG903_PgpMgrSetConfigScaling(AG903_PgpMgrPipelineHandle *handle, uint32_t limit, uint32_t filter, uint32_t nmr_v, uint32_t dnm_v, uint32_t nmr_h, uint32_t dnm_h)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (limit) {
        case AG903_PGP_MGR_LIMIT_0_255:
        case AG903_PGP_MGR_LIMIT_16_235_AND_240:
            break;
        default:
            return -AG903_EINVAL;
    }
    switch (filter) {
        case AG903_PGP_MGR_FILTER_NEAREST:
        case AG903_PGP_MGR_FILTER_LINEAR:
            break;
        default:
            return -AG903_EINVAL;
    }
    if ((nmr_v == 0) || (nmr_v > AG903_PGP_MGR_MAX_SCALING_VALUE)) {
        return -AG903_EINVAL;
    }
    if ((dnm_v == 0) || (dnm_v > AG903_PGP_MGR_MAX_SCALING_VALUE)) {
        return -AG903_EINVAL;
    }
    if ((nmr_h == 0) || (nmr_h > AG903_PGP_MGR_MAX_SCALING_VALUE)) {
        return -AG903_EINVAL;
    }
    if ((dnm_h == 0) || (dnm_h > AG903_PGP_MGR_MAX_SCALING_VALUE)) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->scale_limit = limit;
    handle->scale_mtd = filter;
    handle->scale_v_nmr = nmr_v;
    handle->scale_v_dnm = dnm_v;
    handle->scale_h_nmr = nmr_h;
    handle->scale_h_dnm = dnm_h;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_SCALING] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}

/**
 * @brief         空間フィルタを制御するパラメータ設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         shift [in] 出力時の右シフト量を指定します。
 * @param         border [in] 境界値の処理方法を指定します。
 * @param         border_red [in] 境界値の固定カラー(赤)を指定します。
 * @param         border_green [in] 境界値の固定カラー(緑)を指定します。
 * @param         border_blue [in] 境界値の固定カラー(青)を指定します。
 * @param         coeff [in] 空間フィルタ係数を指定します。
 * @param         offset [in] 出力時の加算するオフセットを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>shiftに不正な値が指定された場合<p>borderに不正な値が指定された場合<p>coeffにNULLが指定された場合
 * @description   空間フィルタを制御するパラメータを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>shift</td><td>0 ~ AG903_PGP_MGR_MAX_SPF_SHIFT</td></tr>
 *                <tr><td>border</td><td>PGP境界値処理</td></tr>
 *                <tr><td>border_red</td><td>8bit で指定</td></tr>
 *                <tr><td>border_green</td><td>8bit で指定</td></tr>
 *                <tr><td>border_blue</td><td>8bit で指定</td></tr>
 *                <tr><td>coeff</td><td>符号付き整数 8bit で指定</td></tr>
 *                <tr><td>offset</td><td>符号付き整数 9bit で指定</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigSpatialFilter(AG903_PgpMgrPipelineHandle *handle, uint32_t shift, uint32_t border, uint32_t border_red, uint32_t border_green, uint32_t border_blue, int32_t coeff[9], int32_t offset)
{
    int32_t i;

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if (shift > AG903_PGP_MGR_MAX_SPF_SHIFT) {
        return -AG903_EINVAL;
    }
    switch (border) {
        case AG903_PGP_MGR_SPF_BORDER_COLOR:
        case AG903_PGP_MGR_SPF_BORDER_NEIGHBOR:
            break;
        default:
            return -AG903_EINVAL;
    }
    if (coeff == NULL) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->spf_shift = shift;
    handle->spf_border_sel = border;
    handle->spf_border_red = border_red;
    handle->spf_border_green = border_green;
    handle->spf_border_blue = border_blue;
    for (i = 0; i < 9; i++) {
        handle->spf_coeff[i] = coeff[i] & SPF1_COEFF_MASK;
    }
    handle->spf_offset = offset & SPF1_OFFSET_MASK;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_SP_FILTER] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         HSV、HLS変換回路の出力フォーマット設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         sel [in] HSV、HLSを選択します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>selに不正な値が指定された場合
 * @description   HSV、HLS変換回路の出力フォーマットを設定します。<p>
 *                詳しくは、「PGP変換回路」を参照してください。
*/
int32_t AG903_PgpMgrSetConfigHSVHLSConversion(AG903_PgpMgrPipelineHandle *handle, uint32_t sel)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (sel) {
        case AG903_PGP_MGR_CONVERT_HSV:
        case AG903_PGP_MGR_CONVERT_HLS:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->hsv_hls_sel = sel;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_HSVHSL_CONV] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}

/**
 * @brief         ヒストグラムの実行制御
 * @param         handle [in] ヒストグラムを実行するパイプラインハンドルを指定します。
 * @param         cmd [in] 実行コマンドを指定します。
 * @return        制御結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL
 *                handleに不正な値が指定された場合<p>cmdに不正な値が指定された場合<p>パイプラインハンドルが物理的なパイプラインに割り当てられていない場合
 * @retval        -AG903_EBUSY 他のパイプラインハンドルが実行するパイプラインで現在処理中の場合<p>コマンドがヒストグラム実行かつ、キューに空きが無い場合
 * @description   ヒストグラムの制御コマンドを発行します。<p>
 *                制御コマンドは、「PGPヒストグラム制御コマンド」を参照してください。
*/
int32_t AG903_PgpMgrExecHistogram(AG903_PgpMgrPipelineHandle *handle, uint32_t cmd)
{
    PGPPrmParamPGPnSTATE   state;
    PGPPrmParamPGPnHGMSTAT hgmstat;

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられていない場合はエラーとします */
    if (handle->is_assign == false) {
        return -AG903_EINVAL;
    }
    /* 実行先の物理パイプラインのステータスを取得 */
    AG903_PgpPrmGetPGPnSTATE(handle->pipeline_no, &state);
    /* 他のパイプラインハンドルが現在実行中の場合はエラー */
    if ((PgpContext.exec_pipeline[handle->pipeline_no] != handle ) && (state.st != AG903_PGP_MGR_STATE_IDLE)) {
        return -AG903_EBUSY;
    }
    AG903_PgpPrmGetPGPnHGMSTAT(handle->pipeline_no, &hgmstat);

    switch (cmd) {
        case AG903_PGP_MGR_HGM_CMD_EXEC:
        case AG903_PGP_MGR_HGM_CMD_EXEC_WO_VRAM:
            /* ヒストグラムのコマンドキューに空きがなければエラー */
            if ((hgmstat.queue == (AG903_PGP_MGR_HGM_CMD_MAX_QUEUE - 1)) || ((hgmstat.cmd != 0) && (cmd != hgmstat.cmd))) {
                return -AG903_EBUSY;
            }
            break;
        case AG903_PGP_MGR_HGM_CMD_NONE:
        case AG903_PGP_MGR_HGM_CMD_DELETE:
        case AG903_PGP_MGR_HGM_CMD_RESET:
            break;
        default:
            return -AG903_EINVAL;
    }


    /* Primitive Layerを通してヒストグラムのコマンドを発行 */
    AG903_PgpPrmSetPGPnHGMCMD(handle->pipeline_no, cmd);

    return AG903_ENONE;
}

/**
 * @brief         ヒストグラム制御のパラメータ設定
 * @param         handle [in] ヒストグラムを実行するパイプラインハンドルを指定します。
 * @param         inv [in] 出力無効期間を指定します。
 * @param         exc [in] ヒストグラム抽出時の値除外方法を指定します。
 * @param         thr [in] ヒストグラム計測の最大値最小値取得時の閾値を指定します。
 * @param         shift [in] 計測データ出力時の右シフト値を指定します。
 * @param         v_inc [in] 垂直方向の間引き設定を指定します。
 * @param         h_inc [in] 水平方向の間引き設定を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL
 *                handleに不正な値が指定された場合<p>invに不正な値が指定された場合<p>excに不正な値が指定された場合<p>
 *                thrに不正な値が指定された場合<p>shiftに不正な値が指定された場合<p>v_incに不正な値が指定された場合<p>h_incに不正な値が指定された場合
 * @description   ヒストグラム制御のパラメータを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>inv</td><td>0 ~ AG903_PGP_MGR_MAX_HGM_OUTPUT_INVALIDATE</td></tr>
 *                <tr><td>exc</td><td>PGPヒストグラム除外方法</td></tr>
 *                <tr><td>thr</td><td>0 ~ AG903_PGP_MGR_MAX_HGM_THR</td></tr>
 *                <tr><td>shift</td><td>0 ~ AG903_PGP_MGR_MAX_HGM_SHIFT</td></tr>
 *                <tr><td>v_inc</td><td>0 ~ AG903_PGP_MGR_MAX_HGM_INC</td></tr>
 *                <tr><td>h_inc</td><td>0 ~ AG903_PGP_MGR_MAX_HGM_INC</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigHistogramParameter(AG903_PgpMgrPipelineHandle *handle, uint32_t inv, uint32_t exc, uint32_t thr, uint32_t shift, uint32_t v_inc, uint32_t h_inc)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if (inv > AG903_PGP_MGR_MAX_HGM_OUTPUT_INVALIDATE) {
        return -AG903_EINVAL;
    }
    switch (exc) {
        case AG903_PGP_MGR_HGM_EXC_NONE:
        case AG903_PGP_MGR_HGM_EXC_0:
        case AG903_PGP_MGR_HGM_EXC_0_16:
        case AG903_PGP_MGR_HGM_EXC_0_WO_R:
            break;
        default:
            return -AG903_EINVAL;
    }
    if (thr > AG903_PGP_MGR_MAX_HGM_THR) {
        return -AG903_EINVAL;
    }
    if (shift > AG903_PGP_MGR_MAX_HGM_SHIFT) {
        return -AG903_EINVAL;
    }
    if (v_inc > AG903_PGP_MGR_MAX_HGM_INC) {
        return -AG903_EINVAL;
    }
    if (h_inc > AG903_PGP_MGR_MAX_HGM_INC) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->hgm_invalidate = inv;
    handle->hgm_exc = exc;
    handle->hgm_thr = thr;
    handle->hgm_shift = shift;
    handle->hgm_vinc = v_inc;
    handle->hgm_hinc = h_inc;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_HGM_PARAM] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}

/**
 * @brief         ヒストグラム制御のパラメータ設定
 * @param         handle [in] ヒストグラムを実行するパイプラインハンドルを指定します。
 * @param         vsize [in] ヒストグラム計測垂直サイズを指定します。
 * @param         hsize [in] ヒストグラム計測水平サイズを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>vsizeに不正な値が指定された場合<p>hsizeに不正な値が指定された場合
 * @description   ヒストグラム計測サイズを設定します。キャプチャサイズを超えた値は設定禁止です。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>vsize</td><td>1 ~ AG903_PGP_MGR_MAX_HGM_SIZE</td></tr>
 *                <tr><td>hsize</td><td>1 ~ AG903_PGP_MGR_MAX_HGM_SIZE</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigHistogramSize(AG903_PgpMgrPipelineHandle *handle, uint32_t vsize, uint32_t hsize)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if ((vsize == 0) || (vsize > AG903_PGP_MGR_MAX_HGM_SIZE)) {
        return -AG903_EINVAL;
    }
    if ((hsize == 0) || (hsize > AG903_PGP_MGR_MAX_HGM_SIZE)) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->hgm_vsize = vsize;
    handle->hgm_hsize = hsize;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_HGM_SIZE] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}

/**
 * @brief         ヒストグラム計測開始座標設定
 * @param         handle [in] ヒストグラムを実行するパイプラインハンドルを指定します。
 * @param         vpos [in] ヒストグラム計測開始垂直座標を指定します。
 * @param         hpos [in] ヒストグラム計測開始水平座標を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>vposに不正な値が指定された場合<p>hposに不正な値が指定された場合
 * @description   ヒストグラム計測開始座標を設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>vpos</td><td>0 ~ AG903_PGP_MGR_MAX_HGM_POS</td></tr>
 *                <tr><td>hpos</td><td>0 ~ AG903_PGP_MGR_MAX_HGM_POS</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigHistogramPosition(AG903_PgpMgrPipelineHandle *handle, uint32_t vpos, uint32_t hpos)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if (vpos > AG903_PGP_MGR_MAX_HGM_POS) {
        return -AG903_EINVAL;
    }
    if (hpos > AG903_PGP_MGR_MAX_HGM_POS) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->hgm_vpos = vpos;
    handle->hgm_hpos = hpos;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_HGM_POS] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}

/**
 * @brief         ヒストグラム計測出力先ベースアドレス設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         addr [in] ヒストグラム計測計測出力先ベースアドレスのポインタを指定します。(8バイトアライン必要)
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>addrにNULLが指定された場合
 * @description   ヒストグラム計測出力先のベースアドレスを設定します。
*/
int32_t AG903_PgpMgrSetConfigHistogramBaseAddr(AG903_PgpMgrPipelineHandle *handle, void *addr)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if (addr == NULL) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->hgm_addr = (uint32_t)addr;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_HGM_BASE_ADDR] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         ヒストグラム計測時のバッファ管理ユニット設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         enable [in] バッファ管理ユニットの有効無効を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   ヒストグラム計測時のバッファ管理ユニットの使用有無を設定します。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrEnableParamHistogramBMU(AG903_PgpMgrPipelineHandle *handle, _Bool enable)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->hgm_bmu = enable;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         ヒストグラム計測時の最頻値、最大値、最小値取得
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         most_r [out] Red要素の最頻値を格納するポインタを指定します。
 * @param         max_r [out] Red要素の最大値を格納するポインタを指定します。
 * @param         min_r [out] Red要素の最少値を格納するポインタを指定します。
 * @param         most_g [out] Green要素の最頻値を格納するポインタを指定します。
 * @param         max_g [out] Green要素の最大値を格納するポインタを指定します。
 * @param         min_g [out] Green要素の最少値を格納するポインタを指定します。
 * @param         most_b [out] Blue要素の最頻値を格納するポインタを指定します。
 * @param         max_b [out] Blue要素の最大値を格納するポインタを指定します。
 * @param         min_b [out] Blue要素の最少値を格納するポインタを指定します。
 * @return        取得結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>パイプラインが物理的に割り当てられていない場合<p>割り当て先の物理パイプラインが他のパイプラインハンドルで使用されている場合
 * @description   ヒストグラム計測時の各要素の最頻値、最大値、最小値を取得します。
 * @note          格納ポインタ=NULL の場合、その値は取得しません。
*/
int32_t AG903_PgpMgrGetHistogramParameter(AG903_PgpMgrPipelineHandle *handle, uint32_t *most_r, uint32_t *max_r, uint32_t *min_r, uint32_t *most_g, uint32_t *max_g, uint32_t *min_g, uint32_t *most_b, uint32_t *max_b, uint32_t *min_b)
{
    uint32_t dummy, tmp_max, tmp_min;

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられていない場合はエラーとします */
    if (handle->is_assign == false) {
        return -AG903_EINVAL;
    }
    /* 割り当て先の物理パイプラインが他のパイプラインハンドルに使用されている場合はエラーとします */
    if (PgpContext.exec_pipeline[handle->pipeline_no] != handle) {
        return -AG903_EINVAL;
    }

    /* Primitive Layerを通して値を取得します */
    if (most_r != NULL) {
        AG903_PgpPrmGetPGPnHGMMOD2(handle->pipeline_no, &dummy, most_r, &dummy);
    }
    AG903_PgpPrmGetPGPnHGMRNG2(handle->pipeline_no, &tmp_max, &tmp_min);
    if (max_r != NULL) {
        *max_r = tmp_max;
    }
    if (min_r != NULL) {
        *min_r = tmp_min;
    }
    if (most_g != NULL) {
        AG903_PgpPrmGetPGPnHGMMOD1(handle->pipeline_no, &dummy, most_g, &dummy);
    }
    AG903_PgpPrmGetPGPnHGMRNG1(handle->pipeline_no, &tmp_max, &tmp_min);
    if (max_g != NULL) {
        *max_g = tmp_max;
    }
    if (min_g != NULL) {
        *min_g = tmp_min;
    }
    if (most_b != NULL) {
        AG903_PgpPrmGetPGPnHGMMOD0(handle->pipeline_no, &dummy, most_b, &dummy);
    }
    AG903_PgpPrmGetPGPnHGMRNG0(handle->pipeline_no, &tmp_max, &tmp_min);
    if (max_b != NULL) {
        *max_b = tmp_max;
    }
    if (min_b != NULL) {
        *min_b = tmp_min;
    }
    return AG903_ENONE;
}


/**
 * @brief         ヒストグラム計測時のステータス取得
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         is_init [out] ヒストグラム回路が初期化中であることを示すフラグを格納するポインタを指定します。
 * @param         is_vram_out [out] VRAM出力中であることを示すフラグを格納するポインタを指定します。
 * @param         is_act [out] ヒストグラム回路が初期化中であることを示すフラグを格納するポインタを指定します。
 * @param         queue_cnt [out] ヒストグラムカウント処理が実行中であること示すフラグを格納するポインタを指定します。
 * @param         exec_cmd [out] ヒストグラム実行中のコマンドを格納するポインタを指定します。
 * @return        取得結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>パイプラインが物理的に割り当てられていない場合<p>割り当て先の物理パイプラインが他のパイプラインハンドルで使用されている場合
 * @description   ヒストグラムのステータスを取得します。
 * @note          格納ポインタ=NULLの場合、その値は取得しません。
*/
int32_t AG903_PgpMgrGetHistogramStatus(AG903_PgpMgrPipelineHandle *handle, _Bool *is_init, _Bool *is_vram_out, _Bool *is_act, uint32_t *queue_cnt, uint32_t *exec_cmd)
{
  PGPPrmParamPGPnHGMSTAT hgmstat;

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられていない場合はエラーとします */
    if (handle->is_assign == false) {
        return -AG903_EINVAL;
    }
    /* Primitive Layerを通して値を取得します */
    AG903_PgpPrmGetPGPnHGMSTAT(handle->pipeline_no, &hgmstat);

    /* 割り当て先の物理パイプラインが他のパイプラインハンドルに使用されている場合はエラーとします */
    if ((PgpContext.exec_pipeline[handle->pipeline_no] != handle) && (hgmstat.cmd != AG903_PGP_MGR_HGM_CMD_NONE)) {
        return -AG903_EINVAL;
    }
    if (is_init != NULL) {
        *is_init = hgmstat.init;
    }
    if (is_vram_out != NULL) {
        *is_vram_out = hgmstat.vrmacc;
    }
    if (is_act != NULL) {
        *is_act = hgmstat.act;
    }
    if (queue_cnt != NULL) {
        *queue_cnt = hgmstat.queue;
    }
    if (exec_cmd != NULL) {
        *exec_cmd = hgmstat.cmd;
    }
    return AG903_ENONE;
}


/**
 * @brief         閾値処理の機能設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         limit [in] limit 出力値のリミットを指定します。
 * @param         spf [in] 1bit空間フィルタの有効無効フラグを指定します。
 * @param         mask [in] 画像切り出し回路の有効無効フラグを指定します。
 * @param         csc [in] 色空間変換の有効無効フラグを指定します。
 * @param         hsv_hls [in] HSV、HLS変換の有効無効フラグを指定します。
 * @param         thr8 [in] 8bit閾値処理の有効無効フラグを指定します。
 * @param         sel_out [in] 出力セレクタのソースを指定します。
 * @param         sel_clut8 [in] CLUT8出力のソースを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>limitに不正な値が指定された場合<p>sel_outに不正な値が指定された場合<p>sel_clut8に不正な値が指定された場合
 * @description   閾値処理の機能を選択します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>limit</td><td>PGPリミット</td></tr>
 *                <tr><td>sel_out</td><td>PGP出力セレクタソース</td></tr>
 *                <tr><td>sel_clut8</td><td>PGPCLUT8出力ソース</td></tr>
 *                </table>
 *                PGPリミット のうち、AG903_PGP_MGR_LIMIT_NONE / AG903_PGP_MGR_LIMIT_16_235_AND_240 が指定可能です。
*/
int32_t AG903_PgpMgrSetConfigThreshold(AG903_PgpMgrPipelineHandle *handle, uint32_t limit, _Bool spf, _Bool mask, _Bool csc, _Bool hsv_hls, _Bool thr8, uint32_t sel_out, uint32_t sel_clut8)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (limit) {
        case AG903_PGP_MGR_LIMIT_NONE:
        case AG903_PGP_MGR_LIMIT_16_235_AND_240:
            break;
        default:
            return -AG903_EINVAL;
    }
    switch (sel_out) {
        case AG903_PGP_MGR_THR_OUT_SEL_RGB:
        case AG903_PGP_MGR_THR_OUT_SEL_MUX8:
        case AG903_PGP_MGR_THR_OUT_SEL_SPF1:
        case AG903_PGP_MGR_THR_OUT_SEL_LBL:
            break;
        default:
            return -AG903_EINVAL;
    }
    switch (sel_clut8) {
        case AG903_PGP_MGR_THR_CLUT8_OUT_B:
        case AG903_PGP_MGR_THR_CLUT8_OUT_G:
        case AG903_PGP_MGR_THR_CLUT8_OUT_R:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->thr_limit = limit;
    handle->thr_spf1_enable = spf;
    handle->thr_msk_enable = mask;
    handle->thr_csc2_enable = csc;
    handle->thr_hsv2_enable = hsv_hls;
    handle->thr_thr8bit_enable = thr8;
    handle->thr_out_sel = sel_out;
    handle->thr_clut8_sel = sel_clut8;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_THR] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         閾値処理の HSV、HLS 変換回路の出力フォーマット機能設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         sel [in] HSV、HLSを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>selに不正な値が指定された
 * @description   閾値の HSV、HLS 変換回路の出力フォーマットを設定します。<p>
 *                詳しくは、「PGP変換回路」を参照してください。
*/
int32_t AG903_PgpMgrSetConfigThresholdHSVHLSConversion(AG903_PgpMgrPipelineHandle *handle, uint32_t sel)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (sel) {
        case AG903_PGP_MGR_CONVERT_HSV:
        case AG903_PGP_MGR_CONVERT_HLS:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->thr_hsv_hls_sel = sel;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_THR_HSCHLS_CONV] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         閾値処理の色空間変換を制御するパラメータ設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         limit [in] limit 出力値のリミットを指定します。
 * @param         shift [in] 閾値処理の色腔有漢変換の出力時の右シフト量を指定します。
 * @param         mtx [in] 閾値処理の色空間変換係数を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>limitに不正な値が指定された場合<p>shiftに不正な値が指定された場合<p>mtxにNULLが指定された場合
 * @description   閾値処理の色空間変換を制御するパラメータを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>limit</td><td>PGPリミット</td></tr>
 *                <tr><td>shift</td><td>0 ~ AG903_PGP_MGR_MAX_COLOR_SPACE_SHIFT</td></tr>
 *                <tr><td>mtx</td><td>3x4マトリクスの符号付き整数<p>加算要素:20bit<p>それ以外:12bit</td></tr>
 *                </table>
 *                PGPリミット のうち、AG903_PGP_MGR_LIMIT_NONE / AG903_PGP_MGR_LIMIT_16_235_AND_240 が指定可能です。
 * @note          マトリクスの3x4の要素は下位12bitが有効となり、加算要素は下位19bitが有効となります。
*/
int32_t AG903_PgpMgrSetConfigThresholdColorSpace(AG903_PgpMgrPipelineHandle *handle, uint32_t limit, uint32_t shift, int32_t mtx[3][4])
{
    int32_t i;

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (limit) {
        case AG903_PGP_MGR_LIMIT_0_255:
        case AG903_PGP_MGR_LIMIT_16_235_AND_240:
            break;
        default:
            return -AG903_EINVAL;
    }
    if (shift > AG903_PGP_MGR_MAX_COLOR_SPACE_SHIFT) {
        return -AG903_EINVAL;
    }
    if (mtx == NULL) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->thr_csc2_limit = limit;
    handle->thr_csc2_shift = shift;
    for (i = 0; i < 3; i++) {
        handle->thr_csc2_matrix[i][0] = mtx[i][0] & CSC_MUL_MASK;
        handle->thr_csc2_matrix[i][1] = mtx[i][1] & CSC_MUL_MASK;
        handle->thr_csc2_matrix[i][2] = mtx[i][2] & CSC_MUL_MASK;
        handle->thr_csc2_matrix[i][3] = mtx[i][3] & CSC_ADD_MASK;
    }
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_THR_COLOR_SPACE] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         色空間変換のプリセット設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         format [in] 色空間変換のプリセットを指定します。
 * @return        色空間変換のプリセットを設定します。
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>formatに不正な値が指定された場合
 * @description   色空間変換のプリセットを設定します。<p>
 *                詳しくは、「PGP色空間プリセット」を参照してください。
*/
int32_t AG903_PgpMgrSetConfigThresholdPresetColorSpace(AG903_PgpMgrPipelineHandle *handle, uint32_t format)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (format) {
        case AG903_PGP_MGR_CSC_YUV_BT_601_FULL_TO_RGB:
        case AG903_PGP_MGR_CSC_RGB_TO_YUV_BT_601_FULL:
        case AG903_PGP_MGR_CSC_YUV_BT_601_LIMIT_TO_RGB:
        case AG903_PGP_MGR_CSC_RGB_TO_YUV_BT_601_LIMIT:
        case AG903_PGP_MGR_CSC_YUV_BT_709_FULL_TO_RGB:
        case AG903_PGP_MGR_CSC_RGB_TO_YUV_BT_709_FULL:
        case AG903_PGP_MGR_CSC_YUV_BT_709_LIMIT_TO_RGB:
        case AG903_PGP_MGR_CSC_RGB_TO_YUV_BT_709_LIMIT:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    PgpMgrGetPresetColorSpaceParameter(format, &handle->thr_csc2_limit, &handle->thr_csc2_shift, &handle->thr_csc2_matrix[0][0]);
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_THR_COLOR_SPACE] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         閾値処理のマスク生成設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         ch [in] 設定するマスク要素を指定します。
 * @param         h [in] 閾値処理のマスク生成パラメータHの値を指定します。
 * @param         l [in] 閾値処理のマスク生成パラメータLの値を指定します。
 * @param         x [in] 閾値処理のマスク生成パラメータXの値を指定します。
 * @param         hmax [in] 閾値処理のマスク生成パラメータHMAXの値を指定します。
 * @param         hmin [in] 閾値処理のマスク生成パラメータHMINの値を指定します。
 * @param         lmax [in] 閾値処理のマスク生成パラメータLMAXの値を指定します。
 * @param         lmin [in] 閾値処理のマスク生成パラメータLMINの値を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>chに不正な値が指定された場合
 * @description   閾値処理のマスク生成のパラメータを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>ch</td><td>PGP閾値マスク要素</td></tr>
 *                <tr><td>h/l/x</td><td>下位 1bit のみ有効</td></tr>
 *                <tr><td>hmax/hmin/lmax/lmin</td><td>下位 8bit のみ有効</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigThresholdMask(AG903_PgpMgrPipelineHandle *handle, uint32_t ch, uint32_t h, uint32_t l, uint32_t x, uint32_t hmax, uint32_t hmin, uint32_t lmax, uint32_t lmin)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (ch) {
        case AG903_PGP_MGR_THR_CHANNEL_B:
        case AG903_PGP_MGR_THR_CHANNEL_G:
        case AG903_PGP_MGR_THR_CHANNEL_R:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->thr_msk_h[ch] = h & THR_MSK_L_MASK;
    handle->thr_msk_l[ch] = l & THR_MSK_H_MASK;
    handle->thr_msk_x[ch] = x & THR_MSK_X_MASK;
    handle->thr_msk_hmax[ch] = hmax & THR_MSK_HMAX_MASK;
    handle->thr_msk_hmin[ch] = hmin & THR_MSK_HMIN_MASK;
    handle->thr_msk_lmax[ch] = lmax & THR_MSK_LMAX_MASK;
    handle->thr_msk_lmin[ch] = lmin & THR_MSK_LMIN_MASK;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_THR_MASK] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         閾値処理の 8bit 閾値処理のパラメータ設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         ch [in] 設定するマスク要素を指定します。
 * @param         type [in] 閾値処理の8bit閾値処理のタイプを指定します。
 * @param         maxval [in] 閾値処理の8bit閾値処理のmaxValueの値を指定します。
 * @param         maxthr [in] 閾値処理の8bit閾値処理のmaxThresholdの値を指定します。
 * @param         minthr [in] 閾値処理の8bit閾値処理のminThresholdの値を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>chに不正な値が指定された場合<p>typeに不正な値が指定された場合<p>PGP閾値処理タイプが拡張仕様の時 minthr > maxthr となる値が指定された場合
 * @description   閾値処理の 8bit 閾値処理のパラメータを設定します。拡張仕様の時 minthr > maxthr となる値は指定できません。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>ch</td><td>PGP閾値マスク要素</td></tr>
 *                <tr><td>type</td><td>PGP閾値処理タイプ</td></tr>
 *                <tr><td>maxval/maxthr/minthr</td><td>下位 8bit のみ有効</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigThreshold8Bit(AG903_PgpMgrPipelineHandle *handle, uint32_t ch, uint32_t type, uint32_t maxval, uint32_t maxthr, uint32_t minthr)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (ch) {
        case AG903_PGP_MGR_THR_CHANNEL_B:
        case AG903_PGP_MGR_THR_CHANNEL_G:
        case AG903_PGP_MGR_THR_CHANNEL_R:
            break;
        default:
            return -AG903_EINVAL;
    }
    switch (type) {
        case AG903_PGP_MGR_THR_8BIT_TYPE_THR_BIN:
        case AG903_PGP_MGR_THR_8BIT_TYPE_THR_BIN_INV:
        case AG903_PGP_MGR_THR_8BIT_TYPE_TRU:
        case AG903_PGP_MGR_THR_8BIT_TYPE_THR_ZERO:
        case AG903_PGP_MGR_THR_8BIT_TYPE_THR_ZERO_INV:
            break;
        case AG903_PGP_MGR_THR_8BIT_TYPE_THR_BIN_EXT:
        case AG903_PGP_MGR_THR_8BIT_TYPE_THR_BIN_INV_EXT:
        case AG903_PGP_MGR_THR_8BIT_TYPE_TRU_EXT:
        case AG903_PGP_MGR_THR_8BIT_TYPE_THR_ZERO_EXT:
        case AG903_PGP_MGR_THR_8BIT_TYPE_THR_ZERO_INV_EXT:
            if (minthr > maxthr) {
                return -AG903_EINVAL;
            }
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->thr_thr8_prm_type[ch] = type;
    handle->thr_thr8_prm_maxval[ch] = maxval & THR_8THR_MAXV_MASK;
    handle->thr_thr8_prm_maxthr[ch] = maxthr & THR_8THR_MAXTH_MASK;
    handle->thr_thr8_prm_minthr[ch] = minthr & THR_8THR_MINTH_MASK;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_THR_8BIT] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         閾値処理の 1bit 閾値処理設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         h [in] 閾値処理の1bit閾値処理パラメータHの値を指定します。
 * @param         l [in] 閾値処理の1bit閾値処理パラメータLの値を指定します。
 * @param         x [in] 閾値処理の1bit閾値処理パラメータXの値を指定します。
 * @param         hmax [in] 閾値処理の1bit閾値処理パラメータHMAXの値を指定します。
 * @param         hmin [in] 閾値処理の1bit閾値処理パラメータHMINの値を指定します。
 * @param         lmax [in] 閾値処理の1bit閾値処理パラメータLMAXの値を指定します。
 * @param         lmin [in] 閾値処理の1bit閾値処理パラメータLMINの値を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @description   閾値処理の 1bit 閾値処理のパラメータを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>h/l/x</td><td>下位 1bit のみ有効</td></tr>
 *                <tr><td>hmax/hmin/lmax/lmin</td><td>下位 8bit のみ有効</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigThreshold1Bit(AG903_PgpMgrPipelineHandle *handle, uint32_t h, uint32_t l, uint32_t x, uint32_t hmax, uint32_t hmin, uint32_t lmax, uint32_t lmin)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->thr_thr1_h = h & THR_MSK_L_MASK;
    handle->thr_thr1_l = l & THR_MSK_H_MASK;
    handle->thr_thr1_x = x & THR_MSK_X_MASK;
    handle->thr_thr1_hmax = hmax & THR_MSK_HMAX_MASK;
    handle->thr_thr1_hmin = hmin & THR_MSK_HMIN_MASK;
    handle->thr_thr1_lmax = lmax & THR_MSK_LMAX_MASK;
    handle->thr_thr1_lmin = lmin & THR_MSK_LMIN_MASK;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_THR_1BIT] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         閾値処理の 1bit 空間フィルタ設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         coeff [in] 閾値処理の1bit空間フィルタ係数を指定します。
 * @param         thr [in] 閾値処理の1bit空間フィルタの閾値を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>coeffにNULLが指定された場合
 * @description   閾値処理の 1bit 空間フィルタのパラメータを設定します。
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>coeff</td><td>下位 1bit のみ有効</td></tr>
 *                <tr><td>thr</td><td>下位 6bit のみ有効</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigThresholdSpatialFilter1Bit(AG903_PgpMgrPipelineHandle *handle, int32_t coeff[9], int32_t thr)
{
    int32_t i;

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if (coeff == NULL) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    for (i = 0; i < 9; i++) {
        handle->thr_spf1_coeff[i] = coeff[i] & THR_SPF1_COEFF_MASK;
    }
    handle->thr_spf1_thr = thr & THR_SPF1_THR_MASK;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_THR_SP_FILTER_1BIT] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         ラベリング処理の実行制御
 * @param         handle [in] ラベリング処理を実行するパイプラインハンドルを指定します。
 * @param         cmd [in] 実行コマンドを指定します。
 * @return        制御結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>cmdに不正な値が指定された場合<p>パイプラインハンドルが物理的なパイプラインに割り当てられていない場合
 * @retval        -AG903_EBUSY 他のパイプラインハンドルが実行するパイプラインで現在処理中の場合<p>コマンドがラベリングの実行かつ、キューに空きが無い場合
 * @description   ラベリング処理の制御コマンドを発行します。<p>
 *                詳しくは、「PGPラベリングコマンド」を参照してください。
*/
int32_t AG903_PgpMgrExecLabeling(AG903_PgpMgrPipelineHandle *handle, uint32_t cmd)
{
    PGPPrmParamPGPnSTATE state;

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    switch (cmd) {
        case AG903_PGP_MGR_LBL_CMD_NONE:
        case AG903_PGP_MGR_LBL_CMD_EXEC:
        case AG903_PGP_MGR_LBL_CMD_DELETE:
        case AG903_PGP_MGR_LBL_CMD_RESET:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられていない場合はエラーとします */
    if (handle->is_assign == false) {
        return -AG903_EINVAL;
    }
    /* 実行先の物理パイプラインのステータスを取得 */
    AG903_PgpPrmGetPGPnSTATE(handle->pipeline_no, &state);
    /* 他のパイプラインハンドルが現在実行中の場合はエラー */
    if ((PgpContext.exec_pipeline[handle->pipeline_no] != handle ) && (state.st != AG903_PGP_MGR_STATE_IDLE)) {
        return -AG903_EBUSY;
    }

    PGPPrmParamPGPnLBLSTAT lblstat;
    AG903_PgpPrmGetPGPnLBLSTAT(handle->pipeline_no, &lblstat);
    /* ラベリングのコマンドキューに空きがなければエラー */
    if ((cmd == AG903_PGP_MGR_LBL_CMD_EXEC) && (lblstat.queue == (AG903_PGP_MGR_LBL_CMD_MAX_QUEUE - 1))) {
        return -AG903_EBUSY;
    }

    /* Primitive Layerを通してラベリングのコマンドを発行 */
    AG903_PgpPrmSetPGPnLBLCMD(handle->pipeline_no, cmd);

    return AG903_ENONE;
}


/**
 * @brief         ラベリングの出力有効/無効期間パラメータ設定
 * @param         handle [in] ラベリング処理を実行するパイプラインハンドルを指定します。
 * @param         vld [in] ラベリング処理の出力有効期間の値を指定します。
 * @param         inv [in] ラベリング処理の出力無効期間の値を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>vldに不正な値が指定された場合<p>invに不正な値が指定された場合
 * @description   ラベリング制御の出力有効/無効期間のパラメータを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>vld</td><td>1 ~ AG903_PGP_MGR_MAX_LBL_OUTPUT_VALIDATE</td></tr>
 *                <tr><td>inv</td><td>0 ~ AG903_PGP_MGR_MAX_LBL_OUTPUT_INVALIDATE</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigLabelingValidTime(AG903_PgpMgrPipelineHandle *handle, uint32_t vld, uint32_t inv)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if ((vld == 0) || (vld > AG903_PGP_MGR_MAX_LBL_OUTPUT_VALIDATE)) {
        return -AG903_EINVAL;
    }
    if (inv > AG903_PGP_MGR_MAX_LBL_OUTPUT_INVALIDATE) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->lbl_valid = vld;
    handle->lbl_invalid = inv;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_LBL_PARAM] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         ラベリングの制御パラメータ設定
 * @param         handle [in] ラベリング処理を実行するパイプラインハンドルを指定します。
 * @param         connect [in] ラベリング処理の連結判定方法を指定します。
 * @param         flush_thr [in] ラベリング付加情報テーブルのフラッシュを行なう閾値を指定します。
 * @param         max_id [in] ラベリング付加情報テーブルのIDの最大値を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>connectに不正な値が指定された場合<p>flush_thrに不正な値が指定された場合<p>max_idに不正な値が指定された場合
 * @description   ラベリングの制御パラメータを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>connect</td><td>PGPラベリング連結判定</td></tr>
 *                <tr><td>flush_thr</td><td>0 ~ AG903_PGP_MGR_MAX_LBL_FLUSH_THR</td></tr>
 *                <tr><td>max_id</td><td>0 ~ AG903_PGP_MGR_MAX_LBL_ID</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigLabelingParameter(AG903_PgpMgrPipelineHandle *handle, uint32_t connect, uint32_t flush_thr, uint32_t max_id)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (connect) {
        case AG903_PGP_MGR_LBL_CNCT_8:
        case AG903_PGP_MGR_LBL_CNCT_4:
            break;
        default:
            return -AG903_EINVAL;
    }
    if (flush_thr > AG903_PGP_MGR_MAX_LBL_FLUSH_THR) {
        return -AG903_EINVAL;
    }
    if (max_id > AG903_PGP_MGR_MAX_LBL_ID) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->lbl_connect = connect;
    handle->lbl_flush_thr = flush_thr;
    handle->lbl_maxid = max_id;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_LBL_PARAM] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         ラベリング処理サイズ設定
 * @param         handle [in] ラベリング処理を実行するパイプラインハンドルを指定します。
 * @param         vsize [in] ラベリング処理垂直サイズを指定します。
 * @param         hsize [in] ラベリング処理水平サイズを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>vsizeに不正な値が指定された場合<p>hsizeに不正な値が指定された場合
 * @description   ラベリングの処理サイズを設定します。キャプチャサイズを超えた値は設定禁止です。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>vsize</td><td>1 ~ AG903_PGP_MGR_MAX_LBL_VSIZE</td></tr>
 *                <tr><td>hsize</td><td>1 ~ AG903_PGP_MGR_MAX_LBL_HSIZE</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigLabelingSize(AG903_PgpMgrPipelineHandle *handle, uint32_t vsize, uint32_t hsize)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if ((vsize == 0) || (vsize > AG903_PGP_MGR_MAX_LBL_VSIZE)) {
        return -AG903_EINVAL;
    }
    if ((hsize == 0) || (hsize > AG903_PGP_MGR_MAX_LBL_HSIZE)) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->lbl_vsize = vsize;
    handle->lbl_hsize = hsize;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_LBL_SIZE] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         ラベリング処理開始座標設定
 * @param         handle [in] ラベリング処理を実行するパイプラインハンドルを指定します。
 * @param         vpos [in] ラベリング処理開始垂直座標を指定します。
 * @param         hpos [in] ラベリング処理開始水平座標を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>vposに不正な値が指定された場合<p>hposに不正な値が指定された場合
 * @description   ラベリングの処理開始座標を設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>vsize</td><td>0 ~ AG903_PGP_MGR_MAX_LBL_POS</td></tr>
 *                <tr><td>hsize</td><td>0 ~ AG903_PGP_MGR_MAX_LBL_POS</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigLabelingPosition(AG903_PgpMgrPipelineHandle *handle, uint32_t vpos, uint32_t hpos)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if (vpos > AG903_PGP_MGR_MAX_LBL_POS) {
        return -AG903_EINVAL;
    }
    if (hpos > AG903_PGP_MGR_MAX_LBL_POS) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->lbl_vpos = vpos;
    handle->lbl_hpos = hpos;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_LBL_POS] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         ラベリング付加情報出力先のベースアドレス設定
 * @param         handle [in] ラベリング処理を実行するパイプラインハンドルを指定します。
 * @param         addr [in] ラベリング付加情報出力先ベースアドレスのポインタを指定します。(8バイトアライン必要)
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>addrにNULLが指定された場合
 * @description   ラベリング付加情報出力先のベースアドレスを設定します。
*/
int32_t AG903_PgpMgrSetConfigLabelingBaseAddr(AG903_PgpMgrPipelineHandle *handle, void *addr)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if (addr == NULL) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->lbl_addr = (uint32_t)addr;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_LBL_BASE_ADDR] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         ラベリング処理時のバッファ管理ユニット使用有無設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         enable [in] バッファ管理ユニットの有効無効を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @retval        -AG903_EBUSY パイプライン割り当て後に本関数が呼び出された場合
 * @description   ラベリング処理時のバッファ管理ユニットを使用有無を設定します。
 * @note          本関数でのパラメータ設定はパイプライン割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrEnableParamLabelingBMU(AG903_PgpMgrPipelineHandle *handle, _Bool enable)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられている場合はエラーとします */
    if (handle->is_assign == true) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->lbl_bmu = enable;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         ラベリング処理時のステータス取得
 * @param         handle [in] パイプラインハンドルを指定します。
 * @param         id [out] ラベリング付加情報テーブルのIDを格納するポインタを指定します。
 * @param         is_vram_out [out] VRAM出力中であることを示すフラグを格納するポインタを指定します。
 * @param         is_act [out] ラベリング処理が実行中であること示すフラグを格納するポインタを指定します。
 * @param         queue_cnt [out] キューに溜めたコマンド数を格納するポインタを指定します。
 * @param         exec_cmd [out] ラベリング処理の実行中のコマンドを格納するポインタを指定します。
 * @return        取得結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>パイプラインが物理的に割り当てられていない場合<p>割り当て先の物理パイプラインが他のパイプラインハンドルで使用されている場合
 * @description   ラベリング処理のステータスを取得します。
 * @note          格納ポインタ=NULL の場合、その値は取得しません。
*/
int32_t AG903_PgpMgrGetLabelingStatus(AG903_PgpMgrPipelineHandle *handle, uint32_t *id, _Bool *is_vram_out, _Bool *is_act, uint32_t *queue_cnt, uint32_t *exec_cmd)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられていない場合はエラーとします */
    if (handle->is_assign == false) {
        return -AG903_EINVAL;
    }

    /* Primitive Layerを通して値を取得します */
    PGPPrmParamPGPnLBLSTAT lblstat;
    AG903_PgpPrmGetPGPnLBLSTAT(handle->pipeline_no, &lblstat);

    /* 割り当て先の物理パイプラインが他のパイプラインハンドルに使用されている場合はエラーとします */
    if ((PgpContext.exec_pipeline[handle->pipeline_no] != handle) && (lblstat.cmd != AG903_PGP_MGR_LBL_CMD_NONE)) {
        return -AG903_EINVAL;
    }
    if (id != NULL) {
        *id = lblstat.l_id;
    }
    if (is_vram_out != NULL) {
        *is_vram_out = lblstat.vrmacc;
    }
    if (is_act != NULL) {
        *is_act = lblstat.act;
    }
    if (queue_cnt != NULL) {
        *queue_cnt = lblstat.queue;
    }
    if (exec_cmd != NULL) {
        *exec_cmd = lblstat.cmd;
    }
    return AG903_ENONE;
}


/**
 * @brief         ラベリング付加情報テーブルの解析
 * @param         src [in] ラベリング付加情報テーブルが格納されたポインタを指定します。
 * @param         tbl_num [in] ラベリング付加情報テーブル数を指定します。(1≦)
 * @param         dst [out] 解析後のラベリング付加情報テーブルを格納するポインタを指定します。
 * @return        解析結果
 * @retval        解析後のテーブル数 成功時
 * @retval        -AG903_ENOMEM メモリアロケートに失敗した場合
 * @retval        -AG903_EINVAL srcにNULLが指定された場合<p>tbl_numに1未満の値が指定された場合
 * @description   ラベリング付加情報テーブルを解析します。<p>
 *                ラベリング付加情報の (xmin, ymin) (xmax, ymax) の矩形領域のうち隣接するものを一つの矩形領域としてまとめます。<p>
 *                引数 dst に返される解析結果はライブラリにより動的に確保されたメモリです。解析結果使用後は AG903_PgpMgrReleaseLabelingTableによって開放して下さい。
 * @note          ラベリング付加情報テーブルのフォーマットは、LSI仕様書を参照してください。
*/
int32_t AG903_PgpMgrAnalyzeLabelingTable(void *src, uint32_t tbl_num, void **dst)
{
    uint32_t dst_num;

    /* 引数のエラーチェック */
    if (src == NULL) {
        return -AG903_EINVAL;
    }
    if (tbl_num < 1) {
        return -AG903_EINVAL;
    }

    /* 解析結果をdstに格納します */
    *dst = PgpMgrAnalyzeLabelingTable(src, tbl_num, &dst_num);

    /* 出力テーブル数 == 0 */
    if (dst_num == 0) {
        return 0;
    }

    /* dstがNULLの場合は格納先メモリ領域の確保に失敗したと判断します */
    if (*dst == NULL) {
        return -AG903_ENOMEM;
    }

    return dst_num;
}


/**
 * @brief         ラベリング付加情報テーブルの開放
 * @param         tbl [in] 解析後のラベリング付加情報テーブルを格納したポインタを指定します。
 * @return        実行結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL 引数異常
 * @note          この関数は AG903_PgpMgrAnalyzeLabelingTableと対で使用して下さい。
*/
int32_t AG903_PgpMgrReleaseLabelingTable(void *tbl)
{
	if (tbl == NULL) {
		return -AG903_EINVAL;
	}
	PgpMgrReleaseLabelingTable(tbl);
	return AG903_ENONE;
}


/**
 * @brief         フレーム間演算ハンドル取得
 * @param         handle [out] 取得したフレーム間演算ハンドルを格納するポインタを指定します。
 * @param         master [in] マスタとして使用するパイプラインハンドルを指定します。
 * @param         slave [in] スレーブとして使用するパイプラインハンドル、またはVRAM入力ハンドルを指定します。
 * @return        取得結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL
 *                取得可能な最大ハンドル数を超える場合<p>masterに有効なパイプラインハンドル以外が指定された場合<p>slaveに有効なパイプラインハンドルまたはVRAM入力ハンドル以外が指定された場合<p>handlesにNULLが指定された場合
 * @retval        -AG903_EBUSY masterに指定されたパイプラインハンドルが既に割り当て済の場合<p>slaveにパイプラインハンドルが指定され、かつ、指定されたパイプラインハンドルが既に割り当て済の場合
 * @description   フレーム間演算のハンドルを取得します。<p>
 *                フレーム間演算のハンドルはマスターとなるパイプラインハンドルとスレーブのパイプラインハンドルまたはVRAM入力ハンドルから作成します。
 * @note          フレーム間演算ハンドルの上限は、AG903_PGP_MGR_MAX_FRAME_CALC_HANDLE となります。<p>
 *                時分割動作無効の場合の上限は、AG903_PGP_MGR_CALC_PIPELINE_NUM となります。
*/
int32_t AG903_PgpMgrGetFrameCalcHandle(AG903_PgpMgrFrameCalcHandle **handle, AG903_PgpMgrPipelineHandle *master, void *slave)
{
    int32_t i;
    AG903_PgpMgrPipelineHandle *slave_pipeline = (AG903_PgpMgrPipelineHandle *)slave;
    AG903_PgpMgrVRAMInputHandle *slave_vram = (AG903_PgpMgrVRAMInputHandle *)slave;

    /* 時分割動作有効、無効により取得可能な最大ハンドル数は異ります */
    if (PgpContext.pipeline_time_sharing_enable == true) {
        if ((PgpContext.num_frame_calc_handles + 1) > AG903_PGP_MGR_MAX_FRAME_CALC_HANDLE) {
            return -AG903_ENOMEM;
        }
    } else {
        if ((PgpContext.num_frame_calc_handles + 1) > AG903_PGP_MGR_CALC_PIPELINE_NUM) {
            return -AG903_ENOMEM;
        }
    }

    if ((handle == NULL) || (master == NULL) || (slave == NULL)) {
        return -AG903_EINVAL;
    }

    /* マスタ側パイプラインハンドルがフレーム間演算として使用可能かチェックします */
    if (master->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID) {
        return -AG903_EINVAL;
    }
    if ((master->is_assign == true) || (master->is_used_frame_calc == true)) {
        return -AG903_EBUSY;
    }
    /* スレーブ側ハンドルがフレーム間演算として使用可能かチェックします */
    if (slave_pipeline->id == AG903_PGP_MGR_PIPELINE_HANDLE_ID) {
        if ((slave_pipeline->is_assign == true) || (slave_pipeline->is_used_frame_calc == true)) {
            return -AG903_EBUSY;
        }
        slave_pipeline->frame_out_enable = false;
        slave_pipeline->is_used_frame_calc = true;
        slave_pipeline->is_dirty = true;
    } else if (slave_vram->id == AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID) {
        slave_vram->ref_cnt++;
    } else {
        return -AG903_EINVAL;
    }
    master->ifc_enable = true;
    master->is_used_frame_calc = true;
    master->is_dirty = true;

    /* 使用可能なフレーム間演算ハンドルを検索し、handlesに格納します */
    for (i = 0; i < AG903_PGP_MGR_MAX_FRAME_CALC_HANDLE; i++) {
        if (PgpContext.frame_calc_handles[i].is_used == false) {
            PgpContext.frame_calc_handles[i].is_used = true;
            PgpContext.frame_calc_handles[i].master_handle = master;
            PgpContext.frame_calc_handles[i].slave_handle = slave;
            PgpContext.frame_calc_handles[i].id = AG903_PGP_MGR_FRAME_CALC_HANDLE_ID;
            PgpContext.frame_calc_handles[i].slave_pipeline = (slave_pipeline->id == AG903_PGP_MGR_PIPELINE_HANDLE_ID) ? true : false;
            *handle = &PgpContext.frame_calc_handles[i];
            break;
        }
    }
    PgpContext.num_frame_calc_handles++;
    return AG903_ENONE;
}


/**
 * @brief         フレーム間演算ハンドル解放
 * @param         handle [in] 解放するフレーム間演算ハンドルを指定します。
 * @return        解放結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @retval        -AG903_EBUSY 指定されたフレーム間演算ハンドルが現在実行中の場合
 * @description   指定されたフレーム間演算ハンドルを解放します。
*/
int32_t AG903_PgpMgrReleaseFrameCalcHandle(AG903_PgpMgrFrameCalcHandle *handle)
{
    AG903_PgpMgrPipelineHandle *slave_pipeline;

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_FRAME_CALC_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインの割り当てが行なわれている場合に以下の処理を行ないます(マスタ側が割り当てられている場合、スレーブも割り当て済とします) */
    if (handle->master_handle->pipeline_no != -1) {
        /* パイプラインハンドルが使用中での場合はエラーとします */
        if (PgpContext.exec_pipeline[handle->master_handle->pipeline_no] == handle->master_handle) {
            PGPPrmParamPGPnSTATE state;
            AG903_PgpPrmGetPGPnSTATE(handle->master_handle->pipeline_no, &state);
            if (state.st != AG903_PGP_MGR_STATE_IDLE) {
                return -AG903_EBUSY;
            }
            PgpContext.exec_pipeline[handle->master_handle->pipeline_no] = NULL;
        }
        /* 強制割り当て等で割り当て先が指定されている場合は解除します */
        if (PgpContext.assign_pipeline[handle->master_handle->pipeline_no] == handle->master_handle) {
            PgpContext.assign_pipeline[handle->master_handle->pipeline_no] = NULL;
        }
        if (handle->slave_pipeline == true) {
            slave_pipeline = (AG903_PgpMgrPipelineHandle *)handle->slave_handle;
            if (PgpContext.assign_pipeline[slave_pipeline->pipeline_no] == slave_pipeline) {
                PgpContext.assign_pipeline[slave_pipeline->pipeline_no] = NULL;
            }
        }
    }

    /* フレーム間演算ハンドルの設定からマスタ、スレーブを解除します */
    handle->master_handle->ifc_enable = false;
    handle->master_handle->is_used_frame_calc = false;
    handle->master_handle->is_assign = false;
    handle->master_handle->pipeline_no = -1;
    handle->master_handle->is_dirty = true;
    if (handle->slave_pipeline == true) {
        slave_pipeline = (AG903_PgpMgrPipelineHandle *)handle->slave_handle;
        if ((slave_pipeline->pipeline_no != -1) && (PgpContext.exec_pipeline[slave_pipeline->pipeline_no] == slave_pipeline)) {
            PgpContext.exec_pipeline[slave_pipeline->pipeline_no] = NULL;
        }
        slave_pipeline->frame_out_enable = true;
        slave_pipeline->is_used_frame_calc = false;
        slave_pipeline->is_assign = false;
        slave_pipeline->pipeline_no = -1;
        slave_pipeline->is_dirty = true;
    } else {
        AG903_PgpMgrVRAMInputHandle *slave_vram = (AG903_PgpMgrVRAMInputHandle *)handle->slave_handle;
        slave_vram->ref_cnt--;
    }

    handle->is_used = false;
    handle->id = 0;
    PgpContext.num_frame_calc_handles--;
    return AG903_ENONE;
}


/**
 * @brief         フレーム間演算パラメータ設定
 * @param         handle [in] フレーム間演算ハンドルを指定します。
 * @param         scan [in] フレーム走査方法を指定します。
 * @param         limit [in] 出力値のリミットを指定します。
 * @param         slave_src [in] スレーブ側の入力ソースを指定します。
 * @param         operation [in] フレーム間の演算方法を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>
 *                scanに不正な値が指定された場合<p>limitに不正な値が指定された場合<p>slave_srcに不正な値が指定された場合<p>operationに不正な値が指定された場合
 * @description   フレーム間演算のパラメータを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>scan</td><td>PGPフレーム走査方法</td></tr>
 *                <tr><td>limit</td><td>PGPリミット</td></tr>
 *                <tr><td>slave_src</td><td>PGPフレーム入力ソース</td></tr>
 *                <tr><td>operation</td><td>PGPフレーム間演算方法</td></tr>
 *                </table>
 *                PGPリミット のうち、AG903_PGP_MGR_LIMIT_0_255 / AG903_PGP_MGR_LIMIT_16_235_AND_240 / AG903_PGP_MGR_IFC_LIMIT_M128_127 が指定可能です。
*/
int32_t AG903_PgpMgrSetConfigFrameCalcParameter(AG903_PgpMgrFrameCalcHandle *handle, uint32_t scan, uint32_t limit, uint32_t slave_src, uint32_t operation)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_FRAME_CALC_HANDLE_ID)) {
        return -AG903_EINVAL;
    }
    /* 引数のエラーチェック */
    switch (scan) {
        case AG903_PGP_MGR_SCAN_PROGRESSIVE:
        case AG903_PGP_MGR_SCAN_INTERLACE:
            break;
        default:
            return -AG903_EINVAL;
    }
    switch (limit) {
        case AG903_PGP_MGR_IFC_LIMIT_0_255:
        case AG903_PGP_MGR_IFC_LIMIT_16_235_AND_240:
        case AG903_PGP_MGR_IFC_LIMIT_M128_127:
            break;
        default:
            return -AG903_EINVAL;
    }
    switch (slave_src) {
        case AG903_PGP_MGR_IFC_SLAVE_VRAM_UI:
        case AG903_PGP_MGR_IFC_SLAVE_VRAM_I:
        case AG903_PGP_MGR_IFC_SLAVE_PIPELINE:
            break;
        default:
            return -AG903_EINVAL;
    }
    switch (operation) {
        case AG903_PGP_MGR_IFC_OP_AND:
        case AG903_PGP_MGR_IFC_OP_OR:
        case AG903_PGP_MGR_IFC_OP_XOR:
        case AG903_PGP_MGR_IFC_OP_ADD:
        case AG903_PGP_MGR_IFC_OP_ABS:
            break;
        default:
            return -AG903_EINVAL;
    }
    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->master_handle->ifc_scan = scan;
    handle->master_handle->ifc_limit = limit;
    handle->master_handle->ifc_slave_src = (handle->slave_pipeline == true) ? AG903_PGP_MGR_IFC_SLAVE_PIPELINE : slave_src;
    handle->master_handle->ifc_operation = operation;
    handle->master_handle->is_config_dirty[AG903_PGP_MGR_CONFIG_IFC_PARAM] = true;
    handle->master_handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         フレーム間演算のゲインパラメータ設定
 * @param         handle [in] フレーム間演算ハンドルを指定します。
 * @param         master_gain [in] マスタ入力のゲインを指定します。
 * @param         slave_gain [in] スレーブ入力のゲインを指定します。
 * @param         master_shift [in] マスタ入力のゲイン演算結果のシフト量を指定します。
 * @param         slave_shift [in] スレーブ入力のゲイン演算結果のシフト量を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @description   フレーム間演算のゲインパラメータを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>master_gain</td><td>下位 8bit のみ有効</td></tr>
 *                <tr><td>slave_gain</td><td>下位 8bit のみ有効</td></tr>
 *                <tr><td>master_shift</td><td>0 ~ AG903_PGP_MGR_MAX_IFC_GAIN_SHIFT</td></tr>
 *                <tr><td>slave_shift</td><td>0 ~ AG903_PGP_MGR_MAX_IFC_GAIN_SHIFT</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigFrameCalcGain(AG903_PgpMgrFrameCalcHandle *handle, int32_t master_gain, int32_t slave_gain, uint32_t master_shift, uint32_t slave_shift)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_FRAME_CALC_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if (master_shift > AG903_PGP_MGR_MAX_IFC_GAIN_SHIFT) {
        return -AG903_EINVAL;
    }
    if (slave_shift > AG903_PGP_MGR_MAX_IFC_GAIN_SHIFT) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->master_handle->ifc_master_gain = master_gain & IFC_GAIN_MASK;
    handle->master_handle->ifc_slave_gain = slave_gain & IFC_GAIN_MASK;
    handle->master_handle->ifc_master_shift = master_shift;
    handle->master_handle->ifc_slave_shift = slave_shift;
    handle->master_handle->is_config_dirty[AG903_PGP_MGR_CONFIG_IFC_PARAM] = true;
    handle->master_handle->is_config_dirty[AG903_PGP_MGR_CONFIG_IFC_GAIN] = true;
    handle->master_handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         指定した数のVRAM入力ハンドル取得
 * @param         num [in] 取得するVRAM入力ハンドルの数を指定します。
 * @param         handles [out] 取得したVRAM入力ハンドルを格納するポインタを指定します。
 * @return        取得結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL numに指定した数と、取得済のVRAM入力ハンドルの合計値が最大ハンドル数を超える場合<p>handlesにNULLが指定された場合
 * @description   VRAM入力のハンドルを取得します。
 * @note          VRAM入力ハンドルの上限は、AG903_PGP_MGR_MAX_VRAMI_HANDLE となります。<p>
 *                時分割動作無効の場合の上限は、AG903_PGP_MGR_VRAMI_NUM となります。
 *
 *
*/
int32_t AG903_PgpMgrGetVRAMInputHandle(int32_t num, AG903_PgpMgrVRAMInputHandle **handles)
{
    int i, j;

    /* 時分割動作有効、無効により取得可能な最大ハンドル数は異ります */
    if (PgpContext.pipeline_time_sharing_enable == true) {
        if ((num + PgpContext.num_vram_input_handles) > AG903_PGP_MGR_MAX_VRAMI_HANDLE) {
            return -AG903_EINVAL;
        }
    } else {
        if ((num + PgpContext.num_vram_input_handles) > AG903_PGP_MGR_VRAMI_NUM) {
            return -AG903_EINVAL;
        }
    }

    if (handles == NULL) {
        return -AG903_EINVAL;
    }

    /* 使用可能なVRAM入力ハンドルを検索し、handlesに格納します */
    for (i = 0; i < num; i++) {
        for (j = 0; j < AG903_PGP_MGR_MAX_VRAMI_HANDLE; j++) {
            if (PgpContext.vram_input_handles[j].is_used == false) {
                /* ハンドルの設定値を初期化します。 */
                PgpMgrInitVRAMInputHandle(&PgpContext.vram_input_handles[j]);

                PgpContext.vram_input_handles[j].is_used = true;
                PgpContext.vram_input_handles[j].id = AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID;
                handles[i] = &PgpContext.vram_input_handles[j];
                break;
            }
        }
    }

    PgpContext.num_vram_input_handles += num;

    return AG903_ENONE;
}


/**
 * @brief         VRAM入力ハンドル解放
 * @param         handle [in] 解放するVRAM入力ハンドルを指定します。
 * @return        解放結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @retval        -AG903_EBUSY 指定されたVRAM入力ハンドルが他のハンドルに関連付けされている場合
 * @description   指定されたVRAM入力ハンドルを解放します。
*/
int32_t AG903_PgpMgrReleaseVRAMInputHandle(AG903_PgpMgrVRAMInputHandle *handle)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 他のハンドルに関連付けされている(リファレンスカウントが0以外)の場合はエラーとします */
    if (handle->ref_cnt != 0) {
        return -AG903_EBUSY;
    }

    if (PgpContext.assign_vram[handle->port_no] == handle) {
        PgpContext.assign_vram[handle->port_no] = NULL;
    }
    if (PgpContext.exec_vram[handle->port_no] == handle) {
        PgpContext.exec_vram[handle->port_no] = NULL;
    }

    handle->is_used = false;
    handle->id = 0;
    PgpContext.num_vram_input_handles--;
    return AG903_ENONE;
}


/**
 * @brief         VRAM入力の実行制御
 * @param         handle [in] 実行するVRAM入力ハンドルを指定します。
 * @param         cmd [in] 実行コマンドを指定します。
 * @return        制御結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>cmdに不正な値が指定された場合<p>入力ポートの割り当てが行なわれていない場合
 * @retval        -AG903_EBUSY 他のVRAM入力ハンドルが実行するポートで現在処理中の場合<p>VRAM入力のコマンドキューに空きが無い場合、コマンドを受けつける状態では無い場合
 * @description   VRAM入力のコマンドを発行します。<p>
 *                詳しくは、「PGPVRAM入力コマンド」を参照してください。
*/
int32_t AG903_PgpMgrExecVRAMInput(AG903_PgpMgrVRAMInputHandle *handle, uint32_t cmd)
{
    uint32_t dummy, queue, st;

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 割り当て前の場合はエラーとします */
    if (handle->port_no == -1) {
        return -AG903_EINVAL;
    }
    /* 実行先の物理ポートのステータスを取得 */
    AG903_PgpPrmGetPGPVInSTATE(handle->port_no, &dummy, &queue, &st);
    /* 他のVRAM入力ハンドルが現在実行中の場合はエラー */
    if ((PgpContext.exec_vram[handle->port_no] != handle ) && (st != AG903_PGP_MGR_VI_CMD_NONE)) {
        return -AG903_EBUSY;
    }

    switch (cmd) {
        case AG903_PGP_MGR_VI_CMD_EXEC:
            /* コマンドキューに空きがない、または、他のコマンドが実行中の場合エラー */
            if ((queue == (AG903_PGP_MGR_VI_CMD_MAX_QUEUE - 1)) || ((st != 0) && (cmd != st))) {
                return -AG903_EBUSY;
            }
            break;
        case AG903_PGP_MGR_VI_CMD_EXEC_CONTINUE:
            /* 連続実行時はアイドル状態のみコマンドを受けつけ可能 */
            if (st != 0) {
                return -AG903_EBUSY;
            }
            break;
        case AG903_PGP_MGR_VI_CMD_NONE:
        case AG903_PGP_MGR_VI_CMD_IDLE:
        case AG903_PGP_MGR_VI_CMD_RESET:
            break;
        default:
            return -AG903_EINVAL;
    }
    /* コマンド発行 */
    PgpMgrExecVRAMInputHandle(handle, cmd);
    return AG903_ENONE;
}


/**
 * @brief         VRAM入力のステータス取得
 * @param         handle [in] VRAM入力ハンドルを指定します。
 * @param         is_vram_out [out] VRAM出力中であることを示すフラグを格納するポインタを指定します。
 * @param         queue_cnt [out] キューに溜めたコマンド数を格納するポインタを指定します。
 * @param         exec_cmd [out] VRAM入力の実行中のコマンドを格納するポインタを指定します。
 * @return        取得結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>パイプラインが物理的に割り当てられていない場合<p>割り当て先の物理VRAMポートが他のVRAM入力で使用されている場合
 * @description   VRAM入力のステータスを取得します。
 * @note          格納ポインタ=NULLの場合、値は取得しません。
*/
int32_t AG903_PgpMgrGetVRAMStatus(AG903_PgpMgrVRAMInputHandle *handle, _Bool *is_vram_out, uint32_t *queue_cnt, uint32_t *exec_cmd)
{
    uint32_t tmp_vram, tmp_queue, tmp_st;

    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 物理ポートに割り当てられていない場合はエラーとします */
    if (handle->port_no == -1) {
        return -AG903_EINVAL;
    }

    /* Primitive Layerを通して値を取得します */
    AG903_PgpPrmGetPGPVInSTATE(handle->port_no, &tmp_vram, &tmp_queue, &tmp_st);

    /* 割り当て先の物理VRAMポートが他のVRAM入力ハンドルに使用されている場合はエラーとします */
    if ((PgpContext.exec_vram[handle->port_no] != handle) && (tmp_st != AG903_PGP_MGR_VI_CMD_NONE)) {
        return -AG903_EINVAL;
    }
    if (is_vram_out != NULL) {
        *is_vram_out = tmp_vram;
    }
    if (queue_cnt != NULL) {
        *queue_cnt = tmp_queue;
    }
    if (exec_cmd != NULL) {
        *exec_cmd = tmp_st;
    }
    return AG903_ENONE;
}


/**
 * @brief         VRAM入力のバッファ管理ユニット設定
 * @param         handle [in] VRAM入力ハンドルを指定します。
 * @param         bmu [in] バッファ管理ユニットを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>bmuに不正な値が指定された場合
 * @retval        -AG903_EBUSY VRAMポート割り当て後に本関数が呼び出された場合
 * @description   VRAM入力のバッファ管理ユニットを設定します。<p>
 *                詳しくは、「PGPVRAM入力BMU設定」を参照してください。
 * @note          本関数でのパラメータ設定はVRAMポート割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamVRAMInputBMU(AG903_PgpMgrVRAMInputHandle *handle, uint32_t bmu)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (bmu) {
        case AG903_PGP_MGR_VI_BMU_NONE:
        case AG903_PGP_MGR_VI_BMU_ENABLE:
        case AG903_PGP_MGR_VI_BMU_ENABLE_ODD:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* VRAMポートに割り当てられている場合はエラーとします */
    if (handle->port_no != -1) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->bmu = bmu;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         VRAM入力のフレーム走査方法設定
 * @param         handle [in] 実行するVRAM入力ハンドルを指定します。
 * @param         scan [in] フレーム走査方法を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>scanに不正な値が指定された場合
 * @retval        -AG903_EBUSY VRAMポート割り当て後に本関数が呼び出された場合
 * @description   VRAM入力時のフレーム走査方法のパラメータを設定します。<p>
 *                詳しくは、「PGPフレーム走査方法」を参照してください。
 * @note          本関数でのパラメータ設定はVRAMポート割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamVRAMInputScan(AG903_PgpMgrVRAMInputHandle *handle, uint32_t scan)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (scan) {
        case AG903_PGP_MGR_SCAN_PROGRESSIVE:
        case AG903_PGP_MGR_SCAN_INTERLACE:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* VRAMポートに割り当てられている場合はエラーとします */
    if (handle->port_no != -1) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->scan = scan;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         VRAM入力のアドレス指定方法設定
 * @param         handle [in] 実行するVRAM入力ハンドルを指定します。
 * @param         dim [in] アドレス指定方法を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>dimに不正な値が指定された場合
 * @retval        -AG903_EBUSY VRAMポート割り当て後に本関数が呼び出された場合
 * @description   VRAM入力時のアドレス指定方法を設定します。<p>
 *                詳しくは、「PGPアドレス指定方法」を参照してください。
 * @note          本関数でのパラメータ設定はVRAMポート割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamVRAMInputAddrDim(AG903_PgpMgrVRAMInputHandle *handle, uint32_t dim)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (dim) {
        case AG903_PGP_MGR_ADDR_DIMENTION_1:
        case AG903_PGP_MGR_ADDR_DIMENTION_2:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* VRAMポートに割り当てられている場合はエラーとします */
    if (handle->port_no != -1) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->dim = dim;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         VRAM入力のデータスワップ設定
 * @param         handle [in] VRAM入力ハンドルを指定します。
 * @param         word [in] ワードデータのスワップの有効無効フラグを指定します。
 * @param         hword [in] ハーフワードデータのスワップの有効無効フラグを指定します。
 * @param         four_bit [in] 4bitデータのスワップの有効無効フラグを指定します。
 * @param         ont_bit [in] 1bitデータのスワップの有効無効フラグを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @description   VRAM入力時のデータスワップを設定します。
*/
int32_t AG903_PgpMgrSetConfigVRAMDataSwap(AG903_PgpMgrVRAMInputHandle *handle, _Bool word, _Bool hword, _Bool four_bit, _Bool one_bit)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->vram_word_swap_enable = word;
    handle->vram_hword_swap_enable = hword;
    handle->vram_4bit_swap_enable = four_bit;
    handle->vram_1bit_swap_enable = one_bit;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_VI_CTRL] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         VRAM入力のインタレースフレームの読みだし方法設定
 * @param         handle [in] VRAM入力ハンドルを指定します。
 * @param         frame_read [in] インタレースフレームの読みだし方法を指定します。
 * @param         fai [in] フレーム付加情報の領域スキップ機能有効無効フラグを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>frame_readに不正な値が指定された場合
 * @description   VRAM入力のインタレースフレームの読み出し方法を設定します。<p>
 *                詳しくは、「PGPVRAM入力フレーム読み出し方法」を参照してください。
*/
int32_t AG903_PgpMgrSetConfigVRAMInterlaceFrame(AG903_PgpMgrVRAMInputHandle *handle, uint32_t frame_read, _Bool fai)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (frame_read) {
        case AG903_PGP_MGR_VI_FRAME_READ_ODD:
        case AG903_PGP_MGR_VI_FRAME_READ_EVEN:
        case AG903_PGP_MGR_VI_FRAME_READ_FIELD:
        case AG903_PGP_MGR_VI_FRAME_READ_WEAVE:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->md = frame_read;
    handle->fai_enable = fai;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_VI_CTRL] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         VRAM入力の出力有効/無効期間パラメータ設定
 * @param         handle [in] VRAM入力ハンドルを指定します。
 * @param         div [in] 出力期間の引き伸ばし設定を指定します。
 * @param         vld [in] 出力有効期間を指定します。
 * @param         inv [in] 出力無効期間を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>divに不正な値が指定された場合<p>vldに不正な値が指定された場合<p>invに不正な値が指定された場合
 * @description   VRAM出力の有効/無効期間パラメータを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>div</td><td>1 ~ AG903_PGP_MGR_MAX_VI_DIV</td></tr>
 *                <tr><td>vld</td><td>1 ~ AG903_PGP_MGR_MAX_VI_VALIDATE</td></tr>
 *                <tr><td>inv</td><td>0 ~ AG903_PGP_MGR_MAX_VI_INVALIDATE</td></tr>
 *                </table>
*/
int32_t AG903_PgpMgrSetConfigVRAMValidTime(AG903_PgpMgrVRAMInputHandle *handle, uint32_t div, uint32_t vld, uint32_t inv)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if ((div == 0) || (div > AG903_PGP_MGR_MAX_VI_DIV)) {
        return -AG903_EINVAL;
    }
    if ((vld == 0) || (vld > AG903_PGP_MGR_MAX_VI_VALIDATE)) {
        return -AG903_EINVAL;
    }
    if (inv > AG903_PGP_MGR_MAX_VI_INVALIDATE) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->div = div;
    handle->valid = vld;
    handle->invalid = inv;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_VI_CTRL1] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         VRAM入力のフォーマット設定
 * @param         handle [in] VRAM入力ハンドルを指定します。
 * @param         format [in] 入力フォーマットを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>formatに不正な値が指定された場合
 * @retval        -AG903_EBUSY VRAMポート割り当て後に本関数が呼び出された場合
 * @description   VRAM入力フォーマットを設定します。<p>
 *                詳しくは、「PGPVRAM入力フォーマット」を参照してください。
 * @note          本関数でのパラメータ設定はVRAMポート割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamVRAMFormat(AG903_PgpMgrVRAMInputHandle *handle, uint32_t format)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    switch (format) {
        case AG903_PGP_MGR_VI_FMT_RGB888_32:
        case AG903_PGP_MGR_VI_FMT_RGB888_24:
        case AG903_PGP_MGR_VI_FMT_RGB565:
        case AG903_PGP_MGR_VI_FMT_YCBCR444_32:
        case AG903_PGP_MGR_VI_FMT_YCBCR444_24:
        case AG903_PGP_MGR_VI_FMT_YCBCR422:
        case AG903_PGP_MGR_VI_FMT_CLUT8:
        case AG903_PGP_MGR_VI_FMT_CLUT1:
            break;
        default:
            return -AG903_EINVAL;
    }

    /* VRAMポートに割り当てられている場合はエラーとします */
    if (handle->port_no != -1) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->format = format;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         VRAM入力の出力先ベースアドレス設定
 * @param         handle [in] VRAM入力ハンドルを指定します。
 * @param         addr [in] 出力先ベースアドレスのポインタを指定します。(8バイトアライン必要)
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>addrにNULLが指定された場合
 * @description   VRAM入力の出力先ベースアドレスを設定します。
*/
int32_t AG903_PgpMgrSetConfigVRAMBaseAddr(AG903_PgpMgrVRAMInputHandle *handle, void *addr)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if (addr == NULL) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->addr = (uint32_t)addr;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_VI_BASE] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         VRAM入力が二次元アドレスの場合のストライドバイト設定
 * @param         handle [in] VRAM入力ハンドルを指定します。
 * @param         stride [in] 2次元アドレスの場合のストライドバイトを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>strideに不正な値が指定された場合
 * @retval        -AG903_EBUSY VRAMポート割り当て後に本関数が呼び出された場合
 * @description   VRAM入力が二次元アドレスの場合のストライドバイトを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>stride</td><td>1 ~ AG903_PGP_MGR_VI_MAX_STRIDE_BYTE</td></tr>
 *                </table>
 * @note          本関数でのパラメータ設定はVRAMポート割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamVRAMStride(AG903_PgpMgrVRAMInputHandle *handle, uint32_t stride)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if ((stride == 0) || (stride > AG903_PGP_MGR_VI_MAX_STRIDE_BYTE)) {
        return -AG903_EINVAL;
    }

    /* VRAMポートに割り当てられている場合はエラーとします */
    if (handle->port_no != -1) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->stride = stride;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         VRAM入力の同期信号出力パラメータ設定
 * @param         handle [in] VRAM入力ハンドルを指定します。
 * @param         h_pw [in] 水平同期信号パルス幅を指定します。
 * @param         h_fp [in] 水平フロントポーチを指定します。
 * @param         h_bp [in] 水平バックポーチを指定します。
 * @param         v_pw [in] 垂直同期信号パルス幅を指定します。
 * @param         v_fp [in] 垂直フロントポーチを指定します。
 * @param         v_bp [in] 垂直バックポーチを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handle/h_pw/h_fp/h_bp/v_pw/v_fp/v_bpに不正な値が指定された場合
 * @retval        -AG903_EBUSY VRAMポート割り当て後に本関数が呼び出された場合
 * @description   VRAM入力の同期信号の出力パラメータを設定します。<p>
 *                水平周期(h_pw + h_fp + h_bp + 水平サイズ)は16ピクセル以上に設定して下さい。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>h_pw</td><td>1 ~ AG903_PGP_MGR_MAX_VI_H_PULES_WIDTH</td></tr>
 *                <tr><td>h_fp</td><td>1 ~ AG903_PGP_MGR_MAX_VI_H_FRONT_PORCH</td></tr>
 *                <tr><td>h_bp</td><td>1 ~ AG903_PGP_MGR_MAX_VI_H_BACK_PORCH</td></tr>
 *                <tr><td>v_pw</td><td>1 ~ AG903_PGP_MGR_MAX_VI_V_PULES_WIDTH</td></tr>
 *                <tr><td>v_fp</td><td>1 ~ AG903_PGP_MGR_MAX_VI_V_FRONT_PORCH</td></tr>
 *                <tr><td>v_bp</td><td>1 ~ AG903_PGP_MGR_MAX_VI_V_BACK_PORCH</td></tr>
 *                </table>
 * @note          本関数でのパラメータ設定はVRAMポート割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamVRAMSyncSignal(AG903_PgpMgrVRAMInputHandle *handle, uint32_t h_pw, uint32_t h_fp, uint32_t h_bp, uint32_t v_pw, uint32_t v_fp, uint32_t v_bp)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if ((h_pw == 0) || (h_pw > AG903_PGP_MGR_MAX_VI_H_PULES_WIDTH)) {
        return -AG903_EINVAL;
    }
    if ((h_fp == 0) || (h_fp > AG903_PGP_MGR_MAX_VI_H_FRONT_PORCH)) {
        return -AG903_EINVAL;
    }
    if ((h_bp == 0) || (h_bp > AG903_PGP_MGR_MAX_VI_H_BACK_PORCH)) {
        return -AG903_EINVAL;
    }
    if ((v_pw == 0) || (v_pw > AG903_PGP_MGR_MAX_VI_V_PULES_WIDTH)) {
        return -AG903_EINVAL;
    }
    if ((v_fp == 0) || (v_fp > AG903_PGP_MGR_MAX_VI_V_FRONT_PORCH)) {
        return -AG903_EINVAL;
    }
    if ((v_bp == 0) || (v_bp > AG903_PGP_MGR_MAX_VI_V_BACK_PORCH)) {
        return -AG903_EINVAL;
    }

    /* VRAMポートに割り当てられている場合はエラーとします */
    if (handle->port_no != -1) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->h_pulse_width = h_pw;
    handle->h_front_porch = h_fp;
    handle->h_back_porch = h_bp;
    handle->v_pulse_width = v_pw;
    handle->v_front_porch = v_fp;
    handle->v_back_porch = v_bp;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         VRAM入力のフレームサイズ設定
 * @param         handle [in] VRAM入力ハンドルを指定します。
 * @param         h_size [in] 水平サイズを指定します。
 * @param         v_size [in] 垂直サイズを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handle/h_size/v_sizeに不正な値が指定された場合
 * @retval        -AG903_EBUSY VRAMポート割り当て後に本関数が呼び出された場合
 * @description   VRAM入力のフレームサイズを設定します。<p>
 *                引数に指定可能な範囲は以下の通りです。
 *                <table>
 *                <tr><th>引数</th><th>設定可能範囲</th></tr>
 *                <tr><td>h_size</td><td>1 ~ AG903_PGP_MGR_MAX_VI_H_SIZE</td></tr>
 *                <tr><td>v_size</td><td>1 ~ AG903_PGP_MGR_MAX_VI_V_SIZE</td></tr>
 *                </table>
 * @note          本関数でのパラメータ設定はVRAMポート割り当て前に行なう必要があります。
*/
int32_t AG903_PgpMgrSetParamVRAMSize(AG903_PgpMgrVRAMInputHandle *handle, uint32_t h_size, uint32_t v_size)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 引数のエラーチェック */
    if ((h_size == 0) || (h_size > AG903_PGP_MGR_MAX_VI_H_SIZE)) {
        return -AG903_EINVAL;
    }
    if ((v_size == 0) || (v_size > AG903_PGP_MGR_MAX_VI_V_SIZE)) {
        return -AG903_EINVAL;
    }

    /* VRAMポートに割り当てられている場合はエラーとします */
    if (handle->port_no != -1) {
        return -AG903_EBUSY;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->h_frame_size = h_size;
    handle->v_frame_size = v_size;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         VRAM入力のインタレースモードでのEVEN/ODDフレーム調整
 * @param         handle [in] VRAM入力ハンドルを指定します。
 * @param         e_vbp [in] インタレースモードでのEVENフレームのVBP調整の有効/無効を指定します。
 * @param         e_vfp [in] インタレースモードでのEVENフレームのVFP調整の有効/無効を指定します。
 * @param         o_vbp [in] インタレースモードでのODDフレームのVBP調整の有効/無効を指定します。
 * @param         o_vfp [in] インタレースモードでのODDフレームのVFP調整の有効/無効を指定します。
 * @param         o_vsize [in] インタレースモードでのODDフレームのVSIZE調整の有効/無効を指定します。
 * @return        調整結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合
 * @description   VRAM入力のインタレースモードでの EVEN/ODD フレームを調整します。
*/
int32_t AG903_PgpMgrAdjustVRAMFrame(AG903_PgpMgrVRAMInputHandle *handle, _Bool e_vbp, _Bool e_vfp, _Bool o_vbp, _Bool o_vfp, _Bool o_vsize)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パラメータをハンドルに保持し、Dirtyフラグをセットします */
    handle->adjust_even_vbp = e_vbp;
    handle->adjust_even_vfp = e_vfp;
    handle->adjust_odd_vbp = o_vbp;
    handle->adjust_odd_vfp = o_vfp;
    handle->adjust_odd_vsize = o_vsize;
    handle->is_config_dirty[AG903_PGP_MGR_CONFIG_VI_ADJUST_FRAME] = true;
    handle->is_dirty = true;
    return AG903_ENONE;
}


/**
 * @brief         指定されたVRAM入力ハンドルとパイプラインハンドルの映像パラメータの互換性確認
 * @param         handle [in] VRAM入力ハンドルを指定します。
 * @param         pipeline [in] パイプラインハンドルを指定します。
 * @return        確認結果
 * @retval        AG903_ENONE 互換性がある場合
 * @retval        -AG903_EINVAL vramに不正な値が指定された場合<p>pipelineに不正な値が指定された場合<p>VRAM入力ハンドルとパイプラインハンドルの映像パラメータに互換性が無い場合
 * @description   指定されたVRAM入力ハンドルの設定とパイプラインハンドルの映像パラメータ設定に互換性があるか確認します。
*/
int32_t AG903_PgpMgrCheckVRAMParameter(AG903_PgpMgrVRAMInputHandle *vram, AG903_PgpMgrPipelineHandle *pipeline)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((vram == NULL) || (vram->id != AG903_PGP_MGR_VRAM_INPUT_HANDLE_ID)) {
        return -AG903_EINVAL;
    }
    if ((pipeline == NULL) || (pipeline->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* 水平ブランクエリアの互換性を確認します */
    if ((vram->h_pulse_width + vram->h_back_porch) != pipeline->input_hpos) {
        return -AG903_EINVAL;
    }
    /* 垂直ブランクエリアの互換性を確認します */
    if ((vram->v_pulse_width + vram->v_back_porch) != pipeline->input_vpos) {
        return -AG903_EINVAL;
    }

    return AG903_ENONE;
}


/**
 * @brief         指定されたパイプラインハンドルのJPEG出力設定
 * @param         handle [in] パイプラインハンドルを指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL handleに不正な値が指定された場合<p>パイプラインハンドルが物理的に割り当てられていない場合
 * @description   指定されたパイプラインハンドルをJPEG出力に設定します。
 * @note          本関数はJPEG出力で使用するパイプラインを指定するのみです。<p>
 *                実際にそのパイプラインを用いてJPEG機能を使用する場合、AG903_PgpMgrEnableJPEG 関数にてJPEGを有効にする必要があります。
 *
*/
int32_t AG903_PgpMgrSetJPEG(AG903_PgpMgrPipelineHandle *handle)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((handle == NULL) || (handle->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインに割り当てられていない場合はエラーとします */
    if (handle->is_assign == false) {
        return -AG903_EINVAL;
    }

    PgpContext.jpeg_output_pipeline = handle->pipeline_no;

    return AG903_ENONE;
}


/**
 * @brief         JPEG出力の有効/無効設定
 * @param         enable [in] JPEG出力の有効無効を指定します。
 * @return        設定結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EBUSY 既にJPEG機能が有効の状態で本関数にて有効にする設定が行なわれた場合
 * @description   JPEG出力の有効/無効を切り替えます。
 * @note          JPEG機能の有効は無効状態からのみ有効に変更することが可能です。<p>
 *                これは、複数のパイプラインから同時に有効にすることを回避するためです。<p>
 *                JPEG機能を有効にする場合は、JPEG機能が停止していることを確認し、一旦無効にしていから有効にして下さい。
*/
int32_t AG903_PgpMgrEnableJPEG(_Bool enable)
{
    if ((enable == true) && (PgpContext.jpeg_output_enable == true)) {
       return -AG903_EBUSY;
    }

    PgpContext.jpeg_output_enable = enable;

    /* Primitive Layerを通してJPEG機能の設定を行ないます */
    AG903_PgpPrmSetPGPJPGOUTSEL(PgpContext.jpeg_output_enable, PgpContext.jpeg_output_pipeline);

    return AG903_ENONE;
}


#define PACK_LUT(d0, d1, d2, d3) (((d0) << 0) | ((d1) << 8) | ((d2) << 16) | ((d3) << 24))
/**
 * @brief         濃度変換テーブルハンドル取得
 * @param         red [in] 濃度変換テーブルのRed値のテーブルを指定します。
 * @param         green [in] 濃度変換テーブルのGreen値のテーブルを指定します。
 * @param         blue [in] 濃度変換テーブルのBlue値のテーブルを指定します。
 * @param         table [out] 取得した濃度変換テーブルハンドルを格納するポインタを指定します。
 * @return        取得結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL red、green、blueのいずれかにNULLが指定された場合
 * @retval        -AG903_ENOMEM 濃度変換テーブルハンドル数の合計値が最大ハンドル数を超える場合
 * @retval        -AG903_EINVAL tableにNULLが指定された場合
 * @description   濃度変換テーブルを取得します。
*/
int32_t AG903_PgpMgrGetDGCLUT(uint8_t red[256], uint8_t green[256], uint8_t blue[256], AG903_PgpMgrDGCLookupTable **table)
{
    int i, j;

    /* 引数のエラーチェック */
    if ((red == NULL) || (green == NULL) || (blue == NULL) || (table == NULL)) {
        return -AG903_EINVAL;
    }

    if ((PgpContext.num_dgc_lut + 1) > AG903_PGP_MGR_MAX_DGC_LUT) {
        return -AG903_ENOMEM;
    }

    /* 使用可能な濃度変換テーブルハンドルを検索し、tableに格納します */
    for (i = 0; i < AG903_PGP_MGR_MAX_DGC_LUT; i++) {
        if (PgpContext.dgc_lut[i].is_used == false) {
            PgpContext.dgc_lut[i].is_used = true;
            PgpContext.dgc_lut[i].id = AG903_PGP_MGR_DGC_LUT_ID;
            PgpContext.dgc_lut[i].ref_cnt = 0;
            /* 濃度変換テーブルデータを作成します */
            for (j = 0; j < 256; j++) {
                PgpContext.dgc_lut[i].lut_data[0][j] = blue[j];
                PgpContext.dgc_lut[i].lut_data[1][j] = green[j];
                PgpContext.dgc_lut[i].lut_data[2][j] = red[j];
            }
            *table = &PgpContext.dgc_lut[i];
            break;
        }
    }

    PgpContext.num_dgc_lut++;

    return AG903_ENONE;
}


/**
 * @brief         濃度変換テーブル解放
 * @param         table [in] 解放する濃度変換テーブルを指定します。
 * @return        解放結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL tableに不正な値が指定された場合<p>濃度変換テーブルがパイプラインハンドルに関連付けされている場合
 * @description   指定された濃度変換テーブルを解放します。
*/
int32_t AG903_PgpMgrReleaseDGCLUT(AG903_PgpMgrDGCLookupTable *table)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((table == NULL) || (table->id != AG903_PGP_MGR_DGC_LUT_ID)) {
        return -AG903_EINVAL;
    }

    /* パイプラインハンドルに関連付けされている場合はエラーとします */
    if (table->ref_cnt != 0) {
        return -AG903_EINVAL;
    }

    /* 濃度変換テーブルを解放状態にします */
    table->is_used = false;
    table->id = 0;
    PgpContext.num_dgc_lut--;

    return AG903_ENONE;
}


/**
 * @brief         パイプラインハンドルへの濃度変換テーブル関連付け
 * @param         pipeline [in] 濃度変換テーブルと関連付けするパイプラインハンドルを指定します。
 * @param         dgc_lut [in] 関連付けする濃度変換テーブルを指定します。
 * @return        関連付け結果
 * @retval        AG903_ENONE 正常終了
 * @retval        -AG903_EINVAL pipelineに不正な値が指定された場合<p>dgc_lutに不正な値が指定された場合(NULLは除きます)
 * @description   パイプラインハンドルに濃度変換テーブルを関連付けます。
 * @note          table=NULLの場合、パイプラインハンドルとの関連付けを解除します。
*/
int32_t AG903_PgpMgrSetConfigDGCLUT(AG903_PgpMgrPipelineHandle *pipeline, AG903_PgpMgrDGCLookupTable *dgc_lut)
{
    /* ハンドルのIDが不正な場合は無効なハンドルとして処理します */
    if ((pipeline == NULL) || (pipeline->id != AG903_PGP_MGR_PIPELINE_HANDLE_ID)) {
        return -AG903_EINVAL;
    }
    if ((dgc_lut != NULL) && (dgc_lut->id != AG903_PGP_MGR_DGC_LUT_ID)) {
        return -AG903_EINVAL;
    }

    /* 同じテーブルが再設定された場合は何も処理しません */
    if (pipeline->dgc_lut == dgc_lut) {
        return AG903_ENONE;
    }

    if (pipeline->dgc_lut != NULL) {
        pipeline->dgc_lut->ref_cnt--;
        pipeline->dgc_lut = NULL;
    }

    pipeline->dgc_lut = dgc_lut;
    if (dgc_lut != NULL) {
        pipeline->dgc_lut_dirty = true;
        dgc_lut->ref_cnt++;
    }

    return AG903_ENONE;
}
