diff --git a/include/blc_array.h b/include/blc_array.h
index 8a21d44a8d1d7ae3ccda6ba85270ca25977d9bc0..83b5fe51a82e051734f310100a08b4120441b47a 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 f33283eaddca5c24c7b271d4f4acdd1acc3b351a..9bfbe4198835460cc848b35d5801fe3a2980ab33 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 7307a9851605c828d3d1c227acce7a22fc25c5f4..4faa15e0b123ead79ba8fae114724e3885b3cd9c 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 8c0adff0fdd1e0befc0fbf76c1bbcc03f1e1cd7f..eae2ef394f4832ded1bdb8a119f59d2559533f0d 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 276a18730e72a42799ee5c001869929c1f999ea4..95f1ed1e295f009b7ae633a48e49f508dab50f0e 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 640f43898e948a888011fca96e2731953ff4b3bf..2b6a93884af63557c4c762474254f82a7cad0028 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 033524b8268e50ddeb28ae2c9bf3877572072444..dd5776915be527f2b5e12525b1260de8974e88ed 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 e3ea91e4169408fcb1d4c82272fd32ac89203c16..d4ec22b36f1aa5c7f24da2e862df9034759c6944 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 81a6f1dae7077e170954df71c8b1784f435a5ac4..892370ad085dd82c9b1b832d05aa337112b8b527 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 aa61fc8ea634b2ab41a55d52e245afe1e0aa27ed..f40d40ee85ef814cb7bd656bdc7b0270fa4c244b 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 2ab8e844e548b46f7f03e874aa19325a710f92f6..a5a36423ebdf74e3565ed186c641f44cef2b7b02 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 93e38eecd13741decb38b2e95dfd8e7d11dbe1de..5e85733d879ce9a1d58c04d2e3d9d41f35f3579a 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=&image; //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=&image; //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 b4b2ffe8efa0db3e103b1e13803e77ac2896f53b..57537bbfb6cf0eb7c78180a59added884bf9d3cb 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 9f1a576c20dc380fa7107693350e48cca425fe5d..c6ffb12e6e8a4e2df15a5116715ebc6e81d9a86b 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;
 }