Megatron300
Megatron300

Reputation: 239

How can I flip a buffer vertically during an YUV to RGB conversion

EDIT : The question was not clear sorry, I updated and added details.

I have a buffer with image data (YUV format) that I convert to an RGB format. The problem is, I would like to flip the image vertically (Invert the Y-position).

What I'm able to do for the moment is convert my YUV data to RGB data in a buffer, then flip this buffer vertically.

Here is the working code for this :

unsigned char* DeckLinkCaptureDelegate::convertYUVtoRGB(void* frameBytes)
{
    unsigned char *mycopy = new unsigned char[height*width*3];
    unsigned char *flippedCopy = new unsigned char[height*width*3];
    unsigned char* pData = (unsigned char *) frameBytes;


    //Conversion from YUV to RGB

    for(int i = 0, j=0; i < width * height * 3; i+=6, j+=4)
    {
        unsigned char v = pData[j];
        unsigned char y = pData[j+1];
        unsigned char u = pData[j+2];

        mycopy[i+2] = 1.0*y + 8 + 1.402*(v-128);               // r
        mycopy[i+1] = 1.0*y - 0.34413*(u-128) - 0.71414*(v-128);   // g
        mycopy[i] = 1.0*y + 1.772*(u-128) + 0;                            // b

        y = pData[j+3];
        mycopy[i+5] = 1.0*y + 8 + 1.402*(v-128);               // r
        mycopy[i+4] = 1.0*y - 0.34413*(u-128) - 0.71414*(v-128);   // g
        mycopy[i+3] = 1.0*y + 1.772*(u-128) + 0;
    }

    //Vertical flip

    for (int i = 0; i < width; ++i) {
        for (int j = 0; j < height; ++j) {
            for (int k = 0; k < 3; ++k) {
                flippedCopy[(i + j * width) * 3 + k] = mycopy[(i + (height - 1 - j) * width) * 3 + k];
            }
        }
    }

    return flippedCopy;   
}

What I would like to do to gain performance is flip the buffer DURING the conversion from YUV to RGB. I had no idea how to do it and Yusuf answer helped me, so here is what I have for the moment :

unsigned char* DeckLinkCaptureDelegate::convertYUVtoRGB(void* frameBytes)
{
    unsigned char *mycopy = new unsigned char[height*width*3];
    unsigned char* pData = (unsigned char *) frameBytes;
    int k = height - 1;

    for(int i = 0, j=0; i < width * height * 3; i+=6, j+=4)
    {
            unsigned char v = pData[j];
            unsigned char y = pData[j+1];
            unsigned char u = pData[j+2];

            mycopy[(width*k*3) + i+2] = 1.0*y + 8 + 1.402*(v-128);               // r
            mycopy[(width*k*3) + i+1] = 1.0*y - 0.34413*(u-128) - 0.71414*(v-128);   // g
            mycopy[(width*k*3) + i] = 1.0*y + 1.772*(u-128) + 0;                            // b

            y = pData[j+3];
            mycopy[(width*k*3) + i+5] = 1.0*y + 8 + 1.402*(v-128);               // r
            mycopy[(width*k*3) + i+4] = 1.0*y - 0.34413*(u-128) - 0.71414*(v-128);   // g
            mycopy[(width*k*3) + i+3] = 1.0*y + 1.772*(u-128) + 0;

            if (<i multiple of (width*3)-1>){ 
                k = k - 2;
            }

    }

    return mycopy;
}

If I'm correct, this should work, assuming the if condition is right. But I don't know how to express this if condition, since i is incremented by 6 each time, so I might "skip" the right moment to decrement k

I hope I'm clear enough. Thanks

Upvotes: 1

Views: 955

Answers (1)

Yusuf R. Karag&#246;z
Yusuf R. Karag&#246;z

Reputation: 589

I assume that width is even, otherwise "reduce in new line"-if will be complicated, then you must use 2 loops. I didn't tested, but should look like this;

unsigned char* DeckLinkCaptureDelegate::convertYUVtoRGB(void* frameBytes)
{
    unsigned char *mycopy = new unsigned char[height*width*3];
    unsigned char* pData = (unsigned char *) frameBytes;
    unsigned int k = height - 1;

    for(int i = 0, j=0; i < width * height * 3; i+=6, j+=4)
    {
        unsigned char v = pData[j];
        unsigned char y = pData[j+1];
        unsigned char u = pData[j+2];

        mycopy[(width*k*3) + i+2] = 1.0*y + 8 + 1.402*(v-128);               // r
        mycopy[(width*k*3) + i+1] = 1.0*y - 0.34413*(u-128) - 0.71414*(v-128);   // g
        mycopy[(width*k*3) + i] = 1.0*y + 1.772*(u-128) + 0;                            // b

        y = pData[j+3];
        mycopy[(width*k*3) + i+5] = 1.0*y + 8 + 1.402*(v-128);               // r
        mycopy[(width*k*3) + i+4] = 1.0*y - 0.34413*(u-128) - 0.71414*(v-128);   // g
        mycopy[(width*k*3) + i+3] = 1.0*y + 1.772*(u-128) + 0;

        if (mod(i, width*3) == 0) //reduce in new line (i am not sure how to reduce it, you should think about here)
            k = k - 2;
    }

    return mycopy;
}

And tag your question as imageprocessing etc not only as c++

Upvotes: 1

Related Questions