# RGB to YUV Conversion Example

This example converts a 2D image from the RGB format to the YUV format. It demonstrates how storing both images in 2D SoA `n_container`s can improve performance.

    #include <iostream>
    #include <sdlt/sdlt.h>
    using namespace sdlt;
    #define WIDTH 1024
    #define HEIGHT 1024

    struct RGBs {
        float r;
        float g;
        float b;
    };

    struct YUVs {
        float y;
        float u;
        float v;

        YUVs(){ };

        YUVs& operator=(const RGBs &tmp){
            y = 0.229f * tmp.r + 0.587f * tmp.g + 0.114f * tmp.b;
            u = -0.147f * tmp.r - 0.289f * tmp.g + 0.436f * tmp.b;
            v = 0.615 * tmp.r - 0.515f * tmp.g - 0.100 * tmp.b;
            return *this;
        }
        YUVs(const RGBs &tmp){
            y = 0.229f * tmp.r + 0.587f * tmp.g + 0.114f * tmp.b;
            u = -0.147f * tmp.r - 0.289f * tmp.g + 0.436f * tmp.b;
            v = 0.615 * tmp.r - 0.515f * tmp.g - 0.100 * tmp.b;
       }
    };

    SDLT_PRIMITIVE(RGBs, r, g, b)
    SDLT_PRIMITIVE(YUVs, y, u, v)

    int main(){
        typedef layout::soa<> LayoutT;
        n_extent_t<int, int> extents(HEIGHT, WIDTH);

        /*  Creating a typedef for SoA N-dimensional container.
            RGBTy and YUVTy are user defined structures whose collection needs to be stored in SoA format in memory.
            Layout in memory specified as layout::soa.
            In the below case N-dimensional SoA container is used in 2-D context
        */
        typedef sdlt::n_container< RGBs, LayoutT, decltype(extents) > ContainerRGB;
        typedef sdlt::n_container< YUVs, LayoutT, decltype(extents) > ContainerYUV;

        //Instantiate Input and Output Containers
        ContainerRGB inputRGB(extents);
        ContainerYUV outputYUV(extents);

        auto input = inputRGB.const_access();   //Get Constant Accessor object for inputRGB
        auto output = outputYUV.access();       //Get Accessor object for outputYUV

        //Select the iteration range in each dimension
        const auto iRGB1 = bounds_d<1>(input);  //bound_d<1>(input);
        const auto iRGB0 = bounds_d<0>(input);  //bound_d<0>(input);

        for(int y = iRGB0.lower(); y < iRGB0.upper(); y++)
        {
            #pragma simd
            for (int x = iRGB1.lower(); x < iRGB1.upper(); x++){
                const RGBs temp1 = input[y][x];
                YUVs temp2 = temp1;
                output[y][x] = temp2;
            }
        }
        return 0;
    }

Parent topic: Examples