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){