37 #ifndef VIGRA_COLORCONVERSIONS_HXX
38 #define VIGRA_COLORCONVERSIONS_HXX
42 #include "mathutil.hxx"
43 #include "rgbvalue.hxx"
44 #include "functortraits.hxx"
51 template<
class ValueType>
52 inline ValueType gammaCorrection(
double value,
double gamma)
54 typedef typename NumericTraits<ValueType>::RealPromote Promote;
55 return NumericTraits<ValueType>::fromRealPromote(
56 RequiresExplicitCast<Promote>::cast(
58 ? -std::pow(-value,
gamma)
59 : std::pow(value,
gamma)));
62 template<
class ValueType>
63 inline ValueType gammaCorrection(
double value,
double gamma,
double norm)
65 typedef typename NumericTraits<ValueType>::RealPromote Promote;
66 return NumericTraits<ValueType>::fromRealPromote(
67 RequiresExplicitCast<Promote>::cast(
73 template<
class ValueType>
74 inline ValueType sRGBCorrection(
double value,
double norm)
77 typedef typename NumericTraits<ValueType>::RealPromote Promote;
78 return NumericTraits<ValueType>::fromRealPromote(
79 RequiresExplicitCast<Promote>::cast(
82 :
norm*(1.055*std::pow(value, 0.41666666666666667) - 0.055)));
85 template<
class ValueType>
86 inline ValueType inverse_sRGBCorrection(
double value,
double norm)
89 typedef typename NumericTraits<ValueType>::RealPromote Promote;
90 return NumericTraits<ValueType>::fromRealPromote(
91 RequiresExplicitCast<Promote>::cast(
94 :
norm*VIGRA_CSTD::pow((value + 0.055)/1.055, 2.4)));
276 template <
class From,
class To = From>
317 detail::gammaCorrection<To>(rgb[0], 0.45, max_),
318 detail::gammaCorrection<To>(rgb[1], 0.45, max_),
319 detail::gammaCorrection<To>(rgb[2], 0.45, max_));
322 static std::string targetColorSpace()
332 class RGB2RGBPrimeFunctor<unsigned char, unsigned char>
334 unsigned char lut_[256];
342 typedef TinyVector<unsigned char, 3>
value_type;
346 for(
int i=0; i<256; ++i)
348 lut_[i] = detail::gammaCorrection<unsigned char>(i, 0.45, 255.0);
354 for(
int i=0; i<256; ++i)
356 lut_[i] = detail::gammaCorrection<unsigned char>(i, 0.45, max);
361 TinyVector<unsigned char, 3>
operator()(V
const & rgb)
const
363 return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
366 static std::string targetColorSpace()
372 template <
class From,
class To>
373 class FunctorTraits<RGB2RGBPrimeFunctor<From, To> >
374 :
public FunctorTraitsBase<RGB2RGBPrimeFunctor<From, To> >
377 typedef VigraTrueType isUnaryFunctor;
404 template <
class From,
class To = From>
445 detail::sRGBCorrection<To>(rgb[0], max_),
446 detail::sRGBCorrection<To>(rgb[1], max_),
447 detail::sRGBCorrection<To>(rgb[2], max_));
450 static std::string targetColorSpace()
460 class RGB2sRGBFunctor<unsigned char, unsigned char>
462 unsigned char lut_[256];
470 typedef TinyVector<unsigned char, 3>
value_type;
474 for(
int i=0; i<256; ++i)
476 lut_[i] = detail::sRGBCorrection<unsigned char>(i, 255.0);
482 for(
int i=0; i<256; ++i)
484 lut_[i] = detail::sRGBCorrection<unsigned char>(i, max);
489 TinyVector<unsigned char, 3>
operator()(V
const & rgb)
const
491 return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
494 static std::string targetColorSpace()
500 template <
class From,
class To>
501 class FunctorTraits<RGB2sRGBFunctor<From, To> >
502 :
public FunctorTraitsBase<RGB2sRGBFunctor<From, To> >
505 typedef VigraTrueType isUnaryFunctor;
529 template <
class From,
class To = From>
554 : max_(255.0), gamma_(1.0/0.45)
561 : max_(max), gamma_(1.0/0.45)
569 detail::gammaCorrection<To>(rgb[0], gamma_, max_),
570 detail::gammaCorrection<To>(rgb[1], gamma_, max_),
571 detail::gammaCorrection<To>(rgb[2], gamma_, max_));
574 static std::string targetColorSpace()
585 class RGBPrime2RGBFunctor<unsigned char, unsigned char>
587 unsigned char lut_[256];
595 typedef TinyVector<unsigned char, 3>
value_type;
599 for(
int i=0; i<256; ++i)
601 lut_[i] = detail::gammaCorrection<unsigned char>(i, 1.0/0.45, 255.0);
607 for(
int i=0; i<256; ++i)
609 lut_[i] = detail::gammaCorrection<unsigned char>(i, 1.0/0.45, max);
614 TinyVector<unsigned char, 3>
operator()(V
const & rgb)
const
616 return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
619 static std::string targetColorSpace()
625 template <
class From,
class To>
626 class FunctorTraits<RGBPrime2RGBFunctor<From, To> >
627 :
public FunctorTraitsBase<RGBPrime2RGBFunctor<From, To> >
630 typedef VigraTrueType isUnaryFunctor;
657 template <
class From,
class To = From>
697 detail::inverse_sRGBCorrection<To>(rgb[0], max_),
698 detail::inverse_sRGBCorrection<To>(rgb[1], max_),
699 detail::inverse_sRGBCorrection<To>(rgb[2], max_));
702 static std::string targetColorSpace()
712 class sRGB2RGBFunctor<unsigned char, unsigned char>
714 unsigned char lut_[256];
722 typedef TinyVector<unsigned char, 3>
value_type;
726 for(
int i=0; i<256; ++i)
728 lut_[i] = detail::inverse_sRGBCorrection<unsigned char>(i, 255.0);
734 for(
int i=0; i<256; ++i)
736 lut_[i] = detail::inverse_sRGBCorrection<unsigned char>(i, max);
741 TinyVector<unsigned char, 3>
operator()(V
const & rgb)
const
743 return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
746 static std::string targetColorSpace()
752 template <
class From,
class To>
753 class FunctorTraits<sRGB2RGBFunctor<From, To> >
754 :
public FunctorTraitsBase<sRGB2RGBFunctor<From, To> >
757 typedef VigraTrueType isUnaryFunctor;
826 typedef detail::RequiresExplicitCast<component_type> Convert;
831 result[0] = Convert::cast(0.412453*red + 0.357580*green + 0.180423*blue);
832 result[1] = Convert::cast(0.212671*red + 0.715160*green + 0.072169*blue);
833 result[2] = Convert::cast(0.019334*red + 0.119193*green + 0.950227*blue);
837 static std::string targetColorSpace()
847 class FunctorTraits<RGB2XYZFunctor<T> >
848 :
public FunctorTraitsBase<RGB2XYZFunctor<T> >
851 typedef VigraTrueType isUnaryFunctor;
904 : gamma_(1.0/ 0.45), max_(max)
911 typedef detail::RequiresExplicitCast<component_type> Convert;
912 component_type red = detail::gammaCorrection<component_type>(rgb[0]/max_, gamma_);
913 component_type green = detail::gammaCorrection<component_type>(rgb[1]/max_, gamma_);
914 component_type blue = detail::gammaCorrection<component_type>(rgb[2]/max_, gamma_);
916 result[0] = Convert::cast(0.412453*red + 0.357580*green + 0.180423*blue);
917 result[1] = Convert::cast(0.212671*red + 0.715160*green + 0.072169*blue);
918 result[2] = Convert::cast(0.019334*red + 0.119193*green + 0.950227*blue);
922 static std::string targetColorSpace()
933 class FunctorTraits<RGBPrime2XYZFunctor<T> >
934 :
public FunctorTraitsBase<RGBPrime2XYZFunctor<T> >
937 typedef VigraTrueType isUnaryFunctor;
965 typedef typename NumericTraits<T>::RealPromote component_type;
1003 typedef detail::RequiresExplicitCast<component_type> Convert;
1004 component_type red = Convert::cast( 3.2404813432*xyz[0] - 1.5371515163*xyz[1] - 0.4985363262*xyz[2]);
1005 component_type green = Convert::cast(-0.9692549500*xyz[0] + 1.8759900015*xyz[1] + 0.0415559266*xyz[2]);
1006 component_type blue = Convert::cast( 0.0556466391*xyz[0] - 0.2040413384*xyz[1] + 1.0573110696*xyz[2]);
1007 return value_type(NumericTraits<T>::fromRealPromote(red * max_),
1008 NumericTraits<T>::fromRealPromote(green * max_),
1009 NumericTraits<T>::fromRealPromote(blue * max_));
1012 static std::string targetColorSpace()
1019 class FunctorTraits<XYZ2RGBFunctor<T> >
1020 :
public FunctorTraitsBase<XYZ2RGBFunctor<T> >
1023 typedef VigraTrueType isUnaryFunctor;
1047 typedef typename NumericTraits<T>::RealPromote component_type;
1050 component_type max_;
1073 : gamma_(0.45), max_(component_type(255.0))
1080 : gamma_(0.45), max_(max)
1088 typedef detail::RequiresExplicitCast<component_type> Convert;
1089 component_type red = Convert::cast( 3.2404813432*xyz[0] - 1.5371515163*xyz[1] - 0.4985363262*xyz[2]);
1090 component_type green = Convert::cast(-0.9692549500*xyz[0] + 1.8759900015*xyz[1] + 0.0415559266*xyz[2]);
1091 component_type blue = Convert::cast( 0.0556466391*xyz[0] - 0.2040413384*xyz[1] + 1.0573110696*xyz[2]);
1092 return value_type(NumericTraits<T>::fromRealPromote(detail::gammaCorrection<component_type>(red, gamma_) * max_),
1093 NumericTraits<T>::fromRealPromote(detail::gammaCorrection<component_type>(green, gamma_) * max_),
1094 NumericTraits<T>::fromRealPromote(detail::gammaCorrection<component_type>(blue, gamma_) * max_));
1097 static std::string targetColorSpace()
1104 class FunctorTraits<XYZ2RGBPrimeFunctor<T> >
1105 :
public FunctorTraitsBase<XYZ2RGBPrimeFunctor<T> >
1108 typedef VigraTrueType isUnaryFunctor;
1167 kappa_(24389.0/27.0),
1168 epsilon_(216.0/24389.0)
1175 if(xyz[1] == NumericTraits<T>::zero())
1177 result[0] = NumericTraits<component_type>::zero();
1178 result[1] = NumericTraits<component_type>::zero();
1179 result[2] = NumericTraits<component_type>::zero();
1183 typedef detail::RequiresExplicitCast<component_type> Convert;
1187 : 116.0 * VIGRA_CSTD::pow((
double)xyz[1], gamma_) - 16.0);
1188 component_type denom = Convert::cast(xyz[0] + 15.0*xyz[1] + 3.0*xyz[2]);
1192 result[1] = Convert::cast(13.0*L*(uprime - 0.197839));
1193 result[2] = Convert::cast(13.0*L*(vprime - 0.468342));
1198 static std::string targetColorSpace()
1204 double gamma_, kappa_, epsilon_;
1208 class FunctorTraits<XYZ2LuvFunctor<T> >
1209 :
public FunctorTraitsBase<XYZ2LuvFunctor<T> >
1212 typedef VigraTrueType isUnaryFunctor;
1249 ikappa_(27.0/24389.0)
1258 if(luv[0] == NumericTraits<T>::zero())
1260 result[0] = NumericTraits<component_type>::zero();
1261 result[1] = NumericTraits<component_type>::zero();
1262 result[2] = NumericTraits<component_type>::zero();
1266 typedef detail::RequiresExplicitCast<component_type> Convert;
1267 component_type uprime = Convert::cast(luv[1] / 13.0 / luv[0] + 0.197839);
1268 component_type vprime = Convert::cast(luv[2] / 13.0 / luv[0] + 0.468342);
1270 result[1] = Convert::cast(
1273 : VIGRA_CSTD::pow((luv[0] + 16.0) / 116.0, gamma_));
1274 result[0] = Convert::cast(9.0*uprime*result[1] / 4.0 / vprime);
1275 result[2] = Convert::cast(((9.0 / vprime - 15.0)*result[1] - result[0])/ 3.0);
1280 static std::string targetColorSpace()
1286 double gamma_, ikappa_;
1290 class FunctorTraits<Luv2XYZFunctor<T> >
1291 :
public FunctorTraitsBase<Luv2XYZFunctor<T> >
1294 typedef VigraTrueType isUnaryFunctor;
1350 kappa_(24389.0/27.0),
1351 epsilon_(216.0/24389.0)
1359 typedef detail::RequiresExplicitCast<component_type> Convert;
1360 component_type xgamma = Convert::cast(std::pow(xyz[0] / 0.950456, gamma_));
1361 component_type ygamma = Convert::cast(std::pow((
double)xyz[1], gamma_));
1362 component_type zgamma = Convert::cast(std::pow(xyz[2] / 1.088754, gamma_));
1366 : 116.0 * ygamma - 16.0);
1369 result[1] = Convert::cast(500.0*(xgamma - ygamma));
1370 result[2] = Convert::cast(200.0*(ygamma - zgamma));
1374 static std::string targetColorSpace()
1380 double gamma_, kappa_, epsilon_;
1384 class FunctorTraits<XYZ2LabFunctor<T> >
1385 :
public FunctorTraitsBase<XYZ2LabFunctor<T> >
1388 typedef VigraTrueType isUnaryFunctor;
1427 ikappa_(27.0/24389.0)
1435 typedef detail::RequiresExplicitCast<component_type> Convert;
1439 : std::pow((lab[0] + 16.0) / 116.0, gamma_));
1440 component_type ygamma = Convert::cast(std::pow((
double)Y, 1.0 / gamma_));
1441 component_type X = Convert::cast(std::pow(lab[1] / 500.0 + ygamma, gamma_) * 0.950456);
1442 component_type Z = Convert::cast(std::pow(-lab[2] / 200.0 + ygamma, gamma_) * 1.088754);
1450 static std::string targetColorSpace()
1456 double gamma_, ikappa_;
1460 class FunctorTraits<Lab2XYZFunctor<T> >
1461 :
public FunctorTraitsBase<Lab2XYZFunctor<T> >
1464 typedef VigraTrueType isUnaryFunctor;
1540 return xyz2luv(rgb2xyz(rgb));
1543 static std::string targetColorSpace()
1549 RGB2XYZFunctor<T> rgb2xyz;
1550 XYZ2LuvFunctor<component_type> xyz2luv;
1554 class FunctorTraits<RGB2LuvFunctor<T> >
1555 :
public FunctorTraitsBase<RGB2LuvFunctor<T> >
1558 typedef VigraTrueType isUnaryFunctor;
1634 return xyz2lab(rgb2xyz(rgb));
1637 static std::string targetColorSpace()
1643 RGB2XYZFunctor<T> rgb2xyz;
1644 XYZ2LabFunctor<component_type> xyz2lab;
1648 class FunctorTraits<RGB2LabFunctor<T> >
1649 :
public FunctorTraitsBase<RGB2LabFunctor<T> >
1652 typedef VigraTrueType isUnaryFunctor;
1669 typedef typename NumericTraits<T>::RealPromote component_type;
1702 return xyz2rgb(luv2xyz(luv));
1705 static std::string targetColorSpace()
1712 class FunctorTraits<Luv2RGBFunctor<T> >
1713 :
public FunctorTraitsBase<Luv2RGBFunctor<T> >
1716 typedef VigraTrueType isUnaryFunctor;
1733 typedef typename NumericTraits<T>::RealPromote component_type;
1773 return xyz2rgb(lab2xyz(lab));
1776 static std::string targetColorSpace()
1783 class FunctorTraits<Lab2RGBFunctor<T> >
1784 :
public FunctorTraitsBase<Lab2RGBFunctor<T> >
1787 typedef VigraTrueType isUnaryFunctor;
1856 return xyz2luv(rgb2xyz(rgb));
1859 static std::string targetColorSpace()
1865 RGBPrime2XYZFunctor<T> rgb2xyz;
1866 XYZ2LuvFunctor<component_type> xyz2luv;
1870 class FunctorTraits<RGBPrime2LuvFunctor<T> >
1871 :
public FunctorTraitsBase<RGBPrime2LuvFunctor<T> >
1874 typedef VigraTrueType isUnaryFunctor;
1943 return xyz2lab(rgb2xyz(rgb));
1946 static std::string targetColorSpace()
1952 RGBPrime2XYZFunctor<T> rgb2xyz;
1953 XYZ2LabFunctor<component_type> xyz2lab;
1957 class FunctorTraits<RGBPrime2LabFunctor<T> >
1958 :
public FunctorTraitsBase<RGBPrime2LabFunctor<T> >
1961 typedef VigraTrueType isUnaryFunctor;
1978 typedef typename NumericTraits<T>::RealPromote component_type;
2018 return xyz2rgb(luv2xyz(luv));
2021 static std::string targetColorSpace()
2028 class FunctorTraits<Luv2RGBPrimeFunctor<T> >
2029 :
public FunctorTraitsBase<Luv2RGBPrimeFunctor<T> >
2032 typedef VigraTrueType isUnaryFunctor;
2049 typedef typename NumericTraits<T>::RealPromote component_type;
2089 return xyz2rgb(lab2xyz(lab));
2092 static std::string targetColorSpace()
2099 class FunctorTraits<Lab2RGBPrimeFunctor<T> >
2100 :
public FunctorTraitsBase<Lab2RGBPrimeFunctor<T> >
2103 typedef VigraTrueType isUnaryFunctor;
2185 typedef detail::RequiresExplicitCast<component_type> Convert;
2191 result[0] = Convert::cast(0.299*red + 0.587*green + 0.114*blue);
2192 result[1] = Convert::cast(-0.1687358916*red - 0.3312641084*green + 0.5*blue);
2193 result[2] = Convert::cast(0.5*red - 0.4186875892*green - 0.0813124108*blue);
2197 static std::string targetColorSpace()
2207 class FunctorTraits<RGBPrime2YPrimePbPrFunctor<T> >
2208 :
public FunctorTraitsBase<RGBPrime2YPrimePbPrFunctor<T> >
2211 typedef VigraTrueType isUnaryFunctor;
2228 typedef typename NumericTraits<T>::RealPromote component_type;
2230 component_type max_;
2267 typedef detail::RequiresExplicitCast<component_type> Convert;
2268 component_type nred = Convert::cast(ypbpr[0] + 1.402*ypbpr[2]);
2269 component_type ngreen = Convert::cast(ypbpr[0] - 0.3441362862*ypbpr[1] - 0.7141362862*ypbpr[2]);
2270 component_type nblue = Convert::cast(ypbpr[0] + 1.772*ypbpr[1]);
2271 return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
2272 NumericTraits<T>::fromRealPromote(ngreen * max_),
2273 NumericTraits<T>::fromRealPromote(nblue * max_));
2276 static std::string targetColorSpace()
2283 class FunctorTraits<YPrimePbPr2RGBPrimeFunctor<T> >
2284 :
public FunctorTraitsBase<YPrimePbPr2RGBPrimeFunctor<T> >
2287 typedef VigraTrueType isUnaryFunctor;
2368 typedef detail::RequiresExplicitCast<component_type> Convert;
2374 result[0] = Convert::cast(0.299*red + 0.587*green + 0.114*blue);
2375 result[1] = Convert::cast(0.596*red - 0.274*green - 0.322*blue);
2376 result[2] = Convert::cast(0.212*red - 0.523*green + 0.311*blue);
2380 static std::string targetColorSpace()
2390 class FunctorTraits<RGBPrime2YPrimeIQFunctor<T> >
2391 :
public FunctorTraitsBase<RGBPrime2YPrimeIQFunctor<T> >
2394 typedef VigraTrueType isUnaryFunctor;
2411 typedef typename NumericTraits<T>::RealPromote component_type;
2413 component_type max_;
2450 typedef detail::RequiresExplicitCast<component_type> Convert;
2451 component_type nred = Convert::cast(yiq[0] + 0.9548892043*yiq[1] + 0.6221039350*yiq[2]);
2452 component_type ngreen = Convert::cast(yiq[0] - 0.2713547827*yiq[1] - 0.6475120259*yiq[2]);
2453 component_type nblue = Convert::cast(yiq[0] - 1.1072510054*yiq[1] + 1.7024603738*yiq[2]);
2454 return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
2455 NumericTraits<T>::fromRealPromote(ngreen * max_),
2456 NumericTraits<T>::fromRealPromote(nblue * max_));
2459 static std::string targetColorSpace()
2466 class FunctorTraits<YPrimeIQ2RGBPrimeFunctor<T> >
2467 :
public FunctorTraitsBase<YPrimeIQ2RGBPrimeFunctor<T> >
2470 typedef VigraTrueType isUnaryFunctor;
2551 typedef detail::RequiresExplicitCast<component_type> Convert;
2557 result[0] = Convert::cast(0.299*red + 0.587*green + 0.114*blue);
2558 result[1] = Convert::cast(-0.1471376975*red - 0.2888623025*green + 0.436*blue);
2559 result[2] = Convert::cast(0.6149122807*red - 0.5149122807*green - 0.100*blue);
2563 static std::string targetColorSpace()
2573 class FunctorTraits<RGBPrime2YPrimeUVFunctor<T> >
2574 :
public FunctorTraitsBase<RGBPrime2YPrimeUVFunctor<T> >
2577 typedef VigraTrueType isUnaryFunctor;
2594 typedef typename NumericTraits<T>::RealPromote component_type;
2596 component_type max_;
2633 typedef detail::RequiresExplicitCast<component_type> Convert;
2634 component_type nred = Convert::cast(yuv[0] + 1.140*yuv[2]);
2635 component_type ngreen = Convert::cast(yuv[0] - 0.3946517044*yuv[1] - 0.580681431*yuv[2]);
2636 component_type nblue = Convert::cast(yuv[0] + 2.0321100920*yuv[1]);
2637 return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
2638 NumericTraits<T>::fromRealPromote(ngreen * max_),
2639 NumericTraits<T>::fromRealPromote(nblue * max_));
2642 static std::string targetColorSpace()
2649 class FunctorTraits<YPrimeUV2RGBPrimeFunctor<T> >
2650 :
public FunctorTraitsBase<YPrimeUV2RGBPrimeFunctor<T> >
2653 typedef VigraTrueType isUnaryFunctor;
2724 typedef detail::RequiresExplicitCast<component_type> Convert;
2730 result[0] = Convert::cast(16.0 + 65.481*red + 128.553*green + 24.966*blue);
2731 result[1] = Convert::cast(128.0 - 37.79683972*red - 74.20316028*green + 112.0*blue);
2732 result[2] = Convert::cast(128.0 + 112.0*red - 93.78601998*green - 18.21398002*blue);
2736 static std::string targetColorSpace()
2746 class FunctorTraits<RGBPrime2YPrimeCbCrFunctor<T> >
2747 :
public FunctorTraitsBase<RGBPrime2YPrimeCbCrFunctor<T> >
2750 typedef VigraTrueType isUnaryFunctor;
2767 typedef typename NumericTraits<T>::RealPromote component_type;
2769 component_type max_;
2806 typedef detail::RequiresExplicitCast<component_type> Convert;
2807 component_type y = Convert::cast(ycbcr[0] - 16.0);
2808 component_type cb = Convert::cast(ycbcr[1] - 128.0);
2809 component_type cr = Convert::cast(ycbcr[2] - 128.0);
2811 component_type nred = Convert::cast(0.00456621*y + 0.006258928571*cr);
2812 component_type ngreen = Convert::cast(0.00456621*y - 0.001536322706*cb - 0.003188108420*cr);
2813 component_type nblue = Convert::cast(0.00456621*y + 0.007910714286*cb);
2814 return result_type(NumericTraits<T>::fromRealPromote(nred * max_),
2815 NumericTraits<T>::fromRealPromote(ngreen * max_),
2816 NumericTraits<T>::fromRealPromote(nblue * max_));
2819 static std::string targetColorSpace()
2826 class FunctorTraits<YPrimeCbCr2RGBPrimeFunctor<T> >
2827 :
public FunctorTraitsBase<YPrimeCbCr2RGBPrimeFunctor<T> >
2830 typedef VigraTrueType isUnaryFunctor;
2936 inline TinyVector<float, 3>
2937 polar2Lab(
double color,
double brightness,
double saturation)
2939 double angle = (color+39.9977)/180.0*M_PI;
2940 double normsat = saturation*133.809;
2943 result[0] = float(100.0*brightness);
2944 result[1] = float(normsat*VIGRA_CSTD::cos(angle));
2945 result[2] = float(normsat*VIGRA_CSTD::sin(angle));
2951 TinyVector<float, 3>
2954 return polar2Lab(polar[0], polar[1], polar[2]);
2974 TinyVector<float, 3>
2978 result[1] = float(lab[0]/100.0);
2979 double angle = (lab[1] == 0.0 && lab[2] == 0.0)
2981 : VIGRA_CSTD::atan2(lab[2], lab[1])/M_PI*180.0-39.9977;
2982 result[0] = angle < 0.0 ?
2983 float(angle + 360.0) :
2985 result[2] = float(VIGRA_CSTD::sqrt(lab[1]*lab[1] + lab[2]*lab[2])/133.809);
3022 inline TinyVector<float, 3>
3023 polar2Luv(
double color,
double brightness,
double saturation)
3025 double angle = (color+12.1727)/180.0*M_PI;
3026 double normsat = saturation*179.04;
3029 result[0] = float(100.0*brightness);
3030 result[1] = float(normsat*VIGRA_CSTD::cos(angle));
3031 result[2] = float(normsat*VIGRA_CSTD::sin(angle));
3036 TinyVector<float, 3>
3039 return polar2Luv(polar[0], polar[1], polar[2]);
3059 TinyVector<float, 3>
3063 result[1] = float(luv[0]/100.0);
3064 double angle = (luv[1] == 0.0 && luv[2] == 0.0)
3066 : VIGRA_CSTD::atan2(luv[2], luv[1])/M_PI*180.0-12.1727;
3067 result[0] = angle < 0.0 ?
3068 float(angle + 360.0) :
3070 result[2] = float(VIGRA_CSTD::sqrt(luv[1]*luv[1] + luv[2]*luv[2])/179.04);
3107 inline TinyVector<float, 3>
3110 double angle = (color+18.6481)/180.0*M_PI;
3111 double normsat = saturation*0.533887;
3114 result[0] = float(brightness);
3115 result[1] = float(-normsat*VIGRA_CSTD::sin(angle));
3116 result[2] = float(normsat*VIGRA_CSTD::cos(angle));
3121 TinyVector<float, 3>
3144 TinyVector<float, 3>
3148 result[1] = float(ypbpr[0]);
3149 double angle = (ypbpr[1] == 0.0 && ypbpr[2] == 0.0)
3151 : VIGRA_CSTD::atan2(-ypbpr[1], ypbpr[2])/M_PI*180.0-18.6481;
3152 result[0] = angle < 0.0 ?
3153 float(angle + 360.0) :
3155 result[2] = float(VIGRA_CSTD::sqrt(ypbpr[1]*ypbpr[1] + ypbpr[2]*ypbpr[2])/0.533887);
3192 inline TinyVector<float, 3>
3195 double angle = (color+18.6482)/180.0*M_PI;
3196 double normsat = saturation*119.591;
3199 result[0] = float(brightness*219.0 + 16.0);
3200 result[1] = float(-normsat*VIGRA_CSTD::sin(angle)+128.0);
3201 result[2] = float(normsat*VIGRA_CSTD::cos(angle)+128.0);
3206 TinyVector<float, 3>
3229 TinyVector<float, 3>
3233 result[1] = float((ycbcr[0]-16.0)/219.0);
3234 double cb = ycbcr[1]-128.0;
3235 double cr = ycbcr[2]-128.0;
3236 double angle = (cb == 0.0 && cr == 0.0)
3238 : VIGRA_CSTD::atan2(-cb, cr)/M_PI*180.0-18.6482;
3239 result[0] = angle < 0.0 ?
3240 float(angle + 360.0) :
3242 result[2] = float(VIGRA_CSTD::sqrt(cb*cb + cr*cr)/119.591);
3279 inline TinyVector<float, 3>
3282 double angle = (color-19.5807)/180.0*M_PI;
3283 double normsat = saturation*0.632582;
3286 result[0] = float(brightness);
3287 result[1] = float(normsat*VIGRA_CSTD::cos(angle));
3288 result[2] = float(-normsat*VIGRA_CSTD::sin(angle));
3293 TinyVector<float, 3>
3316 TinyVector<float, 3>
3320 result[1] = float(yiq[0]);
3321 double angle = (yiq[1] == 0.0 && yiq[2] == 0.0)
3323 : VIGRA_CSTD::atan2(-yiq[2], yiq[1])/M_PI*180.0+19.5807;
3324 result[0] = angle < 0.0 ?
3325 float(angle + 360.0) :
3327 result[2] = float(VIGRA_CSTD::sqrt(yiq[1]*yiq[1] + yiq[2]*yiq[2])/0.632582);
3364 inline TinyVector<float, 3>
3367 double angle = (color+13.4569)/180.0*M_PI;
3368 double normsat = saturation*0.632324;
3371 result[0] = float(brightness);
3372 result[1] = float(-normsat*VIGRA_CSTD::sin(angle));
3373 result[2] = float(normsat*VIGRA_CSTD::cos(angle));
3378 TinyVector<float, 3>
3401 TinyVector<float, 3>
3405 result[1] = float(yuv[0]);
3406 double angle = (yuv[1] == 0.0 && yuv[2] == 0.0)
3408 : VIGRA_CSTD::atan2(-yuv[1], yuv[2])/M_PI*180.0-13.4569;
3409 result[0] = angle < 0.0 ?
3410 float(angle + 360.0) :
3412 result[2] = float(VIGRA_CSTD::sqrt(yuv[1]*yuv[1] + yuv[2]*yuv[2])/0.632324);