/* Copyright (C) 1999 E. H. Haley does RGB <--> YIQ translations (a matrix multiplication). Of course, "2" in the function name means "to". "256" in the function name means the RGB values are JSAMPLEs (i.e. unsigned char). rgbk256yiqy takes a ncolors argument. If nc=3, it does the multiplication, rgb to yiq; if nc=1 (grayscale), it sets k to y. */ #include "color.h" #include /* >> m = [.299,.587,.114; .596, -.275, -.321; .212,-.528, .311] m = 0.29900 0.58700 0.11400 0.59600 -0.27500 -0.32100 0.21200 -0.52800 0.31100 note 1st row adds to one, 2nd to zero, 3rd nearly to 0 (typo?) >> inv(m) ans = 1.00309 0.95485 0.61786 0.99678 -0.27071 -0.64479 1.00850 -1.11049 1.69957 */ void rgb2yiq(float *rgb, float *yiq) { int row,col; float rgb2yiq[3][3]={{.299, .587, .114}, {.596, -.275, -.321}, {.212, -.528, .311}}; for(row=0; row<3; row++) { yiq[row]=0; for(col=0; col<3; col++) yiq[row] += rgb2yiq[row][col] * rgb[col]; } } void rgb256yiq(JSAMPLE *rgb, float *yiq) { int row,col; float rgb2yiq[3][3]={{.299, .587, .114}, {.596, -.275, -.321}, {.212, -.528, .311}}; for(row=0; row<3; row++) { yiq[row]=0; for(col=0; col<3; col++) yiq[row] += rgb2yiq[row][col] * (float)rgb[col]; } } void rgbk256yiqy(JSAMPLE *rgbk, float *yiqy, int nc) { int row,col; float rgb2yiq[3][3]={{.299, .587, .114}, {.596, -.275, -.321}, {.212, -.528, .311}}; if (nc==1) yiqy[0]=rgbk[0]; else if (nc==3) for(row=0; row<3; row++) { yiqy[row]=0; for(col=0; col<3; col++) yiqy[row] += rgb2yiq[row][col] * (float)rgbk[col]; } else exit(0); } void rgbyiq(JSAMPLE *rgb, float *yiq, int wxh, int ent) //for rgb and yiq vectors with all Y entries first (wxh of them //of which we're working on the ent entry), then wxh I's then wxh //Q's. always send in rgb+nothing and yiq+0, not +ent. { int row,col; float rgb2yiq[3][3]={{.299, .587, .114}, {.596, -.275, -.321}, {.212, -.528, .311}}; for(row=0; row<3; row++) { yiq[row*wxh+ent]=0; for(col=0; col<3; col++) yiq[row*wxh+ent] += rgb2yiq[row][col] * (float)rgb[col*wxh+ent]; } } void yiq2rgb(float *yiq, float *rgb) { int row,col; float yiq2rgb[3][3]= {{1.00309, 0.95485, 0.61786}, {0.99678, -0.27071, -0.64479}, {1.00850, -1.11049, 1.69957}}; for(row=0; row<3; row++) { rgb[row]=0; for(col=0; col<3; col++) rgb[row] += yiq2rgb[row][col] * yiq[col]; } } void yiq256rgb(float *yiq, JSAMPLE *rgb) { int row,col; float term; float yiq2rgb[3][3]= {{1.00309, 0.95485, 0.61786}, {0.99678, -0.27071, -0.64479}, {1.00850, -1.11049, 1.69957}}; for(row=0; row<3; row++) { term=0.0; for(col=0; col<3; col++) term += yiq2rgb[row][col] * yiq[col]; rgb[row]=(JSAMPLE)(term<256.0?(term>=0.0?term:0):255); } } void yiqy256rgbk(float *yiqy, JSAMPLE *rgbk, int nc) { int row,col; float term; float yiq2rgb[3][3]= {{1.00309, 0.95485, 0.61786}, {0.99678, -0.27071, -0.64479}, {1.00850, -1.11049, 1.69957}}; if (nc==1) rgbk[0]=yiqy[0]; else if (nc==3) for(row=0; row<3; row++) { term=0.0; for(col=0; col<3; col++) term += yiq2rgb[row][col] * yiqy[col]; rgbk[row]=(JSAMPLE)(term<256.0?(term>=0.0?term:0):255); } else exit(0); } void yiqrgb(float *yiq, JSAMPLE *rgb, int wxh, int ent) //for yiq and rgb vectors with all Y entries first (wxh of them //of which we're working on the ent entry), then wxh I's then wxh //Q's. always send in rgb+nothing and yiq+0, not +ent. { int row,col; float term; float yiq2rgb[3][3]= {{1.00309, 0.95485, 0.61786}, {0.99678, -0.27071, -0.64479}, {1.00850, -1.11049, 1.69957}}; for(row=0; row<3; row++) { term=0.0; for(col=0; col<3; col++) term += yiq2rgb[row][col] * yiq[col*wxh+ent]; rgb[row*wxh+ent]=(JSAMPLE)(term<256.0?(term>=0.0?term:0):255); } } float rgb2y(float *rgb) { int i; float y=0.0; float rgb2y[3]={.299,.587,.114}; for(i=0; i<3; i++) y += rgb2y[i] * rgb[i]; return y; } float rgb256y(JSAMPLE *rgb) { int i; float y=0.0; float rgb2y[3]={.299,.587,.114}; for(i=0; i<3; i++) y += rgb2y[i] * (float)rgb[i]; return y; }