00001 #ifndef Impala_Core_Array_Element_ColConvert_h
00002 #define Impala_Core_Array_Element_ColConvert_h
00003
00004 #include "Core/Array/Element/ArithTypes.h"
00005 #include "Core/Array/Element/E1Sum.h"
00006 #include "Core/Array/Element/E1Min.h"
00007
00008 namespace Impala
00009 {
00010 namespace Core
00011 {
00012 namespace Array
00013 {
00014 namespace Element
00015 {
00016
00017
00018
00019
00024 inline Vec3Real64
00025 ColRGB2CMY(const Vec3Real64& v)
00026 {
00027 return Vec3Real64(1, 1, 1) - v;
00028 }
00029
00034 inline Vec3Real64
00035 ColCMY2RGB(const Vec3Real64& v)
00036 {
00037 return Vec3Real64(1, 1, 1) - v;
00038 }
00039
00040
00041
00046 inline Vec3Real64
00047 ColRGB2XYZ(const Vec3Real64& v)
00048 {
00049
00050
00051
00052
00053
00054 double X = v.X() * 0.161746 + v.Y() * 0.140227 + v.Z() * 0.070754;
00055 double Y = v.X() * 0.083400 + v.Y() * 0.280455 + v.Z() * 0.028301;
00056 double Z = v.X() * 0.007582 + v.Y() * 0.046742 + v.Z() * 0.372638;
00057
00058 return Vec3Real64(X, Y, Z);
00059 }
00060
00065 inline Vec3Real64
00066 ColXYZ2RGB(const Vec3Real64& v)
00067 {
00068
00069
00070
00071
00072
00073 double R = v.X() * 8.25322145 + v.Y() * -3.9197325 + v.Z() * -1.27126425;
00074 double G = v.X() * -2.4716028 + v.Y() * 4.7837796 + v.Z() * 0.1059678;
00075 double B = v.X() * 0.1419024 + v.Y() * -0.52030965 + v.Z() * 2.69614305;
00076
00077 return Vec3Real64(R, G, B);
00078 }
00079
00080
00081
00086 inline Vec3Real64
00087 ColCMY2XYZ(const Vec3Real64& v)
00088 {
00089
00090
00091
00092 double X = 95.045385
00093 - v.X() * 0.161746 - v.Y() * 0.140227 - v.Z() * 0.070754;
00094 double Y = 100.0
00095 - v.X() * 0.083400 - v.Y() * 0.280455 - v.Z() * 0.028301;
00096 double Z = 108.87531
00097 - v.X() * 0.007582 - v.Y() * 0.046742 - v.Z() * 0.372638;
00098
00099 return Vec3Real64(X, Y, Z);
00100 }
00101
00106 inline Vec3Real64
00107 ColXYZ2CMY(const Vec3Real64& v)
00108 {
00109
00110
00111
00112 double C = 255.0
00113 - v.X() * 8.25322145 - v.Y() * -3.9197325 - v.Z() * -1.27126425;
00114 double M = 255.0
00115 - v.X() * -2.4716028 - v.Y() * 4.7837796 - v.Z() * 0.1059678;
00116 double Y = 255.0
00117 - v.X() * 0.1419024 - v.Y() * -0.52030965 - v.Z() * 2.69614305;
00118
00119 return Vec3Real64(C, M, Y);
00120 }
00121
00122
00123
00124 const double Xn = 95.0;
00125 const double Yn = 100.0;
00126 const double Zn = 108.9;
00127
00128 static inline double
00129 Y2L(double YYn)
00130 {
00131 return (YYn > 0.008856) ? 116.0 * pow(YYn , 1.0 / 3.0) - 16.0
00132 : 903.3 * YYn;
00133 }
00134
00135 static inline double
00136 L2Y(double L)
00137 {
00138 return (L > 7.999625) ? Yn * pow((L + 16.0) / 116.0, 3.0)
00139 : Yn * (L / 903.3);
00140 }
00141
00142 static inline double
00143 f4ab(double r)
00144 {
00145 return (r > 0.008856) ? pow(r, 1.0 / 3.0)
00146 : 7.787 * r + (16.0 / 116.0);
00147 }
00148
00149 static inline double
00150 fInv4ab(double r, double Ltmp)
00151 {
00152 return (Ltmp > 0.206893) ? pow(r, 3.0)
00153 : (r - 16.0 / 116.0) / 7.787;
00154 }
00155
00160 inline Vec3Real64
00161 ColLab2XYZ(const Vec3Real64& v)
00162 {
00163 double Y = L2Y(v.X());
00164
00165 double Ltmp = (v.X() + 16.0) / 116.0;
00166 double atmp = Ltmp + v.Y() / 500.0;
00167 double X = Xn * fInv4ab(atmp, Ltmp);
00168 double btmp = Ltmp - v.Z() / 200.0;
00169 double Z = Zn * fInv4ab(btmp, Ltmp);
00170 return Vec3Real64(X, Y, Z);
00171 }
00172
00177 inline Vec3Real64
00178 ColXYZ2Lab(const Vec3Real64& v)
00179 {
00180 Vec3Real64 n = v / Vec3Real64(Xn, Yn, Zn);
00181
00182 double L = Y2L(n.Y());
00183
00184 double fnX = f4ab(n.X());
00185 double fnY = f4ab(n.Y());
00186 double fnZ = f4ab(n.Z());
00187
00188 double a = 500.0 * (fnX - fnY);
00189 double b = 200.0 * (fnY - fnZ);
00190 return Vec3Real64(L, a, b);
00191 }
00192
00193
00194
00195
00196
00201 inline Vec3Real64
00202 ColLuv2XYZ(const Vec3Real64& v)
00203 {
00204 double Y = L2Y(v.X());
00205 double tmp = Xn + 15 * Yn + 3 * Zn;
00206 double unp = 4 * Xn / tmp;
00207 double vnp = 9 * Yn / tmp;
00208 double Q = v.Y() / (13 * v.X()) + unp;
00209 double R = v.Z() / (13 * v.X()) + vnp;
00210 double A = 3 * Y * (5 * R - 3);
00211 double Z = ((Q - 4) * A - 15 * Q * R * Y) / (12 * R);
00212 double X = -(A / R + 3 * Z);
00213 return Vec3Real64(X, Y, Z);
00214 }
00215
00220 inline Vec3Real64
00221 ColXYZ2Luv(const Vec3Real64& v)
00222 {
00223 double L = Y2L(v.Y() / Yn);
00224 double tmp = Xn + 15 * Yn + 3 * Zn;
00225 double unp = 4 * Xn / tmp;
00226 double vnp = 9 * Yn / tmp;
00227 tmp = v.X() + 15 * v.Y() + 3 * v.Z();
00228 double up = 4 * v.X() / tmp;
00229 double vp = 9 * v.Y() / tmp;
00230 double us = 13 * L * (up - unp);
00231 double vs = 13 * L * (vp - vnp);
00232 return Vec3Real64(L, us, vs);
00233 }
00234
00235
00236
00237 #ifdef PI
00238 #undef PI
00239 #endif
00240 #define PI 3.1415926536
00241 #define TWO_PI 6.2831853072
00242 #define PI_3 1.0471975512
00243 #define TWO_PI_3 2.0943951024
00244 #define FOUR_PI_3 4.1887902048
00245 #define FIVE_PI_3 5.2359877560
00246
00250 inline Vec3Real64
00251 ColRGB2HSI(const Vec3Real64& v)
00252 {
00253 double I = E1Sum(v) / 3.0;
00254 double S = (I == 0.0) ? 1.0 : 1.0 - (E1Min(v) / I);
00255 double H;
00256 if (v.X() == v.Y() && v.Y() == v.Z())
00257 H = 0.0;
00258 else {
00259 double tmp = acos((0.5*(v.X()-v.Y()+v.X()-v.Z())) /
00260 sqrt((v.X()-v.Y())*(v.X()-v.Y())+(v.X()-v.Z())*(v.Y()-v.Z())));
00261 H = (v.Y() > v.Z()) ? tmp : TWO_PI - tmp;
00262 }
00263 return Vec3Real64(H, S, I);
00264 }
00265
00269
00270
00271 inline Vec3Real64
00272 ColHSI2RGB(const Vec3Real64& v)
00273 {
00274 double H = v.X();
00275 double S = v.Y();
00276 double I = v.Z();
00277 double Htmp;
00278 double R,B,G;
00279
00280 if (H == 0.0)
00281 R = G = B = I;
00282 else if (H > 0.0 && H < TWO_PI_3 ) {
00283 Htmp = 1 / sqrt(3.0) * tan(H - PI_3);
00284 B = (1.0 - S) * I;
00285 G = (1.5 + 1.5*Htmp ) * I - ((0.5 + 1.5*Htmp) * B);
00286 R = 3.0 * I - G - B;
00287 }
00288 else if (H >= TWO_PI_3 && H < FOUR_PI_3) {
00289 Htmp = 1 / sqrt(3.0) * tan(H - PI);
00290 R = (1.0 - S) * I;
00291 B = (1.5 + 1.5*Htmp ) * I - ((0.5 + 1.5*Htmp) * R);
00292 G = 3.0 * I - B - R;
00293 }
00294 else {
00295 Htmp = 1 / sqrt(3.0) * tan(H - FIVE_PI_3);
00296 G = (1.0 - S) * I;
00297 R = (1.5 + 1.5*Htmp ) * I - ((0.5 + 1.5*Htmp) * G);
00298 B = 3.0 * I - R - G;
00299 }
00300 return Vec3Real64(R, G, B);
00301 }
00302
00303 #undef PI
00304 #undef TWO_PI
00305 #undef PI_3
00306 #undef TWO_PI_3
00307 #undef FOUR_PI_3
00308 #undef FIVE_PI_3
00309
00310
00311
00316 inline Vec3Real64
00317 ColXYZ2OOO(const Vec3Real64& v)
00318 {
00319 double E = v.X() *-0.004362 + v.Y() * 0.010954 + v.Z() * 0.003408;
00320 double El = v.X() * 0.004055 + v.Y() * 0.001220 + v.Z() *-0.004120;
00321 double Ell = v.X() * 0.011328 + v.Y() *-0.011755 + v.Z() *-0.000664;
00322
00323 return Vec3Real64(E, El, Ell);
00324 }
00325
00326
00327
00332 inline Vec3Real64
00333 ColOOO2XYZ(const Vec3Real64& v)
00334 {
00335 double X = v.X() * 103.337 + v.Y() * 68.824 + v.Z() * 103.435;
00336 double Y = v.X() * 92.297 + v.Y() * 74.949 + v.Z() * 8.714;
00337 double Z = v.X() * 129.034 + v.Y() * -152.804 + v.Z() * 104.383;
00338
00339 return Vec3Real64(X, Y, Z);
00340 }
00341
00342
00343
00350 inline Vec3Real64
00351 ColRGB2OOO(const Vec3Real64& v)
00352 {
00353 double E = v.X() * 0.000233846 + v.Y() * 0.00261968 + v.Z() * 0.00127135;
00354 double El = v.X() * 0.000726333 + v.Y() * 0.000718106+ v.Z() * -0.00121377;
00355 double Ell = v.X() * 0.000846833 + v.Y() * -0.00173932+ v.Z() * 0.000221515;
00356
00357 return Vec3Real64(E, El, Ell);
00358 }
00359
00360
00361
00368 inline Vec3Real64
00369 ColOOO2RGB(const Vec3Real64& v)
00370 {
00371 double R = v.X() * 328.084 + v.Y() * 469.182 + v.Z() * 687.853;
00372 double G = v.X() * 199.794 + v.Y() * 172.242 + v.Z() * -202.904;
00373 double B = v.X() * 314.533 + v.Y() * -441.212 + v.Z() * 291.574;
00374
00375 return Vec3Real64(R, G, B);
00376 }
00377
00378
00379
00380
00383 inline int
00384 ColRGB2int(const Vec3Real64& v)
00385 {
00386 int x = (int) (v.X());
00387 if (x < 0)
00388 x = 0;
00389 else {
00390 if (x > 255)
00391 x = 255;
00392 }
00393 int y = (int) (v.Y());
00394 if (y < 0)
00395 y = 0;
00396 else {
00397 if (y > 255)
00398 y = 255;
00399 }
00400 int z = (int) (v.Z());
00401 if (z < 0)
00402 z = 0;
00403 else {
00404 if (z > 255)
00405 z = 255;
00406 }
00407 return (255 << 24) | (x << 16) | (y << 8) | z;
00408 }
00409
00412 inline int
00413 ColRGB2int(const Vec3Int32& v)
00414 {
00415 int x = v.X();
00416 if (x < 0)
00417 x = 0;
00418 else {
00419 if (x > 255)
00420 x = 255;
00421 }
00422 int y = v.Y();
00423 if (y < 0)
00424 y = 0;
00425 else {
00426 if (y > 255)
00427 y = 255;
00428 }
00429 int z = v.Z();
00430 if (z < 0)
00431 z = 0;
00432 else {
00433 if (z > 255)
00434 z = 255;
00435 }
00436 return (255 << 24) | (x << 16) | (y << 8) | z;
00437 }
00438
00439 }
00440 }
00441 }
00442 }
00443
00444 #endif