Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial support for C wrappers #56

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,16 @@ include(config/LibraryDefine.cmake)

# Include these modules without enable/disable options
add_subdirectory(src/Imath)
# Tell CMake where to find the ImathConfig.cmake file. Makes it posible to call
# Tell CMake where to find the ImathConfig.cmake file. Makes it posible to call
# find_package(Imath) in downstream projects
set(Imath_DIR "${CMAKE_CURRENT_BINARY_DIR}/config" CACHE PATH "" FORCE)
# Add an empty ImathTargets.cmake file for the config to use.
# Add an empty ImathTargets.cmake file for the config to use.
# Can be empty since we already defined the targets in add_subdirectory
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/config/ImathTargets.cmake" "# Dummy file")

if (BUILD_CIMATH)
add_subdirectory(src/CImath)
endif()

option(PYTHON "Set ON to compile PyImath bindings")
if (PYTHON)
Expand All @@ -59,7 +62,7 @@ endif()
# upload the results, cmake has builtin support for
# submitting to CDash, or any server who speaks the
# same protocol
#
#
# These settings will need to be set for your environment,
# and then a script such as the example in
#
Expand All @@ -70,7 +73,7 @@ endif()
# cmake -S cmake/SampleCTestScript.cmake
#
# [or whatever you name the file you edit]
#
#
#set(CTEST_PROJECT_NAME "Imath")
#set(CTEST_NIGHTLY_START_TIME "01:01:01 UTC")
#set(CTEST_DROP_METHOD "http") # there are others...
Expand All @@ -83,6 +86,10 @@ if(BUILD_TESTING)
enable_testing()

add_subdirectory(src/ImathTest)

if (BUILD_CIMATH)
add_subdirectory(src/CImathTest)
endif()
endif()

# Including this module will add a `clang-format` target to the build if
Expand Down
2 changes: 2 additions & 0 deletions config/ImathSetup.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ endif()
########################
## Build related options

option(BUILD_CIMATH "Build C interface library" ON)

# This is a variable here for use in install lines. Care must be taken
# when changing this, as many things assume this is Imath
set(IMATH_OUTPUT_SUBDIR Imath CACHE STRING "Destination sub-folder of the include path for install")
Expand Down
19 changes: 19 additions & 0 deletions src/CImath/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.

add_library(CImath SHARED
chalf.h
chalf.cpp
)

target_link_libraries(CImath PUBLIC Imath)

set(public_headers
chalf.h
)

install(TARGETS CImath)
install(FILES ${public_headers}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/CImath
COMPONENT developer
)
31 changes: 31 additions & 0 deletions src/CImath/chalf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <../Imath/half.h>

#include "chalf.h"

static_assert (sizeof (IMATH_NAMESPACE::half) == sizeof (imath_half));

extern "C"
{
imath_half imath_half_create (float f)
{
IMATH_NAMESPACE::half h (f);
imath_half* c_h = reinterpret_cast<imath_half*> (&h);

return *c_h;
}

imath_half imath_half_copy (const imath_half* h)
{
imath_half h_copy;
h_copy._h = h->_h;

return h_copy;
}

float imath_half_toFloat (const imath_half* h)
{
const IMATH_NAMESPACE::half* cpp_h = reinterpret_cast<const IMATH_NAMESPACE::half*> (h);
float f (*cpp_h);
return f;
}
}
24 changes: 24 additions & 0 deletions src/CImath/chalf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef _CHALF_H_
#define _CHALF_H_

#ifdef __cplusplus
extern "C"
{
#endif

typedef struct
{
unsigned short _h;
} imath_half;

// Constructors
imath_half imath_half_create (float f);
imath_half imath_half_copy (const imath_half* h);

// Conversion to float
float imath_half_toFloat (const imath_half* h);

#ifdef __cplusplus
}
#endif
#endif
25 changes: 25 additions & 0 deletions src/CImathTest/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.

add_executable(CImathTest_Cpp
testCImath.cpp
)

target_link_libraries(CImathTest_Cpp CImath Imath)
set_target_properties(CImathTest_Cpp PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
add_test(NAME CImath_Cpp COMMAND $<TARGET_FILE:CImathTest_Cpp>)

project(CImathTest_C C)

add_executable(CImathTest_C
testCImath.c
)

target_link_libraries(CImathTest_C CImath Imath)
set_target_properties(CImathTest_C PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
add_test(NAME CImath_C COMMAND $<TARGET_FILE:CImathTest_C>)
set_property(TARGET CImathTest_C PROPERTY C_STANDARD 99)
48 changes: 48 additions & 0 deletions src/CImathTest/testCImath.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include <float.h>
#include <math.h>
#include <stdio.h>
#include <string.h>

#include "../CImath/chalf.h"

#define TEST(x) \
if (argc < 2 || !strcmp (argv[1], #x)) \
{ \
int result = x(); \
\
if (result != 0) \
{ \
return result; \
} \
}

const float test_values[] = { 1.0, 0.0, -1.0, 123.0, 1234.0, 0.25 };

int
testHalfToFloat()
{
printf ("Create float from half\n");

for (int i = 0; i < (sizeof (test_values) / sizeof (test_values[0])); i++)
{
float f_in = test_values[i];
imath_half h = imath_half_create (f_in);
float f_out = imath_half_toFloat (&h);

if (fabs (f_in - f_out) > FLT_EPSILON)
{
printf ("%f != %f\n", f_in, f_out);
return 1;
}
}

return 0;
}

int
main (int argc, char* argv[])
{
TEST (testHalfToFloat);

return 0;
}
81 changes: 81 additions & 0 deletions src/CImathTest/testCImath.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright Contributors to the OpenEXR Project.
//

#ifdef NDEBUG
# undef NDEBUG
#endif

#include "../CImath/chalf.h"
#include "../Imath/half.h"
#include <assert.h>
#include <cstring>
#include <iostream>
#include <string.h>
#include <vector>

#define TEST(x) \
if (argc < 2 || !strcmp (argv[1], #x)) \
x();

using namespace std;

static const vector<float> test_values = { 1.0, 0.0, -1.0, 123.0, 123456789.0, 0.123456789 };

union CpptoC
{
Imath::half cpp;
imath_half c;
};

void
testHalfCreate()
{
cout << "Create half from float" << endl;
cout << "h1 == h2" << endl;

for (float f : test_values)
{
Imath::half h1 (f);
imath_half h2 = imath_half_create (f);
char* h1_c = reinterpret_cast<char*> (&h1);
char* h2_c = reinterpret_cast<char*> (&h2);

assert (memcmp (h1_c, h2_c, sizeof (Imath::half)) == 0);
}

cout << "ok\n\n" << flush;
}

void
testHalfCopy()
{
cout << "Copy half" << endl;
cout << "h1 == h2" << endl;

for (float f : test_values)
{
Imath::half h1 (f);
CpptoC cpptoc;
cpptoc.cpp = h1;
imath_half h2 = imath_half_copy (&cpptoc.c);
char* h1_c = reinterpret_cast<char*> (&h1);
char* h2_c = reinterpret_cast<char*> (&h2);

assert (memcmp (h1_c, h2_c, sizeof (Imath::half)) == 0);
}

cout << "ok\n\n" << flush;
}

int
main (int argc, char* argv[])
{
std::cout << "\ntesting type half:\n\n" << std::flush;

TEST (testHalfCreate);
TEST (testHalfCopy);

return 0;
}