blob: 3724072b2772d7fecd213903469a11c2eab1ef79 [file] [log] [blame]
/*
* 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>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
static void reference_eqhist(CT_Image src, CT_Image dst)
{
int i, j, i0 = -1, hist[256];
uint32_t x, y, width, height, srcstride, dststride, delta = 0, scale = 1;
uint8_t lut[256];
ASSERT(src && dst);
ASSERT(src->format == VX_DF_IMAGE_U8 && dst->format == VX_DF_IMAGE_U8);
ASSERT(src->width > 0 && src->height > 0 &&
src->width == dst->width && src->height == dst->height);
width = src->width;
height = src->height;
srcstride = ct_stride_bytes(src);
dststride = ct_stride_bytes(dst);
for( i = 0; i < 256; i++ )
hist[i] = 0;
for( y = 0; y < height; y++ )
{
const uint8_t* srcptr = src->data.y + y*srcstride;
for( x = 0; x < width; x++ )
hist[srcptr[x]]++;
}
for( i = 0; i < 256; i++ )
{
if( i0 < 0 && hist[i] > 0 )
{
i0 = i;
delta = hist[i0];
scale = width*height - delta;
if( scale == 0 )
{
// if all the pixels are equal, leave the image as-is
for( j = 0; j < 256; j++ )
lut[j] = j;
break;
}
}
hist[i] += i > 0 ? hist[i-1] : 0;
if( i0 < 0 )
lut[i] = 0;
else
{
int val = (int)(((hist[i] - delta)*255 + scale/2)/scale);
lut[i] = CT_CAST_U8(val);
}
}
for( y = 0; y < height; y++ )
{
const uint8_t* srcptr = src->data.y + y*srcstride;
uint8_t* dstptr = dst->data.y + y*dststride;
for( x = 0; x < width; x++ )
dstptr[x] = lut[srcptr[x]];
}
}
TESTCASE(EqualizeHistogram, CT_VXContext, ct_setup_vx_context, 0)
typedef struct {
const char* name;
int mode;
vx_df_image format;
} format_arg;
#define MAX_BINS 256
#define EQHIST_TEST_CASE(imm, tp) \
{#imm "/" #tp, CT_##imm##_MODE, VX_DF_IMAGE_##tp}
TEST_WITH_ARG(EqualizeHistogram, testOnRandom, format_arg,
EQHIST_TEST_CASE(Immediate, U8),
EQHIST_TEST_CASE(Graph, U8),
)
{
int format = arg_->format;
int mode = arg_->mode;
vx_image src, dst;
vx_node node = 0;
vx_graph graph = 0;
CT_Image src0, dst0, dst1;
vx_context context = context_->vx_context_;
int iter, niters = 100;
uint64_t rng;
int a = 0, b = 256;
rng = CT()->seed_;
for( iter = 0; iter < niters; iter++ )
{
int width, height;
if( ct_check_any_size() )
{
width = ct_roundf(ct_log_rng(&rng, 0, 10));
height = ct_roundf(ct_log_rng(&rng, 0, 10));
width = CT_MAX(width, 1);
height = CT_MAX(height, 1);
}
else
{
width = 640;
height = 480;
}
ct_update_progress(iter, niters);
ASSERT_NO_FAILURE(src0 = ct_allocate_ct_image_random(width, height, format, &rng, a, b));
if( iter % 20 == 0 )
{
uint8_t val = (uint8_t)CT_RNG_NEXT_INT(rng, a, b);
ct_memset(src0->data.y, val, ct_stride_bytes(src0)*src0->height);
}
ASSERT_NO_FAILURE(dst0 = ct_allocate_image(width, height, format));
ASSERT_NO_FAILURE(reference_eqhist(src0, dst0));
src = ct_image_to_vx_image(src0, context);
dst = vxCreateImage(context, width, height, format);
ASSERT_VX_OBJECT(dst, VX_TYPE_IMAGE);
if( mode == CT_Immediate_MODE )
{
ASSERT_EQ_VX_STATUS(VX_SUCCESS, vxuEqualizeHist(context, src, dst));
}
else
{
graph = vxCreateGraph(context);
ASSERT_VX_OBJECT(graph, VX_TYPE_GRAPH);
node = vxEqualizeHistNode(graph, src, dst);
ASSERT_VX_OBJECT(node, VX_TYPE_NODE);
VX_CALL(vxVerifyGraph(graph));
VX_CALL(vxProcessGraph(graph));
}
dst1 = ct_image_from_vx_image(dst);
ASSERT_CTIMAGE_NEAR(dst0, dst1, 1);
VX_CALL(vxReleaseImage(&src));
VX_CALL(vxReleaseImage(&dst));
if(node)
VX_CALL(vxReleaseNode(&node));
if(graph)
VX_CALL(vxReleaseGraph(&graph));
ASSERT(node == 0 && graph == 0);
CT_CollectGarbage(CT_GC_IMAGE);
}
}
TESTCASE_TESTS(EqualizeHistogram, testOnRandom)