#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#define WIDTH 1280
#define HEIGHT 720
#define NEW_WIDTH 1270
#define NEW_HEIGHT 700
#define CONVERT_BEGIN(y, u, v, fd_in, file_in, fd_out, file_out, y_size, uv_size, read_uv_size)
do {
y = malloc(y_size);
u = malloc(uv_size);
v = malloc(uv_size);
fd_in = open(file_in, O_RDONLY);
fd_out = open(file_out, O_WRONLY|O_CREAT|O_TRUNC, 00755);
read(fd_in, y, y_size);
read(fd_in, u, read_uv_size);
read(fd_in, v, read_uv_size);
} while(0)
#define CONVERT_END(fd_in, fd_out, y, u, v)
do {
close(fd_in);
close(fd_out);
free(y);
free(u);
free(v);
} while(0)
static int yuv420_2_yuv444(char *file_in, char *file_out, int buf_size)
{
int fd_in, fd_out, i, j;
char *y_addr, *u_addr, *v_addr;
CONVERT_BEGIN(y_addr, u_addr, v_addr, fd_in, file_in, fd_out, file_out, buf_size, buf_size/4, buf_size/4);
write(fd_out, y_addr, buf_size);
for (j = 0; j < HEIGHT/2; j++) {
for (i = 0; i < WIDTH/2; i++) {
write(fd_out, &u_addr[j*(WIDTH/2) + i], 1);
write(fd_out, &u_addr[j*(WIDTH/2) + i], 1);
}
for (i = 0; i < WIDTH/2; i++) {
write(fd_out, &u_addr[j*(WIDTH/2) + i], 1);
write(fd_out, &u_addr[j*(WIDTH/2) + i], 1);
}
}
for (j = 0; j < HEIGHT/2; j++) {
for (i = 0; i < WIDTH/2; i++) {
write(fd_out, &v_addr[j*(WIDTH/2) + i], 1);
write(fd_out, &v_addr[j*(WIDTH/2) + i], 1);
}
for (i = 0; i < WIDTH/2; i++) {
write(fd_out, &v_addr[j*(WIDTH/2) + i], 1);
write(fd_out, &v_addr[j*(WIDTH/2) + i], 1);
}
}
CONVERT_END(fd_in, fd_out, y_addr, u_addr, v_addr);
return 0;
}
static int yuv420_2_yuv422h(char *file_in, char *file_out, int buf_size)
{
int fd_in, fd_out, i, j;
char *y_addr, *u_addr, *v_addr;
CONVERT_BEGIN(y_addr, u_addr, v_addr, fd_in, file_in, fd_out, file_out, buf_size, buf_size/4, buf_size/4);
write(fd_out, y_addr, buf_size);
for (j = 0; j < HEIGHT/2; j++) {
for (i = 0; i < WIDTH/2; i++) {
write(fd_out, &u_addr[j*(WIDTH/2) + i], 1);
}
for (i = 0; i < WIDTH/2; i++) {
write(fd_out, &u_addr[j*(WIDTH/2) + i], 1);
}
}
for (j = 0; j < HEIGHT/2; j++) {
for (i = 0; i < WIDTH/2; i++) {
write(fd_out, &v_addr[j*(WIDTH/2) + i], 1);
}
for (i = 0; i < WIDTH/2; i++) {
write(fd_out, &v_addr[j*(WIDTH/2) + i], 1);
}
}
CONVERT_END(fd_in, fd_out, y_addr, u_addr, v_addr);
return 0;
}
static int yuv420_2_yuv422v(char *file_in, char *file_out, int buf_size)
{
int fd_in, fd_out, i, j;
char *y_addr, *u_addr, *v_addr;
CONVERT_BEGIN(y_addr, u_addr, v_addr, fd_in, file_in, fd_out, file_out, buf_size, buf_size/2, buf_size/4);
write(fd_out, y_addr, buf_size);
for (j = 0; j < HEIGHT/2; j++) {
for (i = 0; i < WIDTH/2; i++) {
write(fd_out, &u_addr[j*(WIDTH/2) + i], 1);
write(fd_out, &u_addr[j*(WIDTH/2) + i], 1);
}
}
for (j = 0; j < HEIGHT/2; j++) {
for (i = 0; i < WIDTH/2; i++) {
write(fd_out, &v_addr[j*(WIDTH/2) + i], 1);
write(fd_out, &v_addr[j*(WIDTH/2) + i], 1);
}
}
CONVERT_END(fd_in, fd_out, y_addr, u_addr, v_addr);
return 0;
}
static int yuv422h_resize(char *file_in, int src_size, int w, int h)
{
int fd_in, fd_out, j;
int buf_size = w * h;
char *y_addr, *u_addr, *v_addr;
char file_out[32];
sprintf(file_out, "422h_%d_%d.yuv", NEW_WIDTH, NEW_HEIGHT);
CONVERT_BEGIN(y_addr, u_addr, v_addr, fd_in, file_in, fd_out, file_out, src_size, src_size/2, src_size/2);
/* y: WIDTH*HEIGHT => w*h*/
for (j = 0; j < h; j++)
write(fd_out, y_addr + j*WIDTH, w);
/* u: WIDTH/2 *HEIGHT => w/2*h*/
for (j = 0; j < h; j++)
write(fd_out, u_addr + j*WIDTH/2, w/2);
/* v: WIDTH/2 *HEIGHT => w/2*h*/
for (j = 0; j < h; j++)
write(fd_out, v_addr + j*WIDTH/2, w/2);
CONVERT_END(fd_in, fd_out, y_addr, u_addr, v_addr);
return 0;
}
static int yuv422v_resize(char *file_in, int src_size, int w, int h)
{
int fd_in, fd_out, j;
int buf_size = w * h;
char *y_addr, *u_addr, *v_addr;
char file_out[32];
sprintf(file_out, "422v_%d_%d.yuv", NEW_WIDTH, NEW_HEIGHT);
CONVERT_BEGIN(y_addr, u_addr, v_addr, fd_in, file_in, fd_out, file_out, src_size, src_size/2, src_size/2);
/* y: WIDTH*HEIGHT => w*h*/
for (j = 0; j < h; j++)
write(fd_out, y_addr + j*WIDTH, w);
/* u: WIDTH *HEIGHT/2 => w*h/2*/
for (j = 0; j < h/2; j++)
write(fd_out, u_addr + j*WIDTH, w);
/* v: WIDTH *HEIGHT/2 => w*h/2*/
for (j = 0; j < h/2; j++)
write(fd_out, v_addr + j*WIDTH, w);
CONVERT_END(fd_in, fd_out, y_addr, u_addr, v_addr);
return 0;
}
int main(int argc, char **argv)
{
int buf_size = WIDTH*HEIGHT;
yuv420_2_yuv444("420.yuv", "444.yuv", buf_size);
yuv420_2_yuv422h("420.yuv", "422h.yuv", buf_size);
yuv420_2_yuv422v("420.yuv", "422v.yuv", buf_size);
yuv422h_resize("422h.yuv", buf_size, NEW_WIDTH, NEW_HEIGHT);
yuv422v_resize("422v.yuv", buf_size, NEW_WIDTH, NEW_HEIGHT);
return 0;
}