static void
TestFIA_ErosionTest(CuTest* tc)
{
	const char *file = TEST_DATA_DIR "\\morpholology_test.bmp";

	FIBITMAP *dib1 = FIA_LoadFIBFromFile(file);
	
	CuAssertTrue(tc, dib1 != NULL);
	
	FIBITMAP *threshold_dib = FreeImage_Threshold(dib1, 20);

	CuAssertTrue(tc, threshold_dib != NULL);

	FIBITMAP *threshold_8bit_dib = FreeImage_ConvertTo8Bits(threshold_dib);

	CuAssertTrue(tc, threshold_8bit_dib != NULL);

	FIABITMAP *border_dib = FIA_SetBorder(threshold_8bit_dib, 2, 2
        , BorderType_Constant, 0.0);

	PROFILE_START("ErosionFilter");

	FilterKernel kernel = FIA_NewKernel(2, 2, kernel_values, 1.0);

	FIBITMAP* result_dib = FIA_BinaryErosion(border_dib, kernel);

	CuAssertTrue(tc, result_dib != NULL);

	PROFILE_STOP("ErosionFilter");

	FIA_SaveFIBToFile(result_dib, TEST_DATA_OUTPUT_DIR "\\erosion_result.jpg", BIT24);

	result_dib = FIA_BinaryInnerBorder(threshold_8bit_dib);

	FIA_SimpleSaveFIBToFile(result_dib, TEST_DATA_OUTPUT_DIR "morphology/inner_border_result.bmp");

	FreeImage_Unload(dib1);
	FreeImage_Unload(threshold_dib);
	FreeImage_Unload(threshold_8bit_dib);
	FIA_Unload(border_dib);
	FreeImage_Unload(result_dib);
}
/*
static inline int __cdecl
ComparePoints (const void *element1, const void *element2)
{
    FIAPOINT point1 = *(FIAPOINT *) element1;
    FIAPOINT point2 = *(FIAPOINT *) element2;

    if (point1.x > point2.x)
    {
        return 1;
    }
    else if (point1.x < point2.x)
    {
        return -1;
    }
    else
    {
        // Same x sort by y
        if (point1.y > point2.y)
        {
            return 1;
        }
        else if (point1.y < point2.y)
        {
            return -1;
        }
    }

    return 0;
}
*/
FIBITMAP *DLL_CALLCONV
FreeImage_ConvexHull (FIBITMAP * src)
{
	FIBITMAP *tmp = FIA_BinaryInnerBorder(src);
	FIA_InPlaceConvertToGreyscaleFloatType(&tmp, FIT_FLOAT);
    
	int width = FreeImage_GetWidth (tmp);
    int height = FreeImage_GetHeight (tmp);

    FIBITMAP *dst = FreeImage_Allocate (width, height, 8, 0, 0, 0);

    FIA_SetGreyLevelPalette (dst);

    FIAPOINT *sort_array = new FIAPOINT[width * height];
    FIAPOINT *hull_array = new FIAPOINT[width * height];

    float *ptr;
    register int i = 0;

    FIAPOINT pt;

    // Copy image pixels to 1d array
    for(register int y = 0; y < height; y++)
    {
        ptr = (float *) FreeImage_GetScanLine (tmp, y);

        for(register int x = 0; x < width; x++)
        {
            if (ptr[x])
            {
                pt.x = x;
                pt.y = y;
                sort_array[i++] = pt;
            }
        }
    }

    // sort the array by x and then y
    // Sort the peaks
 //   qsort (sort_array, i, sizeof (FIAPOINT), ComparePoints);
	// Should be already sorted in creating the point set

    int number_of_points = ChainHull_2D (sort_array, i, hull_array);

    delete sort_array;

//	FIA_DrawSolidGreyscalePolygon (dst, hull_array, number_of_points, 255, 0);
	
	// replace the above command with this more predictable loop
	for (int i=0; i<number_of_points-1; i++) {
		FIA_DrawOnePixelIndexLineFromTopLeft (dst, hull_array[i], hull_array[i+1], 255);
	}
	FIA_DrawOnePixelIndexLineFromTopLeft (dst, hull_array[number_of_points-1], hull_array[0], 255);
	dst = FIA_Fillholes(dst, 1);
	FreeImage_FlipVertical(dst);   // FIA_Draw is not from top,left

	delete hull_array;

    FreeImage_Unload (tmp);

    return dst;
}