From d0cb27d910487d48c3bea2e90a1666dc5c2c3c82 Mon Sep 17 00:00:00 2001 From: Arnaud Blanchard <arnaud.blanchard@ensea.fr> Date: Mon, 1 Mar 2021 20:53:26 +0100 Subject: [PATCH] Restructuration --- include/blc_array.h | 28 +- include/blc_array_tcp4_server.h | 2 + include/blc_channel.h | 6 +- include/blc_image.h | 44 +- include/blc_mem.h | 6 +- include/blc_tools.h | 3 + src/channel/blc_channel.cpp | 86 ++-- src/channel/channel_file.cpp | 17 +- src/core/blc_array.cpp | 126 ++--- src/core/blc_mem.cpp | 17 +- src/core/blc_tools.cpp | 8 + src/image/blc_image.cpp | 691 +++++++++++++------------- src/network/blc_array_network.cpp | 1 + src/network/blc_array_tcp4_server.cpp | 14 +- 14 files changed, 513 insertions(+), 536 deletions(-) diff --git a/include/blc_array.h b/include/blc_array.h index 8a21d44..83b5fe5 100644 --- a/include/blc_array.h +++ b/include/blc_array.h @@ -20,6 +20,8 @@ #include "blc_tools.h" #include "blc_mem.h" + +#define BLC_ARRAY_DIMS_MAX 8 #ifdef __cplusplus #include <vector> #endif @@ -38,8 +40,7 @@ typedef struct blc_dim { size_t step; ///< shift in bytes to do to pass from one element of this dimension to the next one } blc_dim; - -blc_dim *create_blc_dims(size_t *size, uint32_t type, std::vector<size_t> const &lengths); +//blc_dim *create_blc_dims(size_t *size, uint32_t type, std::vector<size_t> const &lengths); ///Description of a n-dimensional array with type and format typedef struct blc_array @@ -51,26 +52,21 @@ typedef struct blc_array /**Define and allocates the array */ blc_array(uint32_t type, uint32_t format, std::vector<size_t> const &lengths); - /**Copy the definition of the array, not the content, but data points toward the same memeory and the dims definitaions are copied */ - blc_array(blc_array const &array); + blc_array(blc_array const &array, void *data); /**Move the array. The content of initial array is not valid anymore*/ - blc_array(blc_array &&array); - /**Free dims. The data is freed by ~blc_mem()*/ - ~blc_array(); - - /**Copy the definition of the array, NOT the content */ - blc_array& operator=(blc_array const &other); - + /* Definiting the array without allocation. Useful when you want to use external buffer ====================================================================================*/ + /**Defines the blc_array but does not allocate memory (data)*/ + void def_array(blc_array &array); /**Defines the blc_array but does not allocate memory (data)*/ void def_array(uint32_t type, uint32_t format, std::vector<size_t> const &lengths); /**Defines the blc_array but does not allocate memory (data)*/ - void def_array(uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims); + void def_array(uint32_t type, uint32_t format, int dims_nb, blc_dim const dims[BLC_ARRAY_DIMS_MAX]); /**Defines the blc_array but does not allocate memory (data)*/ - void def_array(uint32_t type, uint32_t format, char const *dims_string); + void def_array(uint32_t type, uint32_t format, char const dims_string[BLC_ARRAY_DIMS_MAX]); /* Printing informations about the blc_array ==========================================*/ @@ -89,6 +85,9 @@ typedef struct blc_array /* Modifying the properties of the array ======================================*/ + + void set_dims(uint32_t type, std::vector<size_t> const &lengths); + /**Add one dimention to the definition of the blc_array. You have to manage eventual **memory reallocation** yourself.*/ void add_dim(size_t length, size_t step); /**Add one dimension ti the definition of the blc_array. The step is infered from the type of the data and the size of the previous dimension. You have to manage the eventual **memory reallocation** yourself.*/ @@ -136,14 +135,13 @@ typedef struct blc_array /**Return the size in bytes of one element depending on the type of data of the blc_array*/ int get_type_size(); - #else { blc_mem mem; ///< raw memory of the array #endif uint32_t type; ///< type of data in the memory as a unsigned int of 4 bytes. Possibilities are 'UIN8' uchar, 'INT8' char, 'UI16' uint16_t, 'IN16' int16_t, 'UI32' uint32_t, 'IN32' int32_t, 'FL32' float, 'FL64' double uint32_t format; ///< describes how the data should be interpreted. 'NDEF' (no specification), 'TEXT' for strings, 'Y800' black and white image, 'RGB3' image in RGB, 'LPCM' sound in non compressed format, ... - blc_dim * dims; ///< array of dimentions of the blc_array + blc_dim dims[BLC_ARRAY_DIMS_MAX]; ///< array of dimentions of the blc_array int dims_nb; ///< number of dimension of the blc_array size_t total_length; ///<Total number of elements in the array. This differ of size if an element is bigger than one byte. } blc_array; diff --git a/include/blc_array_tcp4_server.h b/include/blc_array_tcp4_server.h index f33283e..9bfbe41 100644 --- a/include/blc_array_tcp4_server.h +++ b/include/blc_array_tcp4_server.h @@ -9,6 +9,8 @@ typedef struct blc_array_tcp4_server #ifdef __cplusplus :blc_array_network { blc_array_tcp4_server(std::string const &port_name); + blc_array_tcp4_server(std::string const &port_name, blc_array &array); + blc_array_tcp4_server(std::string const &port_name, uint32_t type, uint32_t format, std::vector<size_t> const &lengths); void read_properties(); diff --git a/include/blc_channel.h b/include/blc_channel.h index 7307a98..4faa15e 100644 --- a/include/blc_channel.h +++ b/include/blc_channel.h @@ -68,7 +68,7 @@ typedef struct blc_channel ///Constructor creating or opening the channel if it exist. In this case it has to be compatible with its properties. blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, std::vector<size_t> lengths); ///Constructor creating or opening the channel if it exist. In this case it has to be compatible with its properties. - blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims); + blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, blc_dim const dims[BLC_ARRAY_DIMS_MAX]); //Warning copying channel with data, the new data is not mapped anymore @@ -120,7 +120,7 @@ typedef struct blc_channel void create(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims); /**Creates a new blc_channel and with the dims as a string (i.e. "3x800x600") */ void create(char const *new_name, int mode, uint32_t type, uint32_t format, char const *size_string); - /**Open a blc_channel with mode. The name should already be defined (e.g. with get_info) */ + /**Open a blc_channel with mode. The name should already be defined (e.g. with get_all_info) */ void open( int mode); /**Open a blc_channel with **name** */ void open(const char *name, int mode); @@ -150,7 +150,7 @@ typedef struct blc_channel bool operator<(blc_channel &b); - static std::pair<blc_channel*, int> get_all_infos(std::string filter=""); + static std::vector<blc_channel> get_all_infos(std::string filter=""); static void get_all_infos(std::map<int, blc_channel> &channels, std::string filter=""); #else diff --git a/include/blc_image.h b/include/blc_image.h index 8c0adff..eae2ef3 100644 --- a/include/blc_image.h +++ b/include/blc_image.h @@ -22,7 +22,6 @@ Specific functions to manipulate blc_array as images: - \ref blc_image generic image functions and simple conversions ( Y800, YUYV, yuv2, RGB3, RGBA, BA81, ...) - \ref jpeg functions for jpeg images (need libjpeg) - \ref png functions for png formats (need libpng) - */ #ifndef BLC_IMAGE_H @@ -30,9 +29,7 @@ Specific functions to manipulate blc_array as images: #include "blc_core.h" #include "stdint.h" //uint32_t - - - +#include <array> /** @defgroup blc_image blc_image functions @@ -40,37 +37,30 @@ Specific functions to manipulate blc_array as images: */ #ifdef __cplusplus -class blc_image:public blc_array{ -public: - blc_image(uint32_t type, uint32_t format, size_t width, size_t height, bool need_allocate=true); +struct blc_image:blc_array{ + ///Define but do not allocate data (use nulptr if you do not havec as well blc_image(blc_array &array); - virtual void convert(blc_image const &image)=0; - - int elements_per_pixel; - size_t width, height; - + ///Define a blc_image. Does not allocate data + blc_image(uint32_t type, uint32_t format, int width, int height); + ///Define the blc_array as an image format + std::function<void(void *dest, void const *src, size_t elements_nb)> get_converter_from(uint32_t from_type, uint32_t from_format); + std::function<void(void *dest, void const *src, size_t elements_nb)> get_converter_from(blc_array const &array); + + int elements_per_pixel, width, height; }; -class blc_UIN8_YUYV_image; -class blc_UIN8_Y800_image:public blc_image{ - blc_UIN8_Y800_image(blc_array &array); - void copy_from(blc_UIN8_YUYV_image const &image); -}; - -class blc_UIN8_YUYV_image:public blc_image{ - blc_UIN8_YUYV_image(blc_array &array); -}; -class blc_UIN8_RGB3_image:blc_array{ - blc_UIN8_RGB3_image(blc_array &array); -}; +auto create_blc_image(uint32_t type, uint32_t format, int width, int height); #endif START_EXTERN_C -void blc_RGBA_from_Y800(uint8_t *dest, uint8_t const *src, int elements_nb); -void blc_Y800_from_YUYV(uint8_t *dest, uint8_t const *src, int elements_nb); - +//It is void instead of uin8_t. You have to be careful yourself with the type +void blc_UIN8_RGB3_from_UIN8_YUYV(void *dest, void const *src, int elements_nb); +void blc_UIN8_Y800_from_UIN8_RGB3(void *dest, void const *src, int elements_nb); +void blc_UIN8_Y800_from_UIN8_YUYV(void *dest, void const *src, int elements_nb); +void blc_UIN8_YUYV_from_UIN8_RGB3(void *dest, void const *src, int elements_nb); +void blc_UIN8_YUYV_from_UIN8_Y800(void *dest, void const *src, int elements_nb); /**Return the number of bytes for a pixel of the format. -1 is returned if this data is undefined (i.e. JPEG)*/ int blc_image_get_bytes_per_pixel(blc_array const *image); diff --git a/include/blc_mem.h b/include/blc_mem.h index 276a187..95f1ed1 100644 --- a/include/blc_mem.h +++ b/include/blc_mem.h @@ -67,11 +67,13 @@ typedef struct blc_mem { /// Free the data. Only if data is not NULL and size !=0; It is a way to not delete data we want to keep. ~blc_mem(); /**really allocates the data of size previously set*/ - void allocate(); + blc_mem *allocate(); /** Change the size of memory. The content is not preserved. Use size = 0 to free the memory. */ - void allocate(size_t size); + blc_mem *allocate(size_t size); /// Allocate more memory if needed but does not free memory void allocate_min(size_t size); + /// Copy the content of mem. You have to be sure they have the same size and the memory have been allocated + void copy(blc_mem const &mem); /** Change the size of memory. But keep the content.*/ void reallocate(size_t size); /** Increases the memory of size and adds the new content.*/ diff --git a/include/blc_tools.h b/include/blc_tools.h index 640f438..2b6a938 100644 --- a/include/blc_tools.h +++ b/include/blc_tools.h @@ -26,6 +26,9 @@ Created on: Apr 28, 2011 ///Start a C function definition block. The function inside this block will be able to be call by C programs even if it is compiled in C++. #ifdef __cplusplus +#include <string> +std::string uint32_to_string(uint32_t value); + #define START_EXTERN_C extern "C" { ///End a C definition block. #define END_EXTERN_C } diff --git a/src/channel/blc_channel.cpp b/src/channel/blc_channel.cpp index 033524b..dd57769 100644 --- a/src/channel/blc_channel.cpp +++ b/src/channel/blc_channel.cpp @@ -33,7 +33,8 @@ #include <sys/time.h> //gettimeofday #include <semaphore.h> #include <algorithm> //std:strcopy -#include <map> //std:strcopy +#include <fstream> +#include <array> #include "blc_core.h" @@ -45,20 +46,39 @@ static int blc_channel_id_max = 0; using namespace std; -blc_channel::blc_channel(): access_mode(0), fd(-1), sem_new_data(nullptr), sem_ack_data(nullptr){} +blc_channel::blc_channel(): access_mode{0}, fd{-1}, sem_new_data{nullptr}, sem_ack_data{nullptr}, parameter{"NDEF"}{} -blc_channel::blc_channel(char const *new_name, int mode):blc_channel(){ +blc_channel::blc_channel(char const *new_name, int mode):access_mode{mode}, fd{-1}, sem_new_data{nullptr}, sem_ack_data{nullptr}, parameter{"NDEF"}{ open(new_name, mode); } -blc_channel::blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims):blc_channel(){ +blc_channel::blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, blc_dim const dims[BLC_ARRAY_DIMS_MAX]):access_mode{mode}, fd{-1}, sem_new_data{nullptr}, sem_ack_data{nullptr}, parameter{"NDEF"}{ create_or_open(new_name, access_mode, type, format, dims_nb, dims); } blc_channel::blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, vector<size_t> lengths ):blc_channel(){ - blc_dim *dims=create_blc_dims(&size, type, lengths); - create_or_open(new_name, mode, type,format, dims_nb, dims); - FREE(dims); //probably better to do in RAII + int id, created; + uint32_t new_type_str, new_format_str; + blc_channel info; + + id = blc_channel_get_info_with_name(&info, new_name); + if (id==-1) { + def_array(type, format, lengths); + create(new_name, access_mode); + } else{ + if (info.dims_nb!=lengths.size()) EXIT_ON_CHANNEL_ERROR(&info, "Reopening a blc_channel with different dims_nb '%d'. You may want to unlink it:\n blc_channels --unlink %s", dims_nb, info.name); + if (info.type!=type) EXIT_ON_CHANNEL_ERROR(&info, "Reopening blc_channel with another type '%.4s'. You may want to unlink it:\n blc_channels --unlink %s", UINT32_TO_STRING(new_type_str, type), info.name); + if (info.format!=format) EXIT_ON_CHANNEL_ERROR(&info, "Reopening blc_channel with another format '%.4s'. You may want to unlink it:\n blc_channels --unlink %s", UINT32_TO_STRING(new_format_str, format), info.name); + if (info.dims_nb!=0){ + for(int i=0; i != info.dims_nb; i++) { + if (lengths[i]!=info.dims[i].length) EXIT_ON_ERROR("The reopening dimension '%d' length '%d' of '%s' differ from the existing one '%d'. You may want to unlink the blc_channel before:\n blc_channels --unlink %s", i, lengths[i], info.name, info.dims[i].length, info.name); + } + } + this->type=type; + this->format=format; + set_dims(type, lengths); + open(new_name, access_mode); + } } /* blc_channel::blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, int length, ...):blc_channel(){ @@ -302,7 +322,7 @@ void blc_channel::create(char const *new_name, int access_mode){ } ///Create a blc channel -void blc_channel::create(char const *new_name, int access_mode, uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims){ +void blc_channel::create(char const *new_name, int access_mode, uint32_t type, uint32_t format, int dims_nb, blc_dim const dims[BLC_ARRAY_DIMS_MAX]){ def_array(type, format, dims_nb, dims); create(new_name, access_mode); } @@ -323,7 +343,6 @@ void blc_channel::create(char const *new_name, int mode, uint32_t type, uint32_t void blc_channel::create(char const *new_name, int mode, uint32_t type, uint32_t format, vector<size_t> lengths){ - dims=create_blc_dims(&size, type, lengths); create(new_name, access_mode, type, format, dims_nb, dims); } @@ -409,7 +428,7 @@ void blc_channel::open(const char *name, int mode){ } -int blc_channel::create_or_open(char const *new_name, int access_mode, uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims){ +int blc_channel::create_or_open(char const *new_name, int access_mode, uint32_t type, uint32_t format, int dims_nb, blc_dim const dims[BLC_ARRAY_DIMS_MAX]){ int id, dim, created; uint32_t new_type_str, new_format_str; blc_channel info; @@ -435,13 +454,18 @@ int blc_channel::create_or_open(char const *new_name, int access_mode, uint32_t } ///Create a blc channel -int blc_channel::create_or_open(char const *new_name, int access_mode, uint32_t type, uint32_t format, vector<size_t> lengths){ - blc_dim *dims; - size_t size; - - dims=create_blc_dims(&size, type, lengths); +/*int blc_channel::create_or_open(char const *new_name, int access_mode, uint32_t type, uint32_t format, vector<size_t> lengths){ + int dims_nb; + blc_dim dims[BLC_ARRAY_DIMS_MAX]; + + size_t size= + dims_nb = lengths.size(); + for (int i; i!=dims_nb; i++) { + dims[i].step=; + dims[i].length=lengths[i]; + } return create_or_open(new_name, access_mode, type, format, dims_nb, dims); -} +}*/ int blc_channel::create_or_open(char const *new_name, int mode, uint32_t type, uint32_t format, char const *dims_string){ int created=1; @@ -493,7 +517,6 @@ blc_channel::~blc_channel(){ void blc_channel::remove(){ blc_remove_channel_with_name(name); - if (dims) FREE(dims); if (data){ SYSTEM_SUCCESS_CHECK(munmap(data, size), 0, "Closing blc_channel '%s'", name); data=NULL; @@ -576,24 +599,23 @@ pair<vector<int>, vector<int>> blc_channel::get_update_infos(vector<blc_channel> fclose(file); }*/ -pair<blc_channel*, int> blc_channel::get_all_infos(string filter){ - auto channels_nb=0; +vector<blc_channel> blc_channel::get_all_infos(string filter){ blc_channel channel_info; - blc_channel *channels_infos=nullptr; - FILE *file; + vector<blc_channel> channels; + array<char, LINE_MAX> line; - file=fopen(BLC_CHANNELS_LIST_PATH, "r"); - if (file == nullptr) return make_pair(nullptr, 0); - - while(fscanf(file, "%*[ \t\n]s")!=EOF){ - channel_info.fscan_info(file, 1); - if (filter.empty() || strcmp(filter.data(), channel_info.name)==0){ - APPEND_ITEM(&channels_infos, &channels_nb, &channel_info); - channel_info.dims=nullptr; //Avoid dims to be removed by the destructor or fscan_info - } + ifstream file(BLC_CHANNELS_LIST_PATH, ifstream::in); + if (file.is_open()) { + // while(sscanf(line.data(), "%*[ \t\n]s")!=EOF){ + do{ + file.getline(line.data(), line.size()); + channel_info.sscan_info(line.data(), 1); + if (filter.empty() || strcmp(filter.data(), channel_info.name)==0){ + channels.emplace_back(channel_info); + } + }while (file.gcount()>0); } - fclose(file); - return make_pair(channels_infos, channels_nb); + return channels; } diff --git a/src/channel/channel_file.cpp b/src/channel/channel_file.cpp index e3ea91e..d4ec22b 100644 --- a/src/channel/channel_file.cpp +++ b/src/channel/channel_file.cpp @@ -188,18 +188,15 @@ int blc_channel_get_info_with_name(blc_channel *info, char const *name){ } int blc_channel_get_all_infos(struct blc_channel **channels_infos){ - int channels_nb; - tie(*channels_infos, channels_nb) = blc_channel::get_all_infos(); - return channels_nb; + return blc_channel_get_all_infos_with_filter(channels_infos, nullptr); } int blc_channel_get_all_infos_with_filter(blc_channel **channels_infos, char const *filter){ - int channels_nb; - if (filter==nullptr) tie(*channels_infos, channels_nb) = blc_channel::get_all_infos(); - else tie(*channels_infos, channels_nb) = blc_channel::get_all_infos(filter); - - return channels_nb; + vector<blc_channel> channels = blc_channel::get_all_infos(filter); + *channels_infos=MANY_ALLOCATIONS(channels.size(), blc_channel); + memcpy(channels_infos, channels.data(), sizeof(blc_channel)*channels.size()); //This copy is to incompatibility between c and c++ + return channels.size(); } void blc_channel_close_all(blc_channel *channels, int channels_nb) @@ -270,11 +267,9 @@ void blc_channel_check_for_event(void (*callback)(void*), void *user_data) { void blc_channel_destroy(blc_channel *channel){ channel->~blc_channel(); } - - + void blc_channel_wait_new_data(void *channel_pt){ blc_channel *channel=(blc_channel*)channel_pt; - SYSTEM_ERROR_CHECK(sem_wait(channel->sem_new_data), -1, "Waiting new data for channel '%s'", channel->name); } diff --git a/src/core/blc_array.cpp b/src/core/blc_array.cpp index 81a6f1d..892370a 100644 --- a/src/core/blc_array.cpp +++ b/src/core/blc_array.cpp @@ -24,92 +24,30 @@ #include <algorithm> //copy #include <vector> - using namespace std; -blc_dim *create_blc_dims(size_t *size, uint32_t type, vector<size_t> const &lengths){ - blc_dim *dim, *dims; - - dims=MANY_ALLOCATIONS(lengths.size(), blc_dim); - *size=blc_get_type_size(type); - - dim=dims; - for (auto length:lengths){ - dim->step=*size; - (*size)*=length; - dim->length=length; - dim++; - } - return dims; -} -/* -blc_dim *create_blc_dims(size_t *size, uint32_t type, int dims_nb, int length0, ...){ - blc_dim *dims; - va_list arguments; - va_start(arguments, length0); - - dims=vcreate_blc_dims(size, type, dims_nb, length0, arguments); - - va_end(arguments); - return dims; -}*/ - -blc_array::blc_array(uint32_t type, uint32_t format):type(type), format(type), dims(nullptr), dims_nb(0), total_length(0){} +blc_array::blc_array(uint32_t type, uint32_t format):type(type), format(format), dims_nb(0), total_length(0){} blc_array::blc_array(uint32_t type, uint32_t format, vector<size_t> const &lengths){ def_array( type, format, lengths); allocate(); } -blc_array::blc_array(blc_array const &array):blc_mem(array), type(array.type), format(array.format), dims_nb(array.dims_nb), total_length(array.total_length){ - dims=new blc_dim[dims_nb]; - std::copy(array.dims, array.dims+dims_nb, dims); -} - -blc_array::blc_array(blc_array &&array):blc_mem(array){ - dims=array.dims; - array.dims=nullptr; - array.dims_nb=0; -} - -blc_array& blc_array::operator=(blc_array const &other){ - if (this==&other) return *this; - - blc_mem::operator=(other); - type=other.type; - format=other.format; - total_length=other.total_length; - dims_nb=other.dims_nb; - MANY_REALLOCATIONS(&dims, dims_nb); - std::copy(other.dims, other.dims+dims_nb, dims); - return *this; -} - - - -blc_array::~blc_array(){ - if (dims) FREE(dims); -} - void blc_array::def_array(uint32_t type, uint32_t format, vector<size_t> const &lengths){ + assert(lengths.size()>BLC_ARRAY_DIMS_MAX); total_length=1; this->dims_nb=lengths.size(); this->type=type; this->format=format; - dims=create_blc_dims(&size, type, lengths); total_length=size/get_type_size(); } -void blc_array::def_array(uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims){ - +void blc_array::def_array(uint32_t type, uint32_t format, int dims_nb, blc_dim const dims[BLC_ARRAY_DIMS_MAX]){ this->type=type; this->format=format; this->dims_nb=dims_nb; - size=get_type_size(); - this->dims=MANY_ALLOCATIONS(dims_nb, blc_dim); memcpy(this->dims, dims, sizeof(blc_dim)*dims_nb); - size =dims[dims_nb-1].length*dims[dims_nb-1].step; total_length=size/get_type_size(); } @@ -120,6 +58,18 @@ void blc_array::def_array(uint32_t type, uint32_t format, char const *dims_strin sscan_dims(dims_string); } +void blc_array::set_dims(uint32_t type, vector<size_t> const &lengths){ + assert(lengths.size()<=BLC_ARRAY_DIMS_MAX); + dims_nb=lengths.size(); + size=blc_get_type_size(type); + size_t length; + for (int i; i!=dims_nb; i++){ + length=lengths[i]; + dims[i].step=size; + size*=length; + dims[i].length=length; + } +} /* void blc_array::init(char const *properties){ sscan_properties(properties); @@ -129,6 +79,8 @@ void blc_array::init(char const *properties){ void blc_array::vinit(uint32_t type, uint32_t format, int dims_nb, int length, va_list arguments){ vdef_array(type, format, dims_nb, length, arguments); + + allocate(); } @@ -142,14 +94,12 @@ void blc_array::init(uint32_t type, uint32_t format, int dims_nb, int length, .. } */ void blc_array::add_dim(size_t length, size_t step){ - blc_dim dim; - - dim.length=length; - dim.step=step; - - APPEND_ITEM(&dims, &dims_nb, &dim); + assert(dims_nb<BLC_ARRAY_DIMS_MAX); + dims[dims_nb].length=length; + dims[dims_nb].step=step; size=step*length; //Check if it always true ?? total_length=size/get_type_size(); + dims_nb++; } void blc_array::add_dim(size_t length){ @@ -161,11 +111,7 @@ void blc_array::set_dims(int dims_nb, size_t length, ...){ blc_dim *dim; va_list args; - if (dims) FREE(dims); - this->dims_nb=dims_nb; - dims=MANY_ALLOCATIONS(dims_nb, blc_dim); - size=get_type_size(); va_start(args, length); FOR_EACH(dim, dims, dims_nb) @@ -207,44 +153,38 @@ int blc_array::fprint_dims(FILE *file) const { } void blc_array::fscan_dims(FILE *file){ - blc_dim *dim; size_t length; size=get_type_size(); FSCANF(1, file, "%lu", &length); - if (dims) FREE(dims); dims_nb=0; - if (length != 0){ do{ - dim=APPEND_ALLOCATION(&dims, &dims_nb, blc_dim); - dim->length=length; - dim->step=size; - size*=dim->length; + dims[dims_nb].length=length; + dims[dims_nb].step=size; + size*=length; + dims_nb++; }while(fscanf(file, "x%lu", &length)==1); } total_length=size/get_type_size(); } int blc_array::sscan_dims(char const *string){ - blc_dim *dim; int pos, total_pos; size_t length; size=get_type_size(); - SSCANF(1, string, "%lu%n", &length, &pos); total_pos=0; dims_nb=0; - if (dims) FREE(dims); if (length != 0){ do{ total_pos+=pos; - dim=APPEND_ALLOCATION(&dims, &dims_nb, blc_dim); - dim->length=length; - dim->step=size; - size*=dim->length; + dims[dims_nb].length=length; + dims[dims_nb].step=size; + size*=length; + dims_nb++; }while(sscanf(string+total_pos, "x%lu%n", &length, &pos)==1); } total_length=size/get_type_size(); @@ -414,12 +354,11 @@ void blc_array::save_blc_file(char const *filename)const{ void blc_array::fprint_tsv(FILE *file)const{ int dim, length, i, j; uint32_t type_str; - blc_dim *tmp_dims; + blc_dim tmp_dims[BLC_ARRAY_DIMS_MAX]; dim = 0; j = 0; - tmp_dims = MANY_ALLOCATIONS(dims_nb, blc_dim); memcpy(tmp_dims, dims, dims_nb * sizeof(blc_dim)); while (dim != dims_nb) @@ -496,7 +435,6 @@ void blc_array::fprint_tsv(FILE *file)const{ } } fprintf(file, "\n"); - FREE(tmp_dims); } void blc_array::def_with_tsv_file(char const *filename){ @@ -528,7 +466,7 @@ void blc_array::update_with_tsv_file(char const *filename){ FILE *file; char const *ext; int dim, length, j; - blc_dim *tmp_dims; + blc_dim tmp_dims[BLC_ARRAY_DIMS_MAX]; ext=blc_get_filename_extension(filename); if (strcmp(ext, "tsv")!=0) EXIT_ON_ERROR("'%s' has not .tsv extension but '%s'", filename, ext); @@ -538,7 +476,6 @@ void blc_array::update_with_tsv_file(char const *filename){ dim = 0; j = 0; - tmp_dims = MANY_ALLOCATIONS(dims_nb, blc_dim); memcpy(tmp_dims, dims, dims_nb * sizeof(blc_dim)); @@ -595,7 +532,6 @@ void blc_array::update_with_tsv_file(char const *filename){ EXIT_ON_ARRAY_ERROR(this, "This type is not working with this function. Only 'UIN8' and 'FL32' work for naw."); } - FREE(tmp_dims); fclose(file); } diff --git a/src/core/blc_mem.cpp b/src/core/blc_mem.cpp index aa61fc8..f40d40e 100644 --- a/src/core/blc_mem.cpp +++ b/src/core/blc_mem.cpp @@ -21,18 +21,20 @@ #include "blc_mem.h" #include <algorithm> //std::copy -blc_mem::blc_mem():data(NULL), size(0){}; +blc_mem::blc_mem():data(nullptr), size(0){}; blc_mem::blc_mem(size_t size) -: data(NULL), size(size){ +: data(nullptr), size(size){ data = MANY_ALLOCATIONS(size, char); } blc_mem::blc_mem(blc_mem const &mem):data(mem.data), size(mem.size){ }; +///move blc_mem::blc_mem(blc_mem &&mem):size(mem.size){ chars=mem.chars; + mem.chars=nullptr; //Invalidate origine }; blc_mem &blc_mem::operator=(blc_mem const &other){ @@ -50,12 +52,13 @@ blc_mem::~blc_mem(){ } } -void blc_mem::allocate(){ +blc_mem* blc_mem::allocate(){ if (data) EXIT_ON_ERROR("mem already allocated"); else data = MANY_ALLOCATIONS(size, char); + return this; } -void blc_mem::allocate(size_t new_size){ +blc_mem *blc_mem::allocate(size_t new_size){ if (new_size != size || data == NULL) // Changement de taille ou l'allocation n'a encore jamais été faite { @@ -64,6 +67,7 @@ void blc_mem::allocate(size_t new_size){ else data=NULL; size = new_size; } + return this; } void blc_mem::allocate_min(size_t new_size){ @@ -74,6 +78,11 @@ void blc_mem::allocate_min(size_t new_size){ } } +void blc_mem::copy(blc_mem const &mem){ + memcpy(data, mem.data, size); +} + + void blc_mem::reallocate(size_t new_size){ MANY_REALLOCATIONS(&chars, new_size); size = new_size; diff --git a/src/core/blc_tools.cpp b/src/core/blc_tools.cpp index 2ab8e84..a5a3642 100644 --- a/src/core/blc_tools.cpp +++ b/src/core/blc_tools.cpp @@ -31,12 +31,20 @@ #include <sys/time.h> //gettimeofday #include <sys/uio.h> //iovec #include "blc_text.h" +#include <string> + +using namespace std; FILE *blc_log_file = NULL; char const *blc_program_name=""; char const *blc_program_id=""; //Name + pid +string uint32_to_string(uint32_t value){ + uint32_t value_str = ntohl(value); + return string(reinterpret_cast<char const*>(&value_str), 4); +} + size_t blc_get_type_size(uint32_t type) { uint32_t type_str; diff --git a/src/image/blc_image.cpp b/src/image/blc_image.cpp index 93e38ee..5e85733 100644 --- a/src/image/blc_image.cpp +++ b/src/image/blc_image.cpp @@ -7,13 +7,13 @@ This software is governed by the CeCILL v2.1 license under French law and abiding by the rules of distribution of free software. You can use, modify and/ or redistribute the software under the terms of the CeCILL v2.1 license as circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info". As a counterpart to the access to the source code and rights to copy, modify and redistribute granted by the license, - users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors have only limited liability. - In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or developing or reproducing the software by the user in light of its specific status of free software, - that may mean that it is complicated to manipulate, and that also therefore means that it is reserved for developers and experienced professionals having in-depth computer knowledge. + users are provided only with a limited warranty and the software's author, the holder of the economic rights, and the successive licensors have only limited liability. + In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or developing or reproducing the software by the user in light of its specific status of free software, + that may mean that it is complicated to manipulate, and that also therefore means that it is reserved for developers and experienced professionals having in-depth computer knowledge. Users are therefore encouraged to load and test the software's suitability as regards their requirements in conditions enabling the security of their systems and/or data to be ensured - and, more generally, to use and operate it in the same conditions as regards security. - The fact that you are presently reading this means that you have had knowledge of the CeCILL v2.1 license and that you accept its terms. * - + and, more generally, to use and operate it in the same conditions as regards security. + The fact that you are presently reading this means that you have had knowledge of the CeCILL v2.1 license and that you accept its terms. * + * * * Created on: August 1, 2015 @@ -26,6 +26,8 @@ #include <string> #include <stdexcept> //invalid_argument +#include <variant> +#include <iostream> using namespace std; @@ -40,29 +42,29 @@ static type_RGB *RGB_from_YUYV = NULL; static int get_elements_per_pixel(uint32_t format){ switch (format) { - case 'Y800': - case 'BA81': - return 1; - break; - case 'yuv2': - case 'YUYV': - case 'UYVY': - case 'YU12': case 'YV12': //Be carefull these formats are very specific, it is in fact 1.5 byte per pixel - return 2; - break; - case 'RGB3': - return 3; - break; - case 'RGBA': - return 4; - break; - case 'MJPG': - case 'JPEG': - case 'PNG ': - return -1; - break; - default: - throw invalid_argument( "Unknonw pixel format"); + case 'Y800': + case 'BA81': + return 1; + break; + case 'yuv2': + case 'YUYV': + case 'UYVY': + case 'YU12': case 'YV12': //Be carefull these formats are very specific, it is in fact 1.5 byte per pixel + return 2; + break; + case 'RGB3': + return 3; + break; + case 'RGBA': + return 4; + break; + case 'MJPG': + case 'JPEG': + case 'PNG ': + return -1; + break; + default: + throw invalid_argument( "Unknonw pixel format"); } return 0; } @@ -80,7 +82,7 @@ static void* init_RGB_from_YUYV() FOR_INV(Y, 256) { FOR_INV(j,256) - R[j] = CLIP_UCHAR(Y+1.13983*(j-128)); //It does not depend on Cb + R[j] = CLIP_UCHAR(Y+1.13983*(j-128)); //It does not depend on Cb FOR_INV(Cb, 256) { B = CLIP_UCHAR(Y+2.03211*(Cb-128)); // It does not depend on Cr @@ -241,260 +243,180 @@ void blc_Y800_float_from_BA81(blc_array *dest, blc_array const *src) } } -int blc_image_get_bytes_per_pixel(blc_array const *image) -{ - switch (image->format) - { - case 'Y800': - case 'BA81': - return 1; - break; - case 'yuv2': - case 'YUYV': - case 'UYVY': - case 'YU12': case 'YV12': //Be carefull these formats are very specific, it is in fact 1.5 byte per pixel - return 2; - break; - case 'RGB3': - return 3; - break; - case 'RGBA': - return 4; - break; - case 'MJPG': - case 'JPEG': - case 'PNG ': - return -1; - break; - default: - EXIT_ON_ARRAY_ERROR(image, "Unknonw pixel format"); - } - return 0; -} - -blc_image::blc_image(uint32_t type, uint32_t format, size_t width, size_t height, bool need_allocation):blc_array(type, format), width(width), height(height){ - elements_per_pixel = get_elements_per_pixel(format); - switch (elements_per_pixel) - { - case -1: - add_dim(width*height*3); //We take the max we can imagine - break; - case 1: - add_dim(width); - add_dim(height); - break; - default: - add_dim(static_cast<size_t>(elements_per_pixel)); - add_dim(width); - add_dim(height); - } - if (need_allocation) allocate(); -} - -void blc_image_def(blc_array *array, uint32_t type, uint32_t format, size_t width, size_t height) -{ - int bytes_per_pixel; - - array->type = type; - array->format = format; - bytes_per_pixel = blc_image_get_bytes_per_pixel(array); - switch (bytes_per_pixel) - { - case -1: - array->add_dim(width*height*3); //We take the max we can imagine - break; - case 1: - array->add_dim(width); - array->add_dim(height); - break; - default: - array->add_dim(bytes_per_pixel); - array->add_dim(width); - array->add_dim(height); - } -} - - -void blc_image_init(blc_array *array, uint32_t type, uint32_t format, size_t width, size_t height) -{ - blc_image_def(array, type, format, width, height); - array->allocate(); -} - /* blc_image_info::blc_image_info(uint32_t format, int width, int height):format(format), width(width), height(height) { bytes_per_pixel = blc_get_bytes_per_pixel(format); pixels_nb=width*height; + } + + void blc_image::convert(blc_array const &image){ + blc_array *output=this; + blc_array const *input=ℑ //This is waiting fully C++ methods + int i; + uint32_t output_format_str, input_format_str, input_type_str, output_type_str; + + if (input->format == format) + { + if (input->type == type) memcpy(uchars, input->uchars, input->size); + else if (input->type == 'UIN8' && type == 'FL32') FOR_INV(i, size/sizeof(float)) + floats[i] = (input->uchars[i] + 0.5f) / 256; + else if (input->type == 'FL32' && type == 'UIN8') FOR_INV(i, size) + uchars[i] = CLIP_UCHAR(input->floats[i]*256-0.5f); + else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, this->format)); + } + else + { + switch (input->format) + { + case 'BA81': + switch (this->format) + { + case 'Y800': + if (input->type == type) blc_Y800_from_BA81(output, input); + else if (input->type == 'UIN8' && output->type == 'FL32') blc_Y800_float_from_BA81(output, input); + else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + break; + default: + EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); + } + break; + + case 'yuv2': + switch (output->format) + { + case 'Y800': + if (input->type == output->type) FOR_INV(i, output->size) + output->uchars[i] = input->uchars[i * 2 + 1]; + else if (input->type == 'UIN8' && output->type == 'FL32') FOR_INV(i, output->size/sizeof(float)) + output->floats[i] = (input->uchars[i * 2 + 1] + 0.5f) / 256; + else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + break; + case 'RGB3': + if (input->type == output->type) blc_yuv2_to_RGB3(output, input); + else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + break; + default: + EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); + } + break; + case 'YUYV': + switch (output->format) + { + case 'Y800': + if (input->type == output->type) FOR_INV(i, output->size) + output->uchars[i] = input->uchars[i * 2]; + else if (input->type == 'UIN8' && output->type == 'FL32') FOR_INV(i, output->size/sizeof(float)) + output->floats[i] = (input->uchars[i * 2] + 0.5f) / 256; + else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + + break; + case 'RGB3': + if (input->type == output->type) blc_YUYV_to_RGB3(output, input); + else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + break; + default: + EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); + } + break; + case 'UYVY': + switch (output->format) + { + case 'Y800': + if (input->type == output->type) FOR_INV(i, output->size) output->uchars[i] = input->uchars[i * 2 + 1]; + else if (input->type == 'UIN8' && output->type == 'FL32') FOR_INV(i, output->size/sizeof(float)) + output->floats[i] = (input->uchars[i * 2 + 1] + 0.5f) / 256; + else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + + break; + case 'RGB3': + if (input->type == output->type) blc_YUYV_to_RGB3(output, input); + else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + break; + default: + EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); + } + break; + case 'YU12': + switch (output->format){ + case 'Y800': + if (input->type == output->type) memcpy( output->data, input->data, input->dims[1].length*input->dims[2].length); + else if (input->type == 'UIN8' && output->type == 'FL32') FOR_INV(i, input->dims[1].length*input->dims[2].length) + output->floats[i] = (input->uchars[i] + 0.5f) / 256; + else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + break; + default: + EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); + } + break; + case 'YV12': + switch (output->format){ + case 'Y800': + if (input->type == output->type) memcpy( output->data, input->data, input->dims[1].length*input->dims[2].length); + else if (input->type == 'UIN8' && output->type == 'FL32') FOR_INV(i, input->dims[1].length*input->dims[2].length) + output->floats[i] = (input->uchars[i] + 0.5f) / 256; + else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + break; + default: + EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); + } + break; + case 'Y800': + switch (output->format) + { + case 'JPEG': + if (input->type == output->type) blc_image_to_jpeg(output, input); + else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + break; + default: + EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); + } + break; + case 'RGB3': + switch (output->format) + { + case 'Y800': + if (input->type == output->type) + FOR_INV(i, output->size) output->uchars[i] = (input->uchars[i * 3]+input->uchars[i * 3+1]+input->uchars[i * 3+2])/3; + else if ((input->type=='UIN8') && (output->type=='FL32')) + FOR_INV(i, output->size/sizeof(float)) output->floats[i] = (input->uchars[i * 3]+input->uchars[i * 3+1]+input->uchars[i * 3+2]+0.5f)/(3*256.f); + else if ((input->type=='FL32') && (output->type=='UIN8')) + FOR_INV(i, output->size/sizeof(float)) output->uchars[i] = (input->floats[i * 3]+input->floats[i * 3+1]+input->floats[i * 3+2])*256/3.f-0.5f; + else + EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + break; + case 'JPEG': + if (input->type == output->type) blc_jpeg_to_image(output, input); + else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + break; + default: + EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); + } + break; + case 'JPEG':case 'MJPG': + switch (output->format) + { + case 'Y800': + if (input->type == output->type) blc_jpeg_to_image(output, input); + else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + + break; + case 'RGB3': + if (input->type == output->type) blc_jpeg_to_image(output, input); + else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + + break; + + default: + EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); + } + break; + default: + EXIT_ON_ERROR("Input format '%.4s' is not managed", UINT32_TO_STRING(input_format_str, input->format)); + } + } }*/ -void blc_image::convert(blc_array const &image){ - blc_array *output=this; - blc_array const *input=ℑ //This is waiting fully C++ methods - int i; - uint32_t output_format_str, input_format_str, input_type_str, output_type_str; - - if (input->format == format) - { - if (input->type == type) memcpy(uchars, input->uchars, input->size); - else if (input->type == 'UIN8' && type == 'FL32') FOR_INV(i, size/sizeof(float)) - floats[i] = (input->uchars[i] + 0.5f) / 256; - else if (input->type == 'FL32' && type == 'UIN8') FOR_INV(i, size) - uchars[i] = CLIP_UCHAR(input->floats[i]*256-0.5f); - else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, this->format)); - } - else - { - switch (input->format) - { - case 'BA81': - switch (this->format) - { - case 'Y800': - if (input->type == type) blc_Y800_from_BA81(output, input); - else if (input->type == 'UIN8' && output->type == 'FL32') blc_Y800_float_from_BA81(output, input); - else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - break; - default: - EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); - } - break; - - case 'yuv2': - switch (output->format) - { - case 'Y800': - if (input->type == output->type) FOR_INV(i, output->size) - output->uchars[i] = input->uchars[i * 2 + 1]; - else if (input->type == 'UIN8' && output->type == 'FL32') FOR_INV(i, output->size/sizeof(float)) - output->floats[i] = (input->uchars[i * 2 + 1] + 0.5f) / 256; - else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - break; - case 'RGB3': - if (input->type == output->type) blc_yuv2_to_RGB3(output, input); - else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - break; - default: - EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); - } - break; - case 'YUYV': - switch (output->format) - { - case 'Y800': - if (input->type == output->type) FOR_INV(i, output->size) - output->uchars[i] = input->uchars[i * 2]; - else if (input->type == 'UIN8' && output->type == 'FL32') FOR_INV(i, output->size/sizeof(float)) - output->floats[i] = (input->uchars[i * 2] + 0.5f) / 256; - else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - - break; - case 'RGB3': - if (input->type == output->type) blc_YUYV_to_RGB3(output, input); - else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - break; - default: - EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); - } - break; - case 'UYVY': - switch (output->format) - { - case 'Y800': - if (input->type == output->type) FOR_INV(i, output->size) output->uchars[i] = input->uchars[i * 2 + 1]; - else if (input->type == 'UIN8' && output->type == 'FL32') FOR_INV(i, output->size/sizeof(float)) - output->floats[i] = (input->uchars[i * 2 + 1] + 0.5f) / 256; - else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - - break; - case 'RGB3': - if (input->type == output->type) blc_YUYV_to_RGB3(output, input); - else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - break; - default: - EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); - } - break; - case 'YU12': - switch (output->format){ - case 'Y800': - if (input->type == output->type) memcpy( output->data, input->data, input->dims[1].length*input->dims[2].length); - else if (input->type == 'UIN8' && output->type == 'FL32') FOR_INV(i, input->dims[1].length*input->dims[2].length) - output->floats[i] = (input->uchars[i] + 0.5f) / 256; - else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - break; - default: - EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); - } - break; - case 'YV12': - switch (output->format){ - case 'Y800': - if (input->type == output->type) memcpy( output->data, input->data, input->dims[1].length*input->dims[2].length); - else if (input->type == 'UIN8' && output->type == 'FL32') FOR_INV(i, input->dims[1].length*input->dims[2].length) - output->floats[i] = (input->uchars[i] + 0.5f) / 256; - else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - break; - default: - EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); - } - break; - case 'Y800': - switch (output->format) - { - case 'JPEG': - if (input->type == output->type) blc_image_to_jpeg(output, input); - else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - break; - default: - EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); - } - break; - case 'RGB3': - switch (output->format) - { - case 'Y800': - if (input->type == output->type) - FOR_INV(i, output->size) output->uchars[i] = (input->uchars[i * 3]+input->uchars[i * 3+1]+input->uchars[i * 3+2])/3; - else if ((input->type=='UIN8') && (output->type=='FL32')) - FOR_INV(i, output->size/sizeof(float)) output->floats[i] = (input->uchars[i * 3]+input->uchars[i * 3+1]+input->uchars[i * 3+2]+0.5f)/(3*256.f); - else if ((input->type=='FL32') && (output->type=='UIN8')) - FOR_INV(i, output->size/sizeof(float)) output->uchars[i] = (input->floats[i * 3]+input->floats[i * 3+1]+input->floats[i * 3+2])*256/3.f-0.5f; - else - EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - break; - case 'JPEG': - if (input->type == output->type) blc_jpeg_to_image(output, input); - else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - break; - default: - EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); - } - break; - case 'JPEG':case 'MJPG': - switch (output->format) - { - case 'Y800': - if (input->type == output->type) blc_jpeg_to_image(output, input); - else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - - break; - case 'RGB3': - if (input->type == output->type) blc_jpeg_to_image(output, input); - else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - - break; - - default: - EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); - } - break; - default: - EXIT_ON_ERROR("Input format '%.4s' is not managed", UINT32_TO_STRING(input_format_str, input->format)); - } - } -} - /*The output image must exactly be 2 times smaller than the input */ void blc_image_downscale(blc_array *output, blc_array const *input) { @@ -503,100 +425,185 @@ void blc_image_downscale(blc_array *output, blc_array const *input) switch (input->format) { - case 'Y800': - if ((input->type == output->type) && (input->type=='UIN8')){ - width = output->dims[0].length; - height = output->dims[1].length; - if (width * 2 != input->dims[0].length) EXIT_ON_ARRAY_ERROR(output, "Output width is not half input width '%d'", output->dims[0].length); - if (height * 2 != input->dims[1].length) EXIT_ON_ARRAY_ERROR(output, "Output height is not half input height '%d'", output->dims[1].length); - FOR_INV(j, height) - FOR_INV(i, width) - output->uchars[i + j * width] = (input->uchars[i * 2+(j * 2) * width] + input->uchars[i * 2+(j * 2) * width+1] + input->uchars[i * 2+(j * 2+1) * width] + input->uchars[i * 2+(j * 2+1) * width + 1])/4; - } - else if ((input->type == output->type) && (input->type=='FL32')){ - width = output->dims[0].length; - height = output->dims[1].length; - if (width * 2 != input->dims[0].length) EXIT_ON_ARRAY_ERROR(output, "Output width is not half input width '%d'", output->dims[0].length); - if (height * 2 != input->dims[1].length) EXIT_ON_ARRAY_ERROR(output, "Output height is not half input height '%d'", output->dims[1].length); - FOR_INV(j, height) - FOR_INV(i, width) - output->floats[i + j * width] = (input->floats[i * 2+(j * 2) * width] + input->floats[i * 2+(j * 2) * width+1] + input->floats[i * 2+(j * 2+1) * width] + input->floats[i * 2+(j * 2+1) * width + 1])/4.f; - } - - else EXIT_ON_ERROR("Downscale from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); - - break; - case 'yuv2': - switch (output->format) - { case 'Y800': - if ((input->type == output->type) && (input->type=='UIN8')) - { + if ((input->type == output->type) && (input->type=='UIN8')){ width = output->dims[0].length; height = output->dims[1].length; - if (width * 2 != input->dims[1].length) EXIT_ON_ARRAY_ERROR(output, "Output width is not half input width '%d'", output->dims[1].length); - if (height * 2 != input->dims[2].length) EXIT_ON_ARRAY_ERROR(output, "Output height is not half input height '%d'", output->dims[2].length); + if (width * 2 != input->dims[0].length) EXIT_ON_ARRAY_ERROR(output, "Output width is not half input width '%d'", output->dims[0].length); + if (height * 2 != input->dims[1].length) EXIT_ON_ARRAY_ERROR(output, "Output height is not half input height '%d'", output->dims[1].length); FOR_INV(j, height) + FOR_INV(i, width) + output->uchars[i + j * width] = (input->uchars[i * 2+(j * 2) * width] + input->uchars[i * 2+(j * 2) * width+1] + input->uchars[i * 2+(j * 2+1) * width] + input->uchars[i * 2+(j * 2+1) * width + 1])/4; + } + else if ((input->type == output->type) && (input->type=='FL32')){ + width = output->dims[0].length; + height = output->dims[1].length; + if (width * 2 != input->dims[0].length) EXIT_ON_ARRAY_ERROR(output, "Output width is not half input width '%d'", output->dims[0].length); + if (height * 2 != input->dims[1].length) EXIT_ON_ARRAY_ERROR(output, "Output height is not half input height '%d'", output->dims[1].length); + FOR_INV(j, height) + FOR_INV(i, width) + output->floats[i + j * width] = (input->floats[i * 2+(j * 2) * width] + input->floats[i * 2+(j * 2) * width+1] + input->floats[i * 2+(j * 2+1) * width] + input->floats[i * 2+(j * 2+1) * width + 1])/4.f; + } + + else EXIT_ON_ERROR("Downscale from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + + break; + case 'yuv2': + switch (output->format) + { + case 'Y800': + if ((input->type == output->type) && (input->type=='UIN8')) + { + width = output->dims[0].length; + height = output->dims[1].length; + if (width * 2 != input->dims[1].length) EXIT_ON_ARRAY_ERROR(output, "Output width is not half input width '%d'", output->dims[1].length); + if (height * 2 != input->dims[2].length) EXIT_ON_ARRAY_ERROR(output, "Output height is not half input height '%d'", output->dims[2].length); + FOR_INV(j, height) FOR_INV(i, width) output->uchars[i + j * width] = (input->uchars[i * 4 + 1 + (j * 2) * width * 4] + input->uchars[i * 4 + 3 + (j * 2) * width * 4] + input->uchars[i * 4 + 1 + (j * 2 + 1) * 4 * width] + input->uchars[i * 4 + 3 + (j * 2 + 1) * 4 * width]) / 4; + } + else EXIT_ON_ERROR("Downscale from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + break; + default: + EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); } - else EXIT_ON_ERROR("Downscale from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); break; - default: - EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); - } - break; - case 'UYVY': - switch (output->format) - { - case 'Y800': - if (input->type == output->type) + case 'UYVY': + switch (output->format) { - width = output->dims[0].length; - height = output->dims[1].length; - if (width * 2 != input->dims[1].length) EXIT_ON_ARRAY_ERROR(output, "Output width is not half input width '%d'", output->dims[1].length); - if (height * 2 != input->dims[2].length) EXIT_ON_ARRAY_ERROR(output, "Output height is not half input height '%d'", output->dims[2].length); - FOR_INV(j, height) + case 'Y800': + if (input->type == output->type) + { + width = output->dims[0].length; + height = output->dims[1].length; + if (width * 2 != input->dims[1].length) EXIT_ON_ARRAY_ERROR(output, "Output width is not half input width '%d'", output->dims[1].length); + if (height * 2 != input->dims[2].length) EXIT_ON_ARRAY_ERROR(output, "Output height is not half input height '%d'", output->dims[2].length); + FOR_INV(j, height) FOR_INV(i, width) output->uchars[i + j * width] = (input->uchars[i * 4 + 1 + (j * 2) * width * 4] + input->uchars[i * 4 + 3 + (j * 2) * width * 4] + input->uchars[i * 4 + 1 + (j * 2 + 1) * 4 * width] + input->uchars[i * 4 + 3 + (j * 2 + 1) * 4 * width]) / 4; + } + else EXIT_ON_ERROR("Downscale from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); + break; + default: + EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); } - else EXIT_ON_ERROR("Downscale from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format)); break; default: - EXIT_ON_ERROR("Output format '%.4s' is not managed with input format '%.4s'.", UINT32_TO_STRING(output_format_str, output->format), UINT32_TO_STRING(input_format_str, input->format)); - } - break; - default: - EXIT_ON_ARRAY_ERROR(input, "Input format is not managed "); + EXIT_ON_ARRAY_ERROR(input, "Input format is not managed "); } } -blc_image::blc_image(blc_array &array):blc_array(array){ - +void blc_copy_2_bytes_per_element(void *dest, void const *src, int output_length){ + memcpy(dest, src, 2*output_length); } -blc_UIN8_Y800_image::blc_UIN8_Y800_image(blc_array &array):blc_image(array){ - elements_per_pixel=1; - width =dims[0].length; - height=dims[1].length; +void blc_copy_4_bytes_per_element(void *dest, void const *src, int output_length){ + memcpy(dest, src, 4*output_length); } -void blc_UIN8_Y800_image::copy_from(blc_UIN8_YUYV_image const &image){ - for (size_t i=0; i<total_length; i++) uchars[i]=image.chars[i*2]; +void blc_copy_8_bytes_per_element(void *dest, void const *src, int output_length){ + memcpy(dest, src, 8*output_length); } -void blc_UIN8_YUYV_image::copy_from(blc_UIN8_YUYV_image const &image){ - for (size_t i=0; i<size; i++) uchars[i]=image.chars[i*2]; + +//It is void instead of uin8_t. You have to be careful yourself with the type +void blc_UIN8_RGB3_from_UIN8_Y800(void *dest, void const *src, int output_length){ + auto const input=static_cast<const uint8_t*>(src); + auto const output=static_cast<uint8_t*>(dest); + uint8_t grey; + + for (int i=0; i!=output_length/3; i++){ + grey=input[i]; + output[3*i]=grey; + output[3*i+1]=grey; + output[3*i+2]=grey; + } } +void blc_UIN8_Y800_from_UIN8_YUYV(void *dest, void const *src, int output_length){ + auto input=static_cast<const uint8_t*>(src); + auto output=static_cast<uint8_t*>(dest); + for (int i=0; i!=output_length; i++) output[i]=input[i*2]; +} -START_EXTERN_C -void blc_image_convert(blc_array *output, blc_array const *input){ +struct blc_image_converter{ + uint32_t type; + uint32_t format; + uint32_t from_type; + uint32_t from_format; + function<void(void *dest, void const *src, int src_nb)> converter; + +}; + +struct blc_image_format{ + uint32_t format; + int elements_per_pixel; +}; + +std::array<blc_image_format, 4> blc_image_formats{{{'RGB3', 3}, {'Y800', 1}, {'yuv2', 2}, {'YUYV', 2}}}; // double '{' because fist is class initailization, second is initializer list, third is the struct itself + +std::array<blc_image_converter, 10> blc_image_converters{{ // double '{' because fist is class initailization, second is initializer list, third is the struct itself + {'UIN8', 'RGB3', 'UIN8', 'Y800', blc_UIN8_RGB3_from_UIN8_Y800}, + /* {'UIN8', 'RGB3', 'UIN8', 'yuv2', blc_UIN8_RGB3_from_UIN8_YUYV}, + {'UIN8', 'RGB3', 'UIN8', 'YUYV', blc_UIN8_RGB3_from_UIN8_YUYV}, + {'UIN8', 'Y800', 'UIN8', 'RGB3', blc_UIN8_Y800_from_UIN8_RGB3}, + {'UIN8', 'Y800', 'UIN8', 'yuv2', blc_UIN8_Y800_from_UIN8_YUYV}, + {'UIN8', 'Y800', 'UIN8', 'YUYV', blc_UIN8_Y800_from_UIN8_YUYV}, + {'UIN8', 'yuv2', 'UIN8', 'RGB3', blc_UIN8_YUYV_from_UIN8_RGB3}, + {'UIN8', 'yuv2', 'UIN8', 'Y800', blc_UIN8_YUYV_from_UIN8_Y800}, + {'UIN8', 'YUYV', 'UIN8', 'RGB3', blc_UIN8_YUYV_from_UIN8_RGB3}, + {'UIN8', 'YUYV', 'UIN8', 'Y800', blc_UIN8_YUYV_from_UIN8_Y800},*/ +}}; + + +blc_image::blc_image(uint32_t type, uint32_t format, int width, int height):blc_array(type, format), width(width), height(height){ + auto image_format=find_if(blc_image_formats.cbegin(), blc_image_formats.cend(), [format](blc_image_format const &image_format){ + return image_format.format==format; + }); - blc_image *image=(blc_image*)output; - image->convert(*input); + if (image_format==blc_image_formats.end()) throw invalid_argument(uint32_to_string(format) + ":format unknown"); + else { + this->elements_per_pixel=image_format->elements_per_pixel; + if (elements_per_pixel>1) add_dim(image_format->elements_per_pixel); + add_dim(width); + add_dim(height); + } } + +function<void(void *dest, void const *src, size_t elements_nb)> blc_image::get_converter_from(uint32_t from_type, uint32_t from_format){ + // In case of identical propeties, we do not convert but jsut copy + if ( from_type == type && from_format == format){ + switch (blc_get_type_size(type)){ + case 1: return memcpy; + break; + case 2: return blc_copy_2_bytes_per_element; + break; + case 4: return blc_copy_4_bytes_per_element; + break; + case 8: return blc_copy_8_bytes_per_element; + break; + default: throw invalid_argument(to_string(blc_get_type_size(type)) + " bytes per element is not managed"); + } + } + //We look for a possible converter + auto image_converter=find_if(blc_image_converters.cbegin(), blc_image_converters.cend(), [this, from_type, from_format](blc_image_converter const &image_converter){ + return (this->type==image_converter.type) + && (this->format == image_converter.format) + && (from_type == image_converter.from_type) + && (from_format == image_converter.from_format); + }); + if (image_converter == blc_image_converters.end()){ + throw invalid_argument("Converter does not exist"); + } + else return image_converter->converter; +} + + +function<void(void *dest, void const *src, size_t elements_nb)> blc_image::get_converter_from(blc_array const &array){ + return get_converter_from(array.type, array.format); +} +START_EXTERN_C END_EXTERN_C diff --git a/src/network/blc_array_network.cpp b/src/network/blc_array_network.cpp index b4b2ffe..57537bb 100644 --- a/src/network/blc_array_network.cpp +++ b/src/network/blc_array_network.cpp @@ -2,6 +2,7 @@ #include <unistd.h> + blc_array_network::~blc_array_network(){ SYSTEM_ERROR_CHECK(close(socket_fd), -1, nullptr); } diff --git a/src/network/blc_array_tcp4_server.cpp b/src/network/blc_array_tcp4_server.cpp index 9f1a576..c6ffb12 100644 --- a/src/network/blc_array_tcp4_server.cpp +++ b/src/network/blc_array_tcp4_server.cpp @@ -32,6 +32,11 @@ blc_array_tcp4_server::blc_array_tcp4_server(string const &port_name){ SYSTEM_ERROR_CHECK(listen(socket_fd, 1), -1, nullptr); /* Max one connection*/ } + +blc_array_tcp4_server::blc_array_tcp4_server(string const &port_name, blc_array &array):blc_array_tcp4_server(port_name){ + blc_array::operator=(array); +} + /** If you do not want allocate data, use 'blc_array_tcp4_server(string const &port_name)' then '''server->def_array( type, format, lengths);''' */ @@ -40,6 +45,7 @@ blc_array_tcp4_server::blc_array_tcp4_server(string const &port_name, uint32_t t allocate(); } + int blc_array_tcp4_server::wait_connection(){ struct sockaddr_storage client_storage; socklen_t client_addr_len=sizeof(client_storage); @@ -47,11 +53,9 @@ int blc_array_tcp4_server::wait_connection(){ client_socket=accept(socket_fd, reinterpret_cast<struct sockaddr*>(&client_storage), &client_addr_len); if (client_socket==-1) return errno; - if (dims!=nullptr) { - SYSTEM_ERROR_CHECK(setsockopt(client_socket, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)), -1, nullptr); - SYSTEM_ERROR_CHECK(setsockopt(client_socket, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)), -1, nullptr); - send_properties(); - } + SYSTEM_ERROR_CHECK(setsockopt(client_socket, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)), -1, nullptr); + SYSTEM_ERROR_CHECK(setsockopt(client_socket, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)), -1, nullptr); + send_properties(); return 0; } -- GitLab