diff --git a/include/blc_array.h b/include/blc_array.h
index 2d80a2d2b9d365f2b336519284dca728984f0b41..8a21d44a8d1d7ae3ccda6ba85270ca25977d9bc0 100644
--- a/include/blc_array.h
+++ b/include/blc_array.h
@@ -45,9 +45,9 @@ blc_dim *create_blc_dims(size_t *size, uint32_t type, std::vector<size_t> const
 typedef struct blc_array
 #ifdef __cplusplus
 :blc_mem {
-    
     /**Define an empty array*/
-    blc_array();
+    blc_array(uint32_t type='NDEF', uint32_t format='NDEF');
+
     /**Define and allocates the array */
     blc_array(uint32_t type, uint32_t format, std::vector<size_t> const &lengths);
     
diff --git a/include/blc_image.h b/include/blc_image.h
index 51d1670dbe2556e0eeb4fef9e8ccda3f7dedf7e6..8c0adff0fdd1e0befc0fbf76c1bbcc03f1e1cd7f 100644
--- a/include/blc_image.h
+++ b/include/blc_image.h
@@ -7,12 +7,12 @@
  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. *
  */
 
 /**
@@ -31,26 +31,46 @@ Specific functions to manipulate blc_array as images:
 #include "blc_core.h"
 #include "stdint.h" //uint32_t
 
+
+
+
 /**
  @defgroup blc_image blc_image functions
  @{
  */
 #ifdef __cplusplus
-typedef struct blc_image:blc_array{
-    void convert(blc_array const &image);
-}blc_image;
 
-typedef struct blc_Y800_image:blc_array{
-    void convert(blc_array const &image);
-}blc_Y800_image;
+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);
+    blc_image(blc_array &array);
+    virtual void convert(blc_image const &image)=0;
 
+    int elements_per_pixel;
+    size_t width, height;
 
-#endif
+};
+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);
+};
+#endif
 
 START_EXTERN_C
 
- void blc_RGBA_from_Y800(uint8_t *dest, uint8_t const *src, int elements_nb);
+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);
+
 
 /**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/src/core/blc_array.cpp b/src/core/blc_array.cpp
index f88d5ec62ca5b1b29755d39e20acc22277855fc3..81a6f1dae7077e170954df71c8b1784f435a5ac4 100644
--- a/src/core/blc_array.cpp
+++ b/src/core/blc_array.cpp
@@ -54,7 +54,7 @@ blc_dim *create_blc_dims(size_t *size, uint32_t type, int dims_nb, int length0,
     return dims;
 }*/
 
-blc_array::blc_array():type('NDEF'), format('NDEF'), dims(NULL), dims_nb(0), total_length(0){}
+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, vector<size_t> const &lengths){
     def_array( type,  format, lengths);
diff --git a/src/image/blc_image.cpp b/src/image/blc_image.cpp
index ac7655b16c8144a00e570c8d576e3008bbc2bd07..93e38eecd13741decb38b2e95dfd8e7d11dbe1de 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
@@ -24,6 +24,11 @@
 #include "blc_tools.h"
 #include "jpeg_tools.h"
 
+#include <string>
+#include <stdexcept> //invalid_argument
+
+using namespace std;
+
 #define Y800_to_RGBA(val) (val+(val<<8)+(val<<16)+(255<<24))
 
 typedef struct {
@@ -32,6 +37,36 @@ typedef struct {
 
 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");
+    }
+    return 0;
+}
+
 static void* init_RGB_from_YUYV()
 {
     int Y, Cb, Cr;
@@ -45,7 +80,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
@@ -115,6 +150,11 @@ void blc_yuv2_to_RGB3(blc_array *dest, blc_array const *src)
     }
 }
 
+void blc_Y800_from_YUYV(uint8_t *dest, uint8_t const *src, int elements_nb){
+    for (int i=0; i<elements_nb; i++) dest[i]=src[i*2];
+}
+
+
 /*
  R G R G R G
  G B G B G B
@@ -205,33 +245,52 @@ 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");
+    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;
@@ -241,20 +300,21 @@ void blc_image_def(blc_array *array, uint32_t type, uint32_t format, size_t widt
     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);
+    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);
@@ -278,159 +338,159 @@ void blc_image::convert(blc_array const &image){
     {
         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;
+                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);
+                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 '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));
-            }
+            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;
-                
-            case 'yuv2':
-                switch (output->format)
+            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)
+            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))
+                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));
-            }
+                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;
-            case 'YUYV':
-                switch (output->format)
+            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)
+            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))
+                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));
-            }
+                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;
-            case 'UYVY':
-                switch (output->format)
+            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))
+            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));
-                }
+                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 '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));
-                }
+            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':
-                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));
+                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;
-            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));
+            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;
-            case 'JPEG':case 'MJPG':
-                switch (output->format)
+            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) 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));
+            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("Input format '%.4s' is not managed", UINT32_TO_STRING(input_format_str, input->format));
+                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));
         }
     }
 }
@@ -443,77 +503,96 @@ 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[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);
+                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 * 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;
+                        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 if ((input->type == output->type) &&  (input->type=='FL32')){
+            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)
+            {
                 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);
+                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->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;
+                        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;
-        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));
-        }
-            break;
-        case 'UYVY':
-            switch (output->format)
-        {
-            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));
-        }
             break;
         default:
-            EXIT_ON_ARRAY_ERROR(input, "Input format is not managed ");
+            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 ");
     }
 }
 
 
+blc_image::blc_image(blc_array &array):blc_array(array){
+
+}
+
+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_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_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];
+}
+
+
 START_EXTERN_C
 void blc_image_convert(blc_array *output, blc_array const *input){