diff --git a/.gitignore b/.gitignore index 378eac2..23934e0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,7 @@ build +.vs +Debug +Release +x86 +x64 +libcorrect.VC.db diff --git a/CMakeLists.txt b/CMakeLists.txt index bef9687..afc1fde 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,17 +1,23 @@ cmake_minimum_required(VERSION 2.8) -project(Correct) +project(Correct C) include(CheckLibraryExists) include(CheckIncludeFiles) -include(CheckCXXSourceCompiles) +include(CheckCSourceCompiles) +include(CMakePushCheckState) +include(CheckCCompilerFlag) if(MSVC) set(LIBM "") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") else(MSVC) set(LIBM "m") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -std=c99 -Wpedantic -Wall") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -std=c99 -Wall") +check_c_compiler_flag(-Wpedantic COMPILER_SUPPORTS_WPEDANTIC) +if(COMPILER_SUPPORTS_WPEDANTIC) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic") +endif() if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3 -O0 -march=native -fsanitize=address") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g3 -O0 -fsanitize=address") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-no_pie,") else() if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") @@ -27,15 +33,22 @@ endif(MSVC) find_library(FEC fec) CHECK_LIBRARY_EXISTS(FEC dotprod "" HAVE_LIBFEC) -check_cxx_source_compiles(" - #include - int main() { - __m128i vec; - return 0; - }" HAVE_SSE) + +# Check if host machine can compile with SSE 4.1 intrinsic +cmake_push_check_state(RESET) +set(CMAKE_REQUIRED_DEFINITIONS -march=native) +check_c_source_compiles(" + #include + int main() { + __m128i a; + __m128i b; + __m128i c = _mm_min_epu16(a, b); + return 0; + }" HAVE_SSE) +cmake_pop_check_state() if(HAVE_SSE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.2") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.1") endif() set(CMAKE_CXX_VISIBILITY_PRESET hidden) @@ -54,13 +67,16 @@ if(HAVE_SSE) set(correct_obj_files $ $ $) set(INSTALL_HEADERS ${INSTALL_HEADERS} ${PROJECT_BINARY_DIR}/include/correct-sse.h) add_custom_target(correct-sse-h ALL COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/include/correct-sse.h ${PROJECT_BINARY_DIR}/include/correct-sse.h) - add_definitions(-DHAVE_SSE=1) else() set(correct_obj_files $ $) endif() add_library(correct SHARED ${correct_obj_files}) add_library(correct_static ${correct_obj_files}) set_target_properties(correct_static PROPERTIES OUTPUT_NAME "correct") +if(HAVE_SSE) + target_compile_definitions(correct PUBLIC HAVE_SSE=1) + target_compile_definitions(correct_static PUBLIC HAVE_SSE=1) +endif() add_subdirectory(util) add_subdirectory(tests) @@ -81,4 +97,13 @@ add_custom_target(shim DEPENDS fec_shim_static fec_shim_shared fec-shim-h) install(TARGETS fec_shim_static fec_shim_shared DESTINATION lib OPTIONAL) + install(FILES ${PROJECT_BINARY_DIR}/include/fec.h DESTINATION "${CMAKE_INSTALL_PREFIX}/include" OPTIONAL) + +# Debian Package +SET(CPACK_GENERATOR "DEB") +SET(CPACK_PACKAGE_NAME "libcorrect") +SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Brian Armstrong ") +SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION "C library for Convolutional codes and Reed-Solomon") +INCLUDE(CPack) + diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..7e0d32c --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +libcorrect (1.0-0ppa0) xenial; urgency=low + + * First PPA Package + + -- Lucas Teske Tue, 05 Jun 2018 21:52:07 -0300 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..b76bd43 --- /dev/null +++ b/debian/control @@ -0,0 +1,13 @@ +Source: libcorrect +Section: devel +Priority: optional +Maintainer: Brian Armstrong +Build-Depends: cmake, build-essential +Homepage: https://github.com/quiet/libcorrect + +Package: libcorrect +Architecture: any +Depends: +Description: libcorrect is a library for Forward Error Correction. + By using libcorrect, you can encode extra redundancy into a packet of data and then send it across a lossy channel. + When the packet is received, it can be decoded to recover the original, pre-encoded data. \ No newline at end of file diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..8bb8fad --- /dev/null +++ b/debian/copyright @@ -0,0 +1,12 @@ +Copyright (c) 2016, Brian Armstrong +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/debian/files b/debian/files new file mode 100644 index 0000000..505ffc8 --- /dev/null +++ b/debian/files @@ -0,0 +1 @@ +libcorrect_1.0-0ppa0_source.buildinfo devel optional diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..48dbef1 --- /dev/null +++ b/debian/rules @@ -0,0 +1,28 @@ +#!/usr/bin/make -f + +BUILDDIR = build_dir + +# secondly called by launchpad +build: + mkdir $(BUILDDIR); + cd $(BUILDDIR); cmake -DCMAKE_INSTALL_PREFIX=../debian/tmp/usr .. + make -C $(BUILDDIR) + +# thirdly called by launchpad +binary: binary-indep binary-arch + +binary-indep: + # nothing to be done + +binary-arch: + cd $(BUILDDIR); cmake -P cmake_install.cmake + mkdir debian/tmp/DEBIAN + dpkg-gencontrol -plibcorrect + dpkg --build debian/tmp .. + +# firstly called by launchpad +clean: + rm -rf build + rm -rf $(BUILDDIR) + +.PHONY: binary binary-arch binary-indep clean diff --git a/include/correct.h b/include/correct.h index 12d817d..32fb660 100644 --- a/include/correct.h +++ b/include/correct.h @@ -3,14 +3,19 @@ #include #ifndef _MSC_VER -#include +# include +# ifdef __MINGW32__ +# define ssize_t int +# endif +# define DLL_EXPORT #else -#include +# define DLL_EXPORT extern __declspec(dllexport) +# include +# define __builtin_popcount __popcnt +# include typedef ptrdiff_t ssize_t; #endif - - // Convolutional Codes // Convolutional polynomials are 16 bits wide @@ -41,14 +46,14 @@ typedef struct correct_convolutional correct_convolutional; * * If this call is successful, it returns a non-NULL pointer. */ -correct_convolutional *correct_convolutional_create(size_t inv_rate, size_t order, +DLL_EXPORT correct_convolutional *correct_convolutional_create(size_t inv_rate, size_t order, const correct_convolutional_polynomial_t *poly); /* correct_convolutional_destroy releases all resources associated * with conv. This pointer should not be used for further calls * after calling destroy. */ -void correct_convolutional_destroy(correct_convolutional *conv); +DLL_EXPORT void correct_convolutional_destroy(correct_convolutional *conv); /* correct_convolutional_encode_len returns the number of *bits* * in a msg_len of given size, in *bytes*. In order to convert @@ -57,7 +62,7 @@ void correct_convolutional_destroy(correct_convolutional *conv); * length/8 + 1. If it is zero, then the length is just * length/8. */ -size_t correct_convolutional_encode_len(correct_convolutional *conv, size_t msg_len); +DLL_EXPORT size_t correct_convolutional_encode_len(correct_convolutional *conv, size_t msg_len); /* correct_convolutional_encode uses the given conv instance to * encode a block of data and write it to encoded. The length of @@ -70,7 +75,7 @@ size_t correct_convolutional_encode_len(correct_convolutional *conv, size_t msg_ * this is not an exact multiple of 8, then it occupies an additional * byte. */ -size_t correct_convolutional_encode(correct_convolutional *conv, const uint8_t *msg, size_t msg_len, +DLL_EXPORT size_t correct_convolutional_encode(correct_convolutional *conv, const uint8_t *msg, size_t msg_len, uint8_t *encoded); /* correct_convolutional_decode uses the given conv instance to @@ -96,7 +101,7 @@ size_t correct_convolutional_encode(correct_convolutional *conv, const uint8_t * * This function returns the number of bytes written to msg. If * it fails, it returns -1. */ -ssize_t correct_convolutional_decode(correct_convolutional *conv, const uint8_t *encoded, +DLL_EXPORT ssize_t correct_convolutional_decode(correct_convolutional *conv, const uint8_t *encoded, size_t num_encoded_bits, uint8_t *msg); /* correct_convolutional_decode_soft uses the given conv instance @@ -120,7 +125,7 @@ ssize_t correct_convolutional_decode(correct_convolutional *conv, const uint8_t * This function returns the number of bytes written to msg. If * it fails, it returns -1. */ -ssize_t correct_convolutional_decode_soft(correct_convolutional *conv, +DLL_EXPORT ssize_t correct_convolutional_decode_soft(correct_convolutional *conv, const correct_convolutional_soft_t *encoded, size_t num_encoded_bits, uint8_t *msg); @@ -195,7 +200,7 @@ static const uint16_t correct_rs_primitive_polynomial_ccsds = * generator_root_gap are 1 and 1. Not all combinations of * values produce valid codes. */ -correct_reed_solomon *correct_reed_solomon_create(uint16_t primitive_polynomial, +DLL_EXPORT correct_reed_solomon *correct_reed_solomon_create(uint16_t primitive_polynomial, uint8_t first_consecutive_root, uint8_t generator_root_gap, size_t num_roots); @@ -214,7 +219,7 @@ correct_reed_solomon *correct_reed_solomon_create(uint16_t primitive_polynomial, * * This function returns the number of bytes written to encoded. */ -ssize_t correct_reed_solomon_encode(correct_reed_solomon *rs, const uint8_t *msg, size_t msg_length, +DLL_EXPORT ssize_t correct_reed_solomon_encode(correct_reed_solomon *rs, const uint8_t *msg, size_t msg_length, uint8_t *encoded); /* correct_reed_solomon_decode uses the rs instance to decode @@ -232,7 +237,7 @@ ssize_t correct_reed_solomon_encode(correct_reed_solomon *rs, const uint8_t *msg * This function returns a positive number of bytes written to msg * if it has decoded or -1 if it has encountered an error. */ -ssize_t correct_reed_solomon_decode(correct_reed_solomon *rs, const uint8_t *encoded, +DLL_EXPORT ssize_t correct_reed_solomon_decode(correct_reed_solomon *rs, const uint8_t *encoded, size_t encoded_length, uint8_t *msg); /* correct_reed_solomon_decode_with_erasures uses the rs @@ -262,7 +267,7 @@ ssize_t correct_reed_solomon_decode(correct_reed_solomon *rs, const uint8_t *enc * This function returns a positive number of bytes written to msg * if it has decoded or -1 if it has encountered an error. */ -ssize_t correct_reed_solomon_decode_with_erasures(correct_reed_solomon *rs, const uint8_t *encoded, +DLL_EXPORT ssize_t correct_reed_solomon_decode_with_erasures(correct_reed_solomon *rs, const uint8_t *encoded, size_t encoded_length, const uint8_t *erasure_locations, size_t erasure_length, uint8_t *msg); @@ -271,7 +276,7 @@ ssize_t correct_reed_solomon_decode_with_erasures(correct_reed_solomon *rs, cons * associated with rs. This pointer should not be * used for any functions after this call. */ -void correct_reed_solomon_destroy(correct_reed_solomon *rs); +DLL_EXPORT void correct_reed_solomon_destroy(correct_reed_solomon *rs); #endif diff --git a/include/correct/convolutional/bit.h b/include/correct/convolutional/bit.h index 6483898..2a8c840 100644 --- a/include/correct/convolutional/bit.h +++ b/include/correct/convolutional/bit.h @@ -10,19 +10,19 @@ typedef struct { size_t len; } bit_writer_t; -bit_writer_t *bit_writer_create(uint8_t *bytes, size_t len); +DLL_EXPORT bit_writer_t *bit_writer_create(uint8_t *bytes, size_t len); -void bit_writer_reconfigure(bit_writer_t *w, uint8_t *bytes, size_t len); +DLL_EXPORT void bit_writer_reconfigure(bit_writer_t *w, uint8_t *bytes, size_t len); -void bit_writer_destroy(bit_writer_t *w); +DLL_EXPORT void bit_writer_destroy(bit_writer_t *w); -void bit_writer_write(bit_writer_t *w, uint8_t val, unsigned int n); +DLL_EXPORT void bit_writer_write(bit_writer_t *w, uint8_t val, unsigned int n); -void bit_writer_write_1(bit_writer_t *w, uint8_t val); +DLL_EXPORT void bit_writer_write_1(bit_writer_t *w, uint8_t val); -void bit_writer_write_bitlist_reversed(bit_writer_t *w, uint8_t *l, size_t len); +DLL_EXPORT void bit_writer_write_bitlist_reversed(bit_writer_t *w, uint8_t *l, size_t len); -void bit_writer_flush_byte(bit_writer_t *w); +DLL_EXPORT void bit_writer_flush_byte(bit_writer_t *w); size_t bit_writer_length(bit_writer_t *w); @@ -34,11 +34,11 @@ typedef struct { const uint8_t *bytes; } bit_reader_t; -bit_reader_t *bit_reader_create(const uint8_t *bytes, size_t len); +DLL_EXPORT bit_reader_t *bit_reader_create(const uint8_t *bytes, size_t len); -void bit_reader_reconfigure(bit_reader_t *r, const uint8_t *bytes, size_t len); +DLL_EXPORT void bit_reader_reconfigure(bit_reader_t *r, const uint8_t *bytes, size_t len); -void bit_reader_destroy(bit_reader_t *r); +DLL_EXPORT void bit_reader_destroy(bit_reader_t *r); -uint8_t bit_reader_read(bit_reader_t *r, unsigned int n); +DLL_EXPORT uint8_t bit_reader_read(bit_reader_t *r, unsigned int n); #endif diff --git a/include/correct/convolutional/convolutional.h b/include/correct/convolutional/convolutional.h index b0f66f0..03c3da4 100644 --- a/include/correct/convolutional/convolutional.h +++ b/include/correct/convolutional/convolutional.h @@ -7,6 +7,11 @@ #include "correct/convolutional/history_buffer.h" #include "correct/convolutional/error_buffer.h" +#ifdef _MSC_VER +# include +# define __builtin_popcount __popcnt +#endif + struct correct_convolutional { const unsigned int *table; // size 2**order size_t rate; // e.g. 2, 3... @@ -23,18 +28,18 @@ struct correct_convolutional { error_buffer_t *errors; }; -correct_convolutional *_correct_convolutional_init(correct_convolutional *conv, +DLL_EXPORT correct_convolutional *_correct_convolutional_init(correct_convolutional *conv, size_t rate, size_t order, const polynomial_t *poly); -void _correct_convolutional_teardown(correct_convolutional *conv); +DLL_EXPORT void _correct_convolutional_teardown(correct_convolutional *conv); // portable versions -void _convolutional_decode_init(correct_convolutional *conv, unsigned int min_traceback, unsigned int traceback_length, unsigned int renormalize_interval); -void convolutional_decode_warmup(correct_convolutional *conv, unsigned int sets, +DLL_EXPORT void _convolutional_decode_init(correct_convolutional *conv, unsigned int min_traceback, unsigned int traceback_length, unsigned int renormalize_interval); +DLL_EXPORT void convolutional_decode_warmup(correct_convolutional *conv, unsigned int sets, const uint8_t *soft); -void convolutional_decode_inner(correct_convolutional *conv, unsigned int sets, +DLL_EXPORT void convolutional_decode_inner(correct_convolutional *conv, unsigned int sets, const uint8_t *soft); -void convolutional_decode_tail(correct_convolutional *conv, unsigned int sets, +DLL_EXPORT void convolutional_decode_tail(correct_convolutional *conv, unsigned int sets, const uint8_t *soft); #endif diff --git a/include/correct/convolutional/error_buffer.h b/include/correct/convolutional/error_buffer.h index 12e3f75..f055b69 100644 --- a/include/correct/convolutional/error_buffer.h +++ b/include/correct/convolutional/error_buffer.h @@ -9,7 +9,7 @@ typedef struct { distance_t *write_errors; } error_buffer_t; -error_buffer_t *error_buffer_create(unsigned int num_states); -void error_buffer_destroy(error_buffer_t *buf); -void error_buffer_reset(error_buffer_t *buf); -void error_buffer_swap(error_buffer_t *buf); +DLL_EXPORT error_buffer_t *error_buffer_create(unsigned int num_states); +DLL_EXPORT void error_buffer_destroy(error_buffer_t *buf); +DLL_EXPORT void error_buffer_reset(error_buffer_t *buf); +DLL_EXPORT void error_buffer_swap(error_buffer_t *buf); diff --git a/include/correct/convolutional/history_buffer.h b/include/correct/convolutional/history_buffer.h index ca01e21..9a142e7 100644 --- a/include/correct/convolutional/history_buffer.h +++ b/include/correct/convolutional/history_buffer.h @@ -37,23 +37,23 @@ typedef struct { unsigned int renormalize_counter; } history_buffer; -history_buffer *history_buffer_create(unsigned int min_traceback_length, +DLL_EXPORT history_buffer *history_buffer_create(unsigned int min_traceback_length, unsigned int traceback_group_length, unsigned int renormalize_interval, unsigned int num_states, shift_register_t highbit); -void history_buffer_destroy(history_buffer *buf); -void history_buffer_reset(history_buffer *buf); -void history_buffer_step(history_buffer *buf); -uint8_t *history_buffer_get_slice(history_buffer *buf); -shift_register_t history_buffer_search(history_buffer *buf, +DLL_EXPORT void history_buffer_destroy(history_buffer *buf); +DLL_EXPORT void history_buffer_reset(history_buffer *buf); +DLL_EXPORT void history_buffer_step(history_buffer *buf); +DLL_EXPORT uint8_t *history_buffer_get_slice(history_buffer *buf); +DLL_EXPORT shift_register_t history_buffer_search(history_buffer *buf, const distance_t *distances, unsigned int search_every); -void history_buffer_traceback(history_buffer *buf, shift_register_t bestpath, +DLL_EXPORT void history_buffer_traceback(history_buffer *buf, shift_register_t bestpath, unsigned int min_traceback_length, bit_writer_t *output); -void history_buffer_process_skip(history_buffer *buf, distance_t *distances, +DLL_EXPORT void history_buffer_process_skip(history_buffer *buf, distance_t *distances, bit_writer_t *output, unsigned int skip); -void history_buffer_process(history_buffer *buf, distance_t *distances, +DLL_EXPORT void history_buffer_process(history_buffer *buf, distance_t *distances, bit_writer_t *output); -void history_buffer_flush(history_buffer *buf, bit_writer_t *output); +DLL_EXPORT void history_buffer_flush(history_buffer *buf, bit_writer_t *output); diff --git a/include/correct/convolutional/lookup.h b/include/correct/convolutional/lookup.h index c257389..f45b6d3 100644 --- a/include/correct/convolutional/lookup.h +++ b/include/correct/convolutional/lookup.h @@ -2,6 +2,11 @@ #define CORRECT_CONVOLUTIONAL_LOOKUP #include "correct/convolutional.h" +#ifdef _MSC_VER +# include +# define __builtin_popcount __popcnt +#endif + typedef unsigned int distance_pair_key_t; typedef uint32_t output_pair_t; typedef uint32_t distance_pair_t; @@ -15,13 +20,13 @@ typedef struct { distance_pair_t *distances; } pair_lookup_t; -void fill_table(unsigned int order, +DLL_EXPORT void fill_table(unsigned int order, unsigned int rate, const polynomial_t *poly, unsigned int *table); -pair_lookup_t pair_lookup_create(unsigned int rate, +DLL_EXPORT pair_lookup_t pair_lookup_create(unsigned int rate, unsigned int order, const unsigned int *table); -void pair_lookup_destroy(pair_lookup_t pairs); -void pair_lookup_fill_distance(pair_lookup_t pairs, distance_t *distances); +DLL_EXPORT void pair_lookup_destroy(pair_lookup_t pairs); +DLL_EXPORT void pair_lookup_fill_distance(pair_lookup_t pairs, distance_t *distances); #endif diff --git a/include/correct/convolutional/metric.h b/include/correct/convolutional/metric.h index 5e1cd55..e4d6ef7 100644 --- a/include/correct/convolutional/metric.h +++ b/include/correct/convolutional/metric.h @@ -17,4 +17,4 @@ static inline distance_t metric_soft_distance_linear(unsigned int hard_x, const return dist; } -distance_t metric_soft_distance_quadratic(unsigned int hard_x, const uint8_t *soft_y, size_t len); +DLL_EXPORT distance_t metric_soft_distance_quadratic(unsigned int hard_x, const uint8_t *soft_y, size_t len); diff --git a/include/correct/convolutional/sse/convolutional.h b/include/correct/convolutional/sse/convolutional.h index bf4ad88..0ea0677 100644 --- a/include/correct/convolutional/sse/convolutional.h +++ b/include/correct/convolutional/sse/convolutional.h @@ -3,12 +3,12 @@ // BIG HEAPING TODO sort out the include mess #include "correct-sse.h" #ifdef _MSC_VER -#include +# include +# define __builtin_popcount __popcnt #else #include #endif - struct correct_convolutional_sse { correct_convolutional base_conv; oct_lookup_t oct_lookup; diff --git a/include/correct/reed-solomon/polynomial.h b/include/correct/reed-solomon/polynomial.h index e084e11..e60f50b 100644 --- a/include/correct/reed-solomon/polynomial.h +++ b/include/correct/reed-solomon/polynomial.h @@ -1,14 +1,14 @@ #include "correct/reed-solomon.h" #include "correct/reed-solomon/field.h" -polynomial_t polynomial_create(unsigned int order); -void polynomial_destroy(polynomial_t polynomial); -void polynomial_mul(field_t field, polynomial_t l, polynomial_t r, polynomial_t res); -void polynomial_mod(field_t field, polynomial_t dividend, polynomial_t divisor, polynomial_t mod); -void polynomial_formal_derivative(field_t field, polynomial_t poly, polynomial_t der); -field_element_t polynomial_eval(field_t field, polynomial_t poly, field_element_t val); -field_element_t polynomial_eval_lut(field_t field, polynomial_t poly, const field_logarithm_t *val_exp); -field_element_t polynomial_eval_log_lut(field_t field, polynomial_t poly_log, const field_logarithm_t *val_exp); -void polynomial_build_exp_lut(field_t field, field_element_t val, unsigned int order, field_logarithm_t *val_exp); -polynomial_t polynomial_init_from_roots(field_t field, unsigned int nroots, field_element_t *roots, polynomial_t poly, polynomial_t *scratch); -polynomial_t polynomial_create_from_roots(field_t field, unsigned int nroots, field_element_t *roots); +DLL_EXPORT polynomial_t polynomial_create(unsigned int order); +DLL_EXPORT void polynomial_destroy(polynomial_t polynomial); +DLL_EXPORT void polynomial_mul(field_t field, polynomial_t l, polynomial_t r, polynomial_t res); +DLL_EXPORT void polynomial_mod(field_t field, polynomial_t dividend, polynomial_t divisor, polynomial_t mod); +DLL_EXPORT void polynomial_formal_derivative(field_t field, polynomial_t poly, polynomial_t der); +DLL_EXPORT field_element_t polynomial_eval(field_t field, polynomial_t poly, field_element_t val); +DLL_EXPORT field_element_t polynomial_eval_lut(field_t field, polynomial_t poly, const field_logarithm_t *val_exp); +DLL_EXPORT field_element_t polynomial_eval_log_lut(field_t field, polynomial_t poly_log, const field_logarithm_t *val_exp); +DLL_EXPORT void polynomial_build_exp_lut(field_t field, field_element_t val, unsigned int order, field_logarithm_t *val_exp); +DLL_EXPORT polynomial_t polynomial_init_from_roots(field_t field, unsigned int nroots, field_element_t *roots, polynomial_t poly, polynomial_t *scratch); +DLL_EXPORT polynomial_t polynomial_create_from_roots(field_t field, unsigned int nroots, field_element_t *roots); diff --git a/libcorrect.sln b/libcorrect.sln new file mode 100644 index 0000000..6f38e87 --- /dev/null +++ b/libcorrect.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27004.2005 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcorrect", "libcorrect.vcxproj", "{1C05F002-8DAC-4D31-8CC0-F07858757924}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1C05F002-8DAC-4D31-8CC0-F07858757924}.Debug|x64.ActiveCfg = Debug|x64 + {1C05F002-8DAC-4D31-8CC0-F07858757924}.Debug|x64.Build.0 = Debug|x64 + {1C05F002-8DAC-4D31-8CC0-F07858757924}.Debug|x86.ActiveCfg = Debug|Win32 + {1C05F002-8DAC-4D31-8CC0-F07858757924}.Debug|x86.Build.0 = Debug|Win32 + {1C05F002-8DAC-4D31-8CC0-F07858757924}.Release|x64.ActiveCfg = Release|x64 + {1C05F002-8DAC-4D31-8CC0-F07858757924}.Release|x64.Build.0 = Release|x64 + {1C05F002-8DAC-4D31-8CC0-F07858757924}.Release|x86.ActiveCfg = Release|Win32 + {1C05F002-8DAC-4D31-8CC0-F07858757924}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {EBDDEF48-6B2F-4A71-9E87-32750E772755} + EndGlobalSection +EndGlobal diff --git a/libcorrect.vcxproj b/libcorrect.vcxproj new file mode 100644 index 0000000..e7043a4 --- /dev/null +++ b/libcorrect.vcxproj @@ -0,0 +1,183 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {1C05F002-8DAC-4D31-8CC0-F07858757924} + libcorrect + 10.0.16299.0 + + + + StaticLibrary + true + v141 + MultiByte + false + true + + + StaticLibrary + false + v141 + true + MultiByte + false + + + StaticLibrary + true + v141 + MultiByte + False + true + + + StaticLibrary + false + v141 + true + MultiByte + False + + + + + + + + + + + + + + + + + + + + + .\;$(ExecutablePath) + .\;.\include;$(IncludePath) + + + .\include;$(IncludePath) + + + .\include;$(IncludePath) + + + $(VC_IncludePath);$(WindowsSDK_IncludePath);.\include;$(IncludePath) + + + + Level3 + Disabled + true + ProgramDatabase + + + + + Level3 + Disabled + true + ProgramDatabase + + + + + Level3 + MaxSpeed + true + true + true + _MBCS;%(PreprocessorDefinitions);HAVE_SSE + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + _MBCS;%(PreprocessorDefinitions);HAVE_SSE + Speed + Fast + StreamingSIMDExtensions2 + + + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libcorrect.vcxproj.filters b/libcorrect.vcxproj.filters new file mode 100644 index 0000000..d4d7593 --- /dev/null +++ b/libcorrect.vcxproj.filters @@ -0,0 +1,162 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {b6e14005-1442-4ab7-8bba-1e8d62914767} + + + {bc3ab159-0418-4915-8baa-6bafd6352ada} + + + {831f09b2-1728-485c-b019-2d7e7c92de77} + + + {60c2a483-4e8b-456b-a54f-5b55f922b28e} + + + {7a517274-0e67-45b2-8e80-130a0a005518} + + + {a9760bd8-61f0-407e-88ff-34e0b016a153} + + + {4edadaca-8cec-4962-9afa-16b2cb8b5bb7} + + + {37861685-b2af-41f9-93fd-8a4eb75cbfe5} + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files\correct + + + Header Files\correct + + + Header Files\correct\convolutional + + + Header Files\correct\convolutional + + + Header Files\correct\convolutional + + + Header Files\correct\convolutional + + + Header Files\correct\convolutional + + + Header Files\correct\convolutional + + + Header Files\correct\convolutional\sse + + + Header Files\correct\convolutional\sse + + + Header Files\correct\reed-solomon + + + Header Files\correct\reed-solomon + + + Header Files\correct\reed-solomon + + + Header Files\correct\reed-solomon + + + Header Files\correct\reed-solomon + + + Header Files\correct\util + + + Header Files\correct\util + + + Header Files\correct\util + + + Header Files\correct\util + + + + + Source Files + + + Source Files\convolutional + + + Source Files\convolutional + + + Source Files\convolutional + + + Source Files\convolutional + + + Source Files\convolutional + + + Source Files\convolutional + + + Source Files\convolutional + + + Source Files\convolutional + + + Source Files\reed-solomon + + + Source Files\reed-solomon + + + Source Files\convolutional\sse + + + Source Files\convolutional\sse + + + Source Files\convolutional\sse + + + Source Files\convolutional\sse + + + Source Files\reed-solomon + + + Source Files\reed-solomon + + + \ No newline at end of file diff --git a/libcorrect.vcxproj.user b/libcorrect.vcxproj.user new file mode 100644 index 0000000..be25078 --- /dev/null +++ b/libcorrect.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/convolutional/history_buffer.c b/src/convolutional/history_buffer.c index f54ffdd..2995ac5 100644 --- a/src/convolutional/history_buffer.c +++ b/src/convolutional/history_buffer.c @@ -45,7 +45,7 @@ uint8_t *history_buffer_get_slice(history_buffer *buf) { return buf->history[buf shift_register_t history_buffer_search(history_buffer *buf, const distance_t *distances, unsigned int search_every) { - shift_register_t bestpath; + shift_register_t bestpath = -1; distance_t leasterror = USHRT_MAX; // search for a state with the least error for (shift_register_t state = 0; state < buf->num_states; state += search_every) { @@ -100,7 +100,9 @@ void history_buffer_traceback(history_buffer *buf, shift_register_t bestpath, } else { prefetch_index--; } + prefetch(buf->history[prefetch_index]); + // we're walking backwards from what the work we did before // so, we'll shift high order bits in // the path will cross multiple different shift register states, and we determine diff --git a/src/convolutional/metric.c b/src/convolutional/metric.c index 894db4d..c53cc65 100644 --- a/src/convolutional/metric.c +++ b/src/convolutional/metric.c @@ -3,7 +3,7 @@ // measure the square of the euclidean distance between x and y // since euclidean dist is sqrt(a^2 + b^2 + ... + n^2), the square is just // a^2 + b^2 + ... + n^2 -distance_t metric_soft_distance_quadratic(unsigned int hard_x, const uint8_t *soft_y, size_t len) { +DLL_EXPORT distance_t metric_soft_distance_quadratic(unsigned int hard_x, const uint8_t *soft_y, size_t len) { distance_t dist = 0; for (unsigned int i = 0; i < len; i++) { // first, convert hard_x to a soft measurement (0 -> 0, 1 - > 255) diff --git a/src/convolutional/sse/CMakeLists.txt b/src/convolutional/sse/CMakeLists.txt index 0d0ade9..ec68e16 100644 --- a/src/convolutional/sse/CMakeLists.txt +++ b/src/convolutional/sse/CMakeLists.txt @@ -1,2 +1,2 @@ -set(SRCFILES lookup.c convolutional.c encode.c decode.c) +set(SRCFILES lookup_sse.c convolutional_sse.c encode_sse.c decode_sse.c) add_library(correct-convolutional-sse OBJECT ${SRCFILES}) diff --git a/src/convolutional/sse/convolutional.c b/src/convolutional/sse/convolutional_sse.c similarity index 100% rename from src/convolutional/sse/convolutional.c rename to src/convolutional/sse/convolutional_sse.c diff --git a/src/convolutional/sse/decode.c b/src/convolutional/sse/decode_sse.c similarity index 100% rename from src/convolutional/sse/decode.c rename to src/convolutional/sse/decode_sse.c diff --git a/src/convolutional/sse/encode.c b/src/convolutional/sse/encode_sse.c similarity index 100% rename from src/convolutional/sse/encode.c rename to src/convolutional/sse/encode_sse.c diff --git a/src/convolutional/sse/lookup.c b/src/convolutional/sse/lookup_sse.c similarity index 100% rename from src/convolutional/sse/lookup.c rename to src/convolutional/sse/lookup_sse.c diff --git a/src/reed-solomon/CMakeLists.txt b/src/reed-solomon/CMakeLists.txt index eabe75e..539e5c7 100644 --- a/src/reed-solomon/CMakeLists.txt +++ b/src/reed-solomon/CMakeLists.txt @@ -1,2 +1,2 @@ -set(SRCFILES polynomial.c reed-solomon.c encode.c decode.c) +set(SRCFILES polynomial.c reed-solomon.c rsencode.c rsdecode.c) add_library(correct-reed-solomon OBJECT ${SRCFILES}) diff --git a/src/reed-solomon/polynomial.c b/src/reed-solomon/polynomial.c index 32c2792..5f27535 100644 --- a/src/reed-solomon/polynomial.c +++ b/src/reed-solomon/polynomial.c @@ -1,20 +1,20 @@ #include "correct/reed-solomon/polynomial.h" -polynomial_t polynomial_create(unsigned int order) { +DLL_EXPORT polynomial_t polynomial_create(unsigned int order) { polynomial_t polynomial; polynomial.coeff = malloc(sizeof(field_element_t) * (order + 1)); polynomial.order = order; return polynomial; } -void polynomial_destroy(polynomial_t polynomial) { +DLL_EXPORT void polynomial_destroy(polynomial_t polynomial) { free(polynomial.coeff); } // if you want a full multiplication, then make res.order = l.order + r.order // but if you just care about a lower order, e.g. mul mod x^i, then you can select // fewer coefficients -void polynomial_mul(field_t field, polynomial_t l, polynomial_t r, polynomial_t res) { +DLL_EXPORT void polynomial_mul(field_t field, polynomial_t l, polynomial_t r, polynomial_t res) { // perform an element-wise multiplication of two polynomials memset(res.coeff, 0, sizeof(field_element_t) * (res.order + 1)); for (unsigned int i = 0; i <= l.order; i++) { @@ -29,7 +29,7 @@ void polynomial_mul(field_t field, polynomial_t l, polynomial_t r, polynomial_t } } -void polynomial_mod(field_t field, polynomial_t dividend, polynomial_t divisor, polynomial_t mod) { +DLL_EXPORT void polynomial_mod(field_t field, polynomial_t dividend, polynomial_t divisor, polynomial_t mod) { // find the polynomial remainder of dividend mod divisor // do long division and return just the remainder (written to mod) @@ -71,7 +71,7 @@ void polynomial_mod(field_t field, polynomial_t dividend, polynomial_t divisor, } } -void polynomial_formal_derivative(field_t field, polynomial_t poly, polynomial_t der) { +DLL_EXPORT void polynomial_formal_derivative(field_t field, polynomial_t poly, polynomial_t der) { // if f(x) = a(n)*x^n + ... + a(1)*x + a(0) // then f'(x) = n*a(n)*x^(n-1) + ... + 2*a(2)*x + a(1) // where n*a(n) = sum(k=1, n, a(n)) e.g. the nth sum of a(n) in GF(2^8) @@ -86,7 +86,7 @@ void polynomial_formal_derivative(field_t field, polynomial_t poly, polynomial_t } } -field_element_t polynomial_eval(field_t field, polynomial_t poly, field_element_t val) { +DLL_EXPORT field_element_t polynomial_eval(field_t field, polynomial_t poly, field_element_t val) { // evaluate the polynomial poly at a particular element val if (val == 0) { return poly.coeff[0]; @@ -110,7 +110,7 @@ field_element_t polynomial_eval(field_t field, polynomial_t poly, field_element_ return res; } -field_element_t polynomial_eval_lut(field_t field, polynomial_t poly, const field_logarithm_t *val_exp) { +DLL_EXPORT field_element_t polynomial_eval_lut(field_t field, polynomial_t poly, const field_logarithm_t *val_exp) { // evaluate the polynomial poly at a particular element val // in this case, all of the logarithms of the successive powers of val have been precalculated // this removes the extra work we'd have to do to calculate val_exponentiated each time @@ -131,7 +131,7 @@ field_element_t polynomial_eval_lut(field_t field, polynomial_t poly, const fiel return res; } -field_element_t polynomial_eval_log_lut(field_t field, polynomial_t poly_log, const field_logarithm_t *val_exp) { +DLL_EXPORT field_element_t polynomial_eval_log_lut(field_t field, polynomial_t poly_log, const field_logarithm_t *val_exp) { // evaluate the log_polynomial poly at a particular element val // like polynomial_eval_lut, the logarithms of the successive powers of val have been // precomputed @@ -156,7 +156,7 @@ field_element_t polynomial_eval_log_lut(field_t field, polynomial_t poly_log, co return res; } -void polynomial_build_exp_lut(field_t field, field_element_t val, unsigned int order, field_logarithm_t *val_exp) { +DLL_EXPORT void polynomial_build_exp_lut(field_t field, field_element_t val, unsigned int order, field_logarithm_t *val_exp) { // create the lookup table of successive powers of val used by polynomial_eval_lut field_logarithm_t val_exponentiated = field.log[1]; field_logarithm_t val_log = field.log[val]; @@ -170,7 +170,7 @@ void polynomial_build_exp_lut(field_t field, field_element_t val, unsigned int o } } -polynomial_t polynomial_init_from_roots(field_t field, unsigned int nroots, field_element_t *roots, polynomial_t poly, polynomial_t *scratch) { +DLL_EXPORT polynomial_t polynomial_init_from_roots(field_t field, unsigned int nroots, field_element_t *roots, polynomial_t poly, polynomial_t *scratch) { unsigned int order = nroots; polynomial_t l; field_element_t l_coeff[2]; @@ -210,7 +210,7 @@ polynomial_t polynomial_init_from_roots(field_t field, unsigned int nroots, fiel return poly; } -polynomial_t polynomial_create_from_roots(field_t field, unsigned int nroots, field_element_t *roots) { +DLL_EXPORT polynomial_t polynomial_create_from_roots(field_t field, unsigned int nroots, field_element_t *roots) { polynomial_t poly = polynomial_create(nroots); unsigned int order = nroots; polynomial_t l; diff --git a/src/reed-solomon/reed-solomon.c b/src/reed-solomon/reed-solomon.c index 91a708e..0eac9b3 100644 --- a/src/reed-solomon/reed-solomon.c +++ b/src/reed-solomon/reed-solomon.c @@ -11,7 +11,7 @@ static polynomial_t reed_solomon_build_generator(field_t field, unsigned int nro return polynomial_create_from_roots(field, nroots, roots); } -correct_reed_solomon *correct_reed_solomon_create(field_operation_t primitive_polynomial, field_logarithm_t first_consecutive_root, field_logarithm_t generator_root_gap, size_t num_roots) { +DLL_EXPORT correct_reed_solomon *correct_reed_solomon_create(field_operation_t primitive_polynomial, field_logarithm_t first_consecutive_root, field_logarithm_t generator_root_gap, size_t num_roots) { correct_reed_solomon *rs = calloc(1, sizeof(correct_reed_solomon)); rs->field = field_create(primitive_polynomial); @@ -34,7 +34,7 @@ correct_reed_solomon *correct_reed_solomon_create(field_operation_t primitive_po return rs; } -void correct_reed_solomon_destroy(correct_reed_solomon *rs) { +DLL_EXPORT void correct_reed_solomon_destroy(correct_reed_solomon *rs) { field_destroy(rs->field); polynomial_destroy(rs->generator); free(rs->generator_roots); @@ -67,7 +67,7 @@ void correct_reed_solomon_destroy(correct_reed_solomon *rs) { free(rs); } -void correct_reed_solomon_debug_print(correct_reed_solomon *rs) { +DLL_EXPORT void correct_reed_solomon_debug_print(correct_reed_solomon *rs) { for (unsigned int i = 0; i < 256; i++) { printf("%3d %3d %3d %3d\n", i, rs->field.exp[i], i, rs->field.log[i]); } diff --git a/src/reed-solomon/decode.c b/src/reed-solomon/rsdecode.c similarity index 100% rename from src/reed-solomon/decode.c rename to src/reed-solomon/rsdecode.c diff --git a/src/reed-solomon/encode.c b/src/reed-solomon/rsencode.c similarity index 91% rename from src/reed-solomon/encode.c rename to src/reed-solomon/rsencode.c index d4eb6f3..9480e65 100644 --- a/src/reed-solomon/encode.c +++ b/src/reed-solomon/rsencode.c @@ -1,6 +1,6 @@ #include "correct/reed-solomon/encode.h" -ssize_t correct_reed_solomon_encode(correct_reed_solomon *rs, const uint8_t *msg, size_t msg_length, uint8_t *encoded) { +DLL_EXPORT ssize_t correct_reed_solomon_encode(correct_reed_solomon *rs, const uint8_t *msg, size_t msg_length, uint8_t *encoded) { if (msg_length > rs->message_length) { return -1; } diff --git a/tools/find_conv_optim_poly.c b/tools/find_conv_optim_poly.c index 8b22574..4ea9bc7 100644 --- a/tools/find_conv_optim_poly.c +++ b/tools/find_conv_optim_poly.c @@ -210,7 +210,7 @@ void test(size_t rate, size_t order, // added by our msg block iterations and then sorts by this metric search_exhaustive_fin(exhaustive, convs_len, weights, num_scratches); - // decide paramters for next loop iter + // decide parameters for next loop iter // if we've reduced to 20 or fewer items, we're going to just select // those and declare the test done size_t new_convs_len = (convs_len / 2) < 20 ? 20 : convs_len / 2;