#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

void yuv2rgb(uint8_t Y, uint8_t U, uint8_t V, uint8_t* rgb)
{
    float wr = 0.299;
    float wb = 0.114;
    float wg = 0.587;
    float umax = 0.436;
    float vmax = 0.615;

    rgb[0] = Y + V*(1-wr)/vmax;
    rgb[1] = Y - U*wb*(1-wb)/(umax*wg) - V*wr*(1-wr)/(vmax*wg);
    rgb[2] = Y + U*(1-wb)/umax;
}

int main()
{
    int w = 640;
    int h = 480;
    FILE* fp = fopen("ref.yuv", "r");
    FILE* op = fopen("out.rgb", "w+");
    uint8_t Y[w*h];
    uint8_t U[w*h/4];
    uint8_t V[w*h/4];
    uint8_t rgb[3];
    uint8_t y1, y2, u, v;
    uint8_t *yp, *up, *vp;

    yp = Y;
    up = U;
    vp = V;

    fread(Y, 1, w*h, fp);
    fread(U, 1, w*h/4, fp);
    fread(V, 1, w*h/4, fp);
    fclose(fp);

    for (int i = 0; i < h; i += 2) {
        for (int j = 0; j < w; j++) {
            y1 = *yp;
            y2 = *(yp + w);
            u = *up;
            v = *vp;

            yuv2rgb(y1, u, v, rgb);
            fseek(op, 3*(w*h + j), SEEK_SET);
            fwrite(rgb, 1, 3, op);

            yuv2rgb(y2, u, v, rgb);
            fseek(op, 3*((w+1)*h + j), SEEK_SET);
            fwrite(rgb, 1, 3, op);
            
            yp++;
            if (j % 2 != 0) 
            {
                up++;
                vp++;
            }
        }

        yp += w;
    }

    fclose(op);
    return 0; 
}

