📄 yuv2ppm.c
字号:
/* * file converter * * How to compile: * gcc -o yuv2ppm yuv2ppm * * Usage: * $ yuv2ppm < cap001.yuv > cap001.ppm * $ yuv2ppm -i < cap001.yuv > cap001.ppm */#include <stdio.h>#include <unistd.h>#include <errno.h>#define SHOW_MAXMIN#define FW 720#define FH 480#define PIXCEL_NUM (FW*FH)int opt_i=0, opt_s=0, opt_v=0, opt_W=FW, opt_H=FH;unsigned char frame[PIXCEL_NUM*3];unsigned char yuvbuf[PIXCEL_NUM*2];static void pixcel_to_buffer(int n, int r, int g, int b){ frame[n*3] = r; frame[n*3+1] = g; frame[n*3+2] = b;}static void pixcel_write(void){ int x, y, p, n, r, g, b; n = 0; for(y=0; y<opt_H; y++){ for(x=0; x<opt_W; x++){ if( opt_i ){ if( (y & 1) == 0 ) p = (y >> 1) * opt_W + x; else p = (opt_H/2 + (y >> 1)) * opt_W + x; }else{ p = y * opt_W + x; } r = frame[p*3]; g = frame[p*3+1]; b = frame[p*3+2]; if( n++ % 5 == 0 ) printf("\n%3d %3d %3d ", r, g, b); else printf("%3d %3d %3d ", r, g, b); } }}#ifdef NEVERstatic void YCbCr2RGB_xx(int n, int Y, int Cb, int Cr, int *r, int *g, int *b){ Cb = ((Cb-128) * 3) >> 1; /* fix me */ Cr = ((Cr-128) * 3) >> 1; /* fix me */ /* * Y = 0.587 * G + 0.114 * B + 0.299 * R * Cb = -0.587 * G + 0.886 * B - 0.299 * R * Cr = 0.587 * G - 0.114 * B - 0.701 * R * * R = Y + Cr * G = Y - 0.194 * Cb - 0.509 * Cr * B = Y + Cb */ *r = Y + Cr; *g = (Y * 1000 - 194 * Cb - 509 * Cr) / 1000; *b = Y + Cb; if( *r < 0 || *g < 0 || *b < 0 || *r > 255 || *g > 255 || *b > 255 ){ if( opt_v ) fprintf(stderr, "pixcel(%d,%d): Y=%d Cb=%d Cr=%d rgb=(%d,%d,%d)\n", n % opt_W, n / opt_W, Y, Cb, Cr, *r, *g, *b); if( *r < 0 ) *r = 0; if( *r > 255 ) *r = 255; if( *g < 0 ) *g = 0; if( *g > 255 ) *g = 255; if( *b < 0 ) *b = 0; if( *b > 255 ) *b = 255; }}#endifstatic void YCbCr2RGB_8fs(int n, int Y, int Cb, int Cr, int *r, int *g, int *b){ Cb = Cb-128; Cr = Cr-128; /* * Y = 0.299R + 0.587G + 0.114B * U = -0.169R - 0.331G + 0.500B * V = 0.500R - 0.419G - 0.081B * * R = 1.000Y + 1.402V * G = 1.000Y - 0.344U - 0.714V * B = 1.000Y + 1.772U */ *r = (1000 * Y + 1402 * Cr) / 1000; *g = (1000 * Y - 344 * Cb - 714 * Cr) / 1000; *b = (1000 * Y + 1772 * Cb) / 1000; if( *r < 0 || *g < 0 || *b < 0 || *r > 255 || *g > 255 || *b > 255 ){ if( opt_v ) fprintf(stderr, "pixcel(%d,%d): Y=%d Cb=%d Cr=%d rgb=(%d,%d,%d)\n", n % opt_W, n / opt_W, Y, Cb, Cr, *r, *g, *b); if( *r < 0 ) *r = 0; if( *r > 255 ) *r = 255; if( *g < 0 ) *g = 0; if( *g > 255 ) *g = 255; if( *b < 0 ) *b = 0; if( *b > 255 ) *b = 255; }}#define max(a,b) ((a)>(b)?(a):(b))#define min(a,b) ((a)<(b)?(a):(b))int main(int argc, char **argv){ int len; int p, retval, Y0, Y1, Cb, Cr, r, g, b; unsigned char *d; int bufn, bufp;#ifdef SHOW_MAXMIN int Y_max, Y_min, Cb_max, Cb_min, Cr_max, Cr_min;#endif int opt,n; while( (opt=getopt(argc, argv, "vsiW:H:")) != -1 ){ switch(opt){ case 'i': opt_i = 1; break; case 'v': opt_v = 1; break; case 'W': n = atoi(optarg); if( 0 < n && n <= FW ) opt_W = n; else{ fprintf(stderr, "invalid argument -W %s\n", optarg); } break; case 'H': n = atoi(optarg); if( 0 < n && n <= FH ) opt_H = n; else{ fprintf(stderr, "invalid argument -H %s\n", optarg); } break; default: fprintf(stderr, "unknown option %c(0x%02x)\n", opt, opt); } } p = 0; printf("P3\n"); printf("# CREATOR: yuv2ppm\n"); printf("%d %d\n", opt_W, opt_H); printf("255"); bufn = fread(yuvbuf, 4, PIXCEL_NUM/2, stdin); if( bufn == -1 ){ fprintf(stderr, "yuv2ppm fread: error .. return %d (errno=%d)\n", retval, errno); return 1; } bufp = 0; while( bufp < bufn ){ d = yuvbuf + bufp++ * 4; if( p > PIXCEL_NUM ){ fprintf(stderr, "input file over %d\n", PIXCEL_NUM); break; }#ifdef SHOW_MAXMIN if( p == 0 ){ Y_max = Y_min = d[0]; Cb_max = Cb_min = d[1]; Cr_max = Cr_min = d[3]; Y_max = max(Y_max, d[2]); Y_min = min(Y_min, d[2]); }else{ Y_max = max(Y_max, d[0]); Y_min = min(Y_min, d[0]); Cb_max = max(Cb_max, d[1]); Cb_min = min(Cb_min, d[1]); Y_max = max(Y_max, d[2]); Y_min = min(Y_min, d[2]); Cr_max = max(Cr_max, d[3]); Cr_min = min(Cr_min, d[3]); }#endif Y0 = d[0]; Cb = d[1]; Y1 = d[2]; Cr = d[3];#if 0#if 1 Cb = ((d[1]-128) * 3) >> 1; /* fix me */ Cr = ((d[3]-128) * 3) >> 1; /* fix me */#else Cb = d[1]-128; Cr = d[3]-128;#endif#endif YCbCr2RGB_8fs(p, Y0, Cb, Cr, &r, &g, &b); pixcel_to_buffer(p++, r, g, b); YCbCr2RGB_8fs(p, Y1, Cb, Cr, &r, &g, &b); pixcel_to_buffer(p++, r, g, b); } while( p < PIXCEL_NUM ){ pixcel_to_buffer(p++, 30, 10, 10); } pixcel_write(); printf("\n");#ifdef SHOW_MAXMIN if( opt_v ) fprintf(stderr, "Y = (%d - %d), Cb = (%d - %d), Cr = (%d - %d)\n", Y_min, Y_max, Cb_min, Cb_max, Cr_min, Cr_max);#endif return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -