/* 

 * Copyright (c) 2012-2017 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "test_engine/test.h"
#include <VX/vx.h>
#include <VX/vxu.h>


TESTCASE(ChannelCombine, CT_VXContext, ct_setup_vx_context, 0)


TEST(ChannelCombine, testNodeCreation)
{
    vx_context context = context_->vx_context_;
    vx_image src1_image = 0, src2_image = 0, src3_image = 0, dst_image = 0;
    vx_graph graph = 0;
    vx_node node = 0;

    ASSERT_VX_OBJECT(src1_image = vxCreateImage(context, 128, 128, VX_DF_IMAGE_U8), VX_TYPE_IMAGE);
    ASSERT_VX_OBJECT(src2_image = vxCreateImage(context, 128, 128, VX_DF_IMAGE_U8), VX_TYPE_IMAGE);
    ASSERT_VX_OBJECT(src3_image = vxCreateImage(context, 128, 128, VX_DF_IMAGE_U8), VX_TYPE_IMAGE);

    ASSERT_VX_OBJECT(dst_image = vxCreateImage(context, 128, 128, VX_DF_IMAGE_RGB), VX_TYPE_IMAGE);

    ASSERT_VX_OBJECT(graph = vxCreateGraph(context), VX_TYPE_GRAPH);

    ASSERT_VX_OBJECT(node = vxChannelCombineNode(graph, src1_image, src2_image, src3_image, NULL, dst_image), VX_TYPE_NODE);

    VX_CALL(vxVerifyGraph(graph));

    VX_CALL(vxReleaseNode(&node));
    VX_CALL(vxReleaseGraph(&graph));
    VX_CALL(vxReleaseImage(&dst_image));
    VX_CALL(vxReleaseImage(&src1_image));
    VX_CALL(vxReleaseImage(&src2_image));
    VX_CALL(vxReleaseImage(&src3_image));

    ASSERT(node == 0);
    ASSERT(graph == 0);
    ASSERT(dst_image == 0);
    ASSERT(src1_image == 0);
    ASSERT(src2_image == 0);
    ASSERT(src3_image == 0);
}


static CT_Image channel_combine_image_generate_random(int width, int height, vx_df_image format)
{
    CT_Image image;

    ASSERT_NO_FAILURE_(return 0,
            image = ct_allocate_ct_image_random(width, height, format, &CT()->seed_, 0, 256));

    return image;
}


static void channel_combine_fill_chanel(CT_Image src, vx_enum channel, CT_Image dst)
{
    uint8_t *dst_base = NULL;
    int x, y;

    int plane, component;

    int x_subsampling = ct_image_get_channel_subsampling_x(dst, channel);
    int y_subsampling = ct_image_get_channel_subsampling_y(dst, channel);

    int xstep = ct_image_get_channel_step_x(dst, channel);
    int ystep = ct_image_get_channel_step_y(dst, channel);

    int src_width = dst->width / x_subsampling;
    int src_height = dst->height / y_subsampling;

    // Check that src was subsampled (by spec)
    ASSERT_EQ_INT(src_width, src->width);
    ASSERT_EQ_INT(src_height, src->height);

    ASSERT_NO_FAILURE(plane = ct_image_get_channel_plane(dst, channel));
    ASSERT_NO_FAILURE(component = ct_image_get_channel_component(dst, channel));

    ASSERT(dst_base = ct_image_get_plane_base(dst, plane));

    for (y = 0; y < src_height; y++)
    {
        for (x = 0; x < src_width; x++)
        {
            uint8_t *src_data = CT_IMAGE_DATA_PTR_8U(src, x, y);
            uint8_t *dst_data = dst_base + (x * xstep) + (y * ystep);
            dst_data[component] = *src_data;
        }
    }

    return;
}


static CT_Image channel_combine_create_reference_image(CT_Image src1, CT_Image src2, CT_Image src3, CT_Image src4, vx_df_image format)
{
    CT_Image dst = NULL;

    ASSERT_(return NULL, src1);
    ASSERT_NO_FAILURE_(return NULL, dst = ct_allocate_image(src1->width, src1->height, format));

    switch (format)
    {
        case VX_DF_IMAGE_RGB:
        case VX_DF_IMAGE_RGBX:
            ASSERT_(return NULL, src1);
            ASSERT_(return NULL, src2);
            ASSERT_(return NULL, src3);
            if (format == VX_DF_IMAGE_RGB)
                ASSERT_(return NULL, src4 == NULL);
            ASSERT_NO_FAILURE_(return NULL, channel_combine_fill_chanel(src1, VX_CHANNEL_R, dst));
            ASSERT_NO_FAILURE_(return NULL, channel_combine_fill_chanel(src2, VX_CHANNEL_G, dst));
            ASSERT_NO_FAILURE_(return NULL, channel_combine_fill_chanel(src3, VX_CHANNEL_B, dst));
            if (format == VX_DF_IMAGE_RGBX)
                ASSERT_NO_FAILURE_(return NULL, channel_combine_fill_chanel(src4, VX_CHANNEL_A, dst));
            return dst;
        case VX_DF_IMAGE_NV12:
        case VX_DF_IMAGE_NV21:
        case VX_DF_IMAGE_UYVY:
        case VX_DF_IMAGE_YUYV:
        case VX_DF_IMAGE_IYUV:
        case VX_DF_IMAGE_YUV4:
            ASSERT_(return NULL, src1);
            ASSERT_(return NULL, src2);
            ASSERT_(return NULL, src3);
            ASSERT_(return NULL, src4 == NULL);
            ASSERT_NO_FAILURE_(return NULL, channel_combine_fill_chanel(src1, VX_CHANNEL_Y, dst));
            ASSERT_NO_FAILURE_(return NULL, channel_combine_fill_chanel(src2, VX_CHANNEL_U, dst));
            ASSERT_NO_FAILURE_(return NULL, channel_combine_fill_chanel(src3, VX_CHANNEL_V, dst));
            return dst;
    }

    CT_FAIL_(return NULL, "Not supported");
}

static void channel_combine_check(CT_Image src1, CT_Image src2, CT_Image src3, CT_Image src4, CT_Image dst)
{
    CT_Image dst_ref = NULL;

    ASSERT_NO_FAILURE(dst_ref = channel_combine_create_reference_image(src1, src2, src3, src4, dst->format));

    EXPECT_EQ_CTIMAGE(dst_ref, dst);
#if 0
    if (CT_HasFailure())
    {
#define DUMP_SRC(i) \
        if (src##i) \
        { \
            printf("=== SRC" #i " ===\n"); \
            ct_dump_image_info(src##i); \
        }
        DUMP_SRC(1) DUMP_SRC(2) DUMP_SRC(3) DUMP_SRC(4)
#undef DUMP_SRC
        printf("=== DST ===\n");
        ct_dump_image_info(dst);
        printf("=== EXPECTED ===\n");
        ct_dump_image_info(dst_ref);
    }
#endif
}

typedef struct {
    const char* testName;
    vx_df_image dst_format;
    int width, height;
} Arg;

#define ADD_CASE(testArgName, nextmacro, format, ...) \
    CT_EXPAND(nextmacro(testArgName "/" #format, __VA_ARGS__, format))

#define ADD_CASES(testArgName, nextmacro, ...) \
    ADD_CASE(testArgName, nextmacro, VX_DF_IMAGE_RGB, __VA_ARGS__),  \
    ADD_CASE(testArgName, nextmacro, VX_DF_IMAGE_RGBX, __VA_ARGS__), \
    ADD_CASE(testArgName, nextmacro, VX_DF_IMAGE_NV12, __VA_ARGS__), \
    ADD_CASE(testArgName, nextmacro, VX_DF_IMAGE_NV21, __VA_ARGS__), \
    ADD_CASE(testArgName, nextmacro, VX_DF_IMAGE_UYVY, __VA_ARGS__), \
    ADD_CASE(testArgName, nextmacro, VX_DF_IMAGE_YUYV, __VA_ARGS__), \
    ADD_CASE(testArgName, nextmacro, VX_DF_IMAGE_IYUV, __VA_ARGS__), \
    ADD_CASE(testArgName, nextmacro, VX_DF_IMAGE_YUV4, __VA_ARGS__), \


#define ADD_SIZE(testArgName, nextmacro, ...) \
    CT_EXPAND(nextmacro(testArgName "/sz=16x16", __VA_ARGS__, 16, 16))

#define ChannelCombine_PARAMETERS \
    CT_GENERATE_PARAMETERS("randomInput", ADD_CASES, ADD_SIZE, ARG)

TEST_WITH_ARG(ChannelCombine, testGraphProcessing, Arg,
    ChannelCombine_PARAMETERS
)
{
    vx_context context = context_->vx_context_;
    vx_image src_image[4] = {0, 0, 0, 0};
    vx_image dst_image = 0;
    vx_graph graph = 0;
    vx_node node = 0;

    int channels = 0, i;
    CT_Image src[4] = {NULL, NULL, NULL, NULL};
    CT_Image dst = NULL, dst_dummy = NULL;
    vx_enum channel_ref;

    ASSERT_NO_FAILURE(dst_dummy = ct_allocate_image(4, 4, arg_->dst_format));

    ASSERT_NO_FAILURE(channels = ct_get_num_channels(arg_->dst_format));
    channel_ref = (arg_->dst_format==VX_DF_IMAGE_RGB)||(arg_->dst_format==VX_DF_IMAGE_RGBX)?VX_CHANNEL_R:VX_CHANNEL_Y;
    for (i = 0; i < channels; i++)
    {
        int w = arg_->width / ct_image_get_channel_subsampling_x(dst_dummy, channel_ref + i);
        int h = arg_->height / ct_image_get_channel_subsampling_y(dst_dummy, channel_ref + i);
        ASSERT_NO_FAILURE(src[i] = channel_combine_image_generate_random(w, h, VX_DF_IMAGE_U8));
        ASSERT_VX_OBJECT(src_image[i] = ct_image_to_vx_image(src[i], context), VX_TYPE_IMAGE);
    }

    ASSERT_VX_OBJECT(dst_image = vxCreateImage(context, arg_->width, arg_->height, arg_->dst_format), VX_TYPE_IMAGE);

    graph = vxCreateGraph(context);
    ASSERT_VX_OBJECT(graph, VX_TYPE_GRAPH);

    node = vxChannelCombineNode(graph, src_image[0], src_image[1], src_image[2], src_image[3], dst_image);
    ASSERT_VX_OBJECT(node, VX_TYPE_NODE);

    VX_CALL(vxVerifyGraph(graph));
    VX_CALL(vxProcessGraph(graph));

    ASSERT_NO_FAILURE(dst = ct_image_from_vx_image(dst_image));

    ASSERT_NO_FAILURE(channel_combine_check(src[0], src[1], src[2], src[3], dst));

    VX_CALL(vxReleaseNode(&node));
    VX_CALL(vxReleaseGraph(&graph));

    ASSERT(node == 0);
    ASSERT(graph == 0);

    VX_CALL(vxReleaseImage(&dst_image));
    ASSERT(dst_image == 0);

    for (i = 0; i < channels; i++)
    {
        VX_CALL(vxReleaseImage(&src_image[i]));
        ASSERT(src_image[i] == 0);
    }
}

TEST_WITH_ARG(ChannelCombine, testImmediateProcessing, Arg,
    ChannelCombine_PARAMETERS
)
{
    vx_context context = context_->vx_context_;
    vx_image src_image[4] = {0, 0, 0, 0};
    vx_image dst_image = 0;

    int channels = 0, i;
    CT_Image src[4] = {NULL, NULL, NULL, NULL};
    CT_Image dst = NULL, dst_dummy = NULL;
    vx_enum channel_ref;

    ASSERT_NO_FAILURE(dst_dummy = ct_allocate_image(4, 4, arg_->dst_format));

    ASSERT_NO_FAILURE(channels = ct_get_num_channels(arg_->dst_format));
    channel_ref = (arg_->dst_format==VX_DF_IMAGE_RGB)||(arg_->dst_format==VX_DF_IMAGE_RGBX)?VX_CHANNEL_R:VX_CHANNEL_Y;
    for (i = 0; i < channels; i++)
    {
        int w = arg_->width / ct_image_get_channel_subsampling_x(dst_dummy, channel_ref + i);
        int h = arg_->height / ct_image_get_channel_subsampling_y(dst_dummy, channel_ref + i);
        ASSERT_NO_FAILURE(src[i] = channel_combine_image_generate_random(w, h, VX_DF_IMAGE_U8));
        ASSERT_VX_OBJECT(src_image[i] = ct_image_to_vx_image(src[i], context), VX_TYPE_IMAGE);
    }

    ASSERT_VX_OBJECT(dst_image = vxCreateImage(context, arg_->width, arg_->height, arg_->dst_format), VX_TYPE_IMAGE);

    VX_CALL(vxuChannelCombine(context, src_image[0], src_image[1], src_image[2], src_image[3], dst_image));

    ASSERT_NO_FAILURE(dst = ct_image_from_vx_image(dst_image));

    ASSERT_NO_FAILURE(channel_combine_check(src[0], src[1], src[2], src[3], dst));

    VX_CALL(vxReleaseImage(&dst_image));
    ASSERT(dst_image == 0);

    for (i = 0; i < channels; i++)
    {
        VX_CALL(vxReleaseImage(&src_image[i]));
        ASSERT(src_image[i] == 0);
    }
}

TESTCASE_TESTS(ChannelCombine,
        testNodeCreation,
        testGraphProcessing,
        testImmediateProcessing
)
