vigra - vigra/colorconversions.hxx Source File

[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

colorconversions.hxx |

1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2002 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35
36
37 #ifndef VIGRA_COLORCONVERSIONS_HXX
38 #define VIGRA_COLORCONVERSIONS_HXX
39
40 #include <cmath>
41 #include <string>
42 #include "mathutil.hxx"
43 #include "rgbvalue.hxx"
44 #include "functortraits.hxx"
45
46 namespace vigra {
47
48 namespace detail
49 {
50
51 template<class ValueType>
52 inline ValueType gammaCorrection(double value, double gamma)
53 {
54 typedef typename NumericTraits<ValueType>::RealPromote Promote;
55 return NumericTraits<ValueType>::fromRealPromote(
56 RequiresExplicitCast<Promote>::cast(
57 (value < 0.0)
58 ? -std::pow(-value, gamma)
59 : std::pow(value, gamma)));
60 }
61
62 template<class ValueType>
63 inline ValueType gammaCorrection(double value, double gamma, double norm)
64 {
65 typedef typename NumericTraits<ValueType>::RealPromote Promote;
66 return NumericTraits<ValueType>::fromRealPromote(
67 RequiresExplicitCast<Promote>::cast(
68 (value < 0.0)
69 ? -norm*std::pow(-value/norm, gamma)
70 : norm*std::pow(value/norm, gamma)));
71 }
72
73 template<class ValueType>
74 inline ValueType sRGBCorrection(double value, double norm)
75 {
76 value /= norm;
77 typedef typename NumericTraits<ValueType>::RealPromote Promote;
78 return NumericTraits<ValueType>::fromRealPromote(
79 RequiresExplicitCast<Promote>::cast(
80 (value <= 0.0031308)
81 ? norm*12.92*value
82 : norm*(1.055*std::pow(value, 0.41666666666666667) - 0.055)));
83 }
84
85 template<class ValueType>
86 inline ValueType inverse_sRGBCorrection(double value, double norm)
87 {
88 value /= norm;
89 typedef typename NumericTraits<ValueType>::RealPromote Promote;
90 return NumericTraits<ValueType>::fromRealPromote(
91 RequiresExplicitCast<Promote>::cast(
92 (value <= 0.04045)
93 ? norm*value / 12.92
94 : norm*VIGRA_CSTD::pow((value + 0.055)/1.055, 2.4)));
95 }
96
97
98 } // namespace detail
99
100 /** \defgroup ColorConversions Color Space Conversions
101
102 Convert between RGB, sRGB, R'G'B', XYZ, L*a*b*, L*u*v*, Y'PbPr, Y'CbCr, Y'IQ, and Y'UV color spaces.
103
104 <b>\#include</b> <vigra/colorconversions.hxx><br>
105 Namespace: vigra
106
107 <UL>
108 <LI> <b>RGB/sRGB/R'G'B'</b><br>
109 <em>linear and non-linear (gamma corrected) additive color</em>
110 <p>
111 <UL style="list-style-image:url(documents/bullet.gif)">
112 <LI> \ref vigra::RGB2sRGBFunctor
113 <LI> \ref vigra::sRGB2RGBFunctor
114 <LI> \ref vigra::RGB2RGBPrimeFunctor
115 <LI> \ref vigra::RGBPrime2RGBFunctor
116 </UL><p>
117 <LI> <b>XYZ</b><br>
118 <em>device independent color representation
119 (according to Publication CIE No 15.2 "Colorimetry"
120 and ITU-R Recommendation BT.709)</em>
121 <p>
122 <UL style="list-style-image:url(documents/bullet.gif)">
123 <LI> \ref vigra::RGB2XYZFunctor
124 <LI> \ref vigra::RGBPrime2XYZFunctor
125 <LI> \ref vigra::XYZ2RGBFunctor
126 <LI> \ref vigra::XYZ2RGBPrimeFunctor
127 </UL><p>
128 <LI> <b>L*a*b* </b><br>
129 <em>perceptually uniform color representation
130 (according to Publication CIE No 15.2 "Colorimetry" and
131 ITU-R Recommendation BT.709)</em>
132 <p>
133 <UL style="list-style-image:url(documents/bullet.gif)">
134 <LI> \ref vigra::RGB2LabFunctor
135 <LI> \ref vigra::RGBPrime2LabFunctor
136 <LI> \ref vigra::XYZ2LabFunctor
137 <LI> \ref vigra::Lab2RGBFunctor
138 <LI> \ref vigra::Lab2RGBPrimeFunctor
139 <LI> \ref vigra::Lab2XYZFunctor
140 <LI> \ref polar2Lab()
141 <LI> \ref lab2Polar()
142 </UL><p>
143 <LI> <b>L*u*v* </b><br>
144 <em>perceptually uniform color representation
145 (according to Publication CIE No 15.2 "Colorimetry" and
146 ITU-R Recommendation BT.709)</em>
147 <p>
148 <UL style="list-style-image:url(documents/bullet.gif)">
149 <LI> \ref vigra::RGB2LuvFunctor
150 <LI> \ref vigra::RGBPrime2LuvFunctor
151 <LI> \ref vigra::XYZ2LuvFunctor
152 <LI> \ref vigra::Luv2RGBFunctor
153 <LI> \ref vigra::Luv2RGBPrimeFunctor
154 <LI> \ref vigra::Luv2XYZFunctor
155 <LI> \ref polar2Luv()
156 <LI> \ref luv2Polar()
157 </UL><p>
158 <LI> <b>Y'PbPr and Y'CbCr </b><br>
159 <em>color difference coding
160 (according to ITU-R Recommendation BT. 601)</em>
161 <p>
162 <UL style="list-style-image:url(documents/bullet.gif)">
163 <LI> \ref vigra::RGBPrime2YPrimePbPrFunctor
164 <LI> \ref vigra::YPrimePbPr2RGBPrimeFunctor
165 <LI> \ref polar2YPrimePbPr()
166 <LI> \ref yPrimePbPr2Polar()
167 <LI> \ref vigra::RGBPrime2YPrimeCbCrFunctor
168 <LI> \ref vigra::YPrimeCbCr2RGBPrimeFunctor
169 <LI> \ref polar2YPrimeCbCr()
170 <LI> \ref yPrimeCbCr2Polar()
171 </UL><p>
172 <LI> <b>Y'UV and Y'IQ </b><br>
173 <em>analog video coding according to NTSC and PAL standards</em>
174 <p>
175 <UL style="list-style-image:url(documents/bullet.gif)">
176 <LI> \ref vigra::RGBPrime2YPrimeUVFunctor
177 <LI> \ref vigra::YPrimeUV2RGBPrimeFunctor
178 <LI> \ref polar2YPrimeUV()
179 <LI> \ref yPrimeUV2Polar()
180 <LI> \ref vigra::RGBPrime2YPrimeIQFunctor
181 <LI> \ref vigra::YPrimeIQ2RGBPrimeFunctor
182 <LI> \ref polar2YPrimeIQ()
183 <LI> \ref yPrimeIQ2Polar()
184 </UL><p>
185 </UL>
186
187 \anchor _details
188 This module provides conversion from RGB/R'G'B' into more perceptually uniform
189 color spaces. In image analysis, colors are usually converted into another color space
190 in order to get good estimates of perceived color differences by just calculating
191 Euclidean distances between the transformed colors. The L*a*b* and L*u*v* were
192 designed with exactly this application in mind and thus give the best results. But these
193 conversions are also the most computationally demanding. The Y'PbPr color difference
194 space (designed for coding digital video) is computationally much cheaper, and
195 almost as good. Y'CbCr represents essentially the same transformation, but the color values
196 are scaled so that they can be stored with 8 bits per channel with minimal loss of
197 information. The other transformations are of lesser interest here: XYZ is a device independent
198 (but not perceptually uniform) color representation, and Y'IQ and Y'UV are the color
199 spaces used by the PAL and NTSC analog video standards. Detailed information about
200 these color spaces and their transformations can be found in
201 <a href="http://www.poynton.com/ColorFAQ.html">Charles Poynton's Color FAQ</a>
202
203 When you want to perform a color conversion, you must first know in which
204 color space the data are given. Although this sounds trivial, it is
205 quite often done wrong, because the distinction between RGB and sRGB (still images) or R'G'B'
206 (digital video) is frequently overlooked: nowadays, most still images are stored in
207 sRGB space, and treating them as RGB leads to wrong results (although the color primaries
208 are named the same). RGB and R'G'B' are related by a so called <em>gamma correction</em>:
209
210 \f[
211 C' = C_{max} \left(\frac{C_{RGB}}{C_{max}} \right)^{0.45} \qquad
212 \f]
213
214 where C represents one of the color channels R, G, and B, and \f$ C_{max} \f$ usually equals 255.
215 The sRGB color space realizes a slight enhancement of this definition:
216
217 \f[
218 C_{sRGB} = \left\{\begin{array}{ll}
219 12.92\,C_{RGB} & \textrm{ if }\frac{C_{RGB}}{C_{max}} \le 0.00304 \\
220 C_{max}\left( 1.055 \left(\frac{C_{RGB}}{C_{max}}\right)^{1/2.4}-0.055\right) & \textrm{ otherwise}
221 \end{array} \right.
222 \f]
223
224 sRGB has now become a widely accepted international standard (IEC 61966-2.1) which is used by most
225 consumer products (digital cameras, printers, and screens). In practice, you can
226 distinguish between linear and gamma-corrected red, green, and blue by displaying the images: if they look
227 too dark, they are probably RGB, if they are OK, they are likely sRGB. (However, there are still a few older
228 graphics cards and display programs which silently apply an additional gamma correction to every image,
229 so that RGB appears correct and sRGB is too bright.) Whether or not the data are represented
230 in the sRGB color space can also be seen in the color space tag of an image's EXIF data, if available.
231
232 The distinction between RGB and R'G'B' is important because some conversions start at
233 RGB (XYZ, L*a*b*, L*u*v*), while others start at R'G'B' (Y'PbPr, Y'CbCr, Y'IQ, and Y'UV).
234 The names of VIGRA's color conversion functors always make clear to which color space
235 they must be applied.
236
237 In addition VIGRA provides a <em>\ref PolarColors "polar coordinate interface"</em>
238 to several color spaces (L*a*b*, L*u*v*, Y'PbPr, Y'CbCr, Y'IQ, and Y'UV). This
239 interface makes use of the fact that these color spaces are conceptually similar:
240 they represent colors by a "brightness" coordinate (L* or Y') and a pair of
241 "chromaticity" coordinates that span a plane of colors with equal brightness.
242 The polar representation transforms chroma coordinates into a color "angle"
243 (similar to hue in the HSV system) and a "saturation". The polar coordinates are
244 normalized so that a color angle of 0 degrees is always associated with red
245 (green is at about 120 degrees, blue at about 240 degrees - exact values differ
246 between color spaces). A saturation of 1 is the highest saturation that any RGB color
247 in the unit cube can have after transformation into the respective color space,
248 and saturation 0 corresponds to gray. Polar coordinates provide a more intuitive
249 interface to color specification by users and make different color spaces somewhat
250 comparable.
251 */
252 //@{
253
254
255 /** \brief Convert linear (raw) RGB into non-linear (gamma corrected) R'G'B'.
256
257 <b>\#include</b> <vigra/colorconversions.hxx><br>
258 Namespace: vigra
259
260 The functor realizes the transformation
261
262 \f[
263 R' = R_{max} \left(\frac{R}{R_{max}} \right)^{0.45} \qquad
264 G' = G_{max} \left(\frac{G}{G_{max}} \right)^{0.45} \qquad
265 B' = B_{max} \left(\frac{B}{B_{max}} \right)^{0.45}
266 \f]
267
268 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
269 in the constructor. If both source and target colors components are stored
270 as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
271
272 <b> Traits defined:</b>
273
274 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
275 */
276 template <class From, class To = From>
277 class RGB2RGBPrimeFunctor
278 {
279 public:
280
281 /** the functor's argument type
282 */
283 typedef TinyVector<From, 3> argument_type;
284
285 /** the functor's result type
286 */
287 typedef TinyVector<To, 3> result_type;
288
289 /** \deprecated use argument_type and result_type
290 */
291 typedef TinyVector<To, 3> value_type;
292
293 /** the result component's promote type
294 */
295 typedef typename NumericTraits<To>::RealPromote component_type;
296
297 /** Default constructor.
298 The maximum value for each RGB component defaults to 255
299 */
300 RGB2RGBPrimeFunctor()
301 : max_(255.0)
302 {}
303
304 /** constructor
305 \arg max - the maximum value for each RGB component
306 */
307 RGB2RGBPrimeFunctor(component_type max)
308 : max_(max)
309 {}
310
311 /** apply the transformation
312 */
313 template <class V>
314 result_type operator()(V const & rgb) const
315 {
316 return TinyVector<To, 3>(
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_));
320 }
321
322 static std::string targetColorSpace()
323 {
324 return "RGB'";
325 }
326
327 private:
328 component_type max_;
329 };
330
331 template <>
332 class RGB2RGBPrimeFunctor<unsigned char, unsigned char>
333 {
334 unsigned char lut_[256];
335
336 public:
337
338 typedef TinyVector<unsigned char, 3> argument_type;
339
340 typedef TinyVector<unsigned char, 3> result_type;
341
342 typedef TinyVector<unsigned char, 3> value_type;
343
344 RGB2RGBPrimeFunctor()
345 {
346 for(int i=0; i<256; ++i)
347 {
348 lut_[i] = detail::gammaCorrection<unsigned char>(i, 0.45, 255.0);
349 }
350 }
351
352 RGB2RGBPrimeFunctor(double max)
353 {
354 for(int i=0; i<256; ++i)
355 {
356 lut_[i] = detail::gammaCorrection<unsigned char>(i, 0.45, max);
357 }
358 }
359
360 template <class V>
361 TinyVector<unsigned char, 3> operator()(V const & rgb) const
362 {
363 return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
364 }
365
366 static std::string targetColorSpace()
367 {
368 return "RGB'";
369 }
370 };
371
372 template <class From, class To>
373 class FunctorTraits<RGB2RGBPrimeFunctor<From, To> >
374 : public FunctorTraitsBase<RGB2RGBPrimeFunctor<From, To> >
375 {
376 public:
377 typedef VigraTrueType isUnaryFunctor;
378 };
379
380 /** \brief Convert linear (raw) RGB into standardized sRGB.
381
382 <b>\#include</b> <vigra/colorconversions.hxx><br>
383 Namespace: vigra
384
385 The sRGB color space is a slight improvement over the R'G'B' space. It is now a widely accepted
386 international standard (IEC 61966-2.1) which is used by most consumer products
387 (digital cameras, printers, and screens). The functor realizes the transformation
388
389 \f[
390 C_{sRGB} = \left\{ \begin{array}{ll}
391 12.92\,C_{RGB} & \textrm{ if }\frac{C_{RGB}}{C_{max}} \le 0.0031308 \\
392 C_{max}\left( 1.055 \left(\frac{C_{RGB}}{C_{max}}\right)^{1/2.4}-0.055\right) & \textrm{ otherwise}
393 \end{array} \right.
394 \f]
395
396 where C is any of the primaries R, G, and B. By default, \f$ C_{max} = 255 \f$ (this default can be
397 overridden in the constructor). If both source and target color components are stored
398 as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
399
400 <b> Traits defined:</b>
401
402 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
403 */
404 template <class From, class To = From>
405 class RGB2sRGBFunctor
406 {
407 public:
408
409 /** the functor's argument type
410 */
411 typedef TinyVector<From, 3> argument_type;
412
413 /** the functor's result type
414 */
415 typedef TinyVector<To, 3> result_type;
416
417 /** \deprecated use argument_type and result_type
418 */
419 typedef TinyVector<To, 3> value_type;
420
421 /** the result component's promote type
422 */
423 typedef typename NumericTraits<To>::RealPromote component_type;
424
425 /** Default constructor.
426 The maximum value for each RGB component defaults to 255
427 */
428 RGB2sRGBFunctor()
429 : max_(255.0)
430 {}
431
432 /** constructor
433 \arg max - the maximum value for each RGB component
434 */
435 RGB2sRGBFunctor(component_type max)
436 : max_(max)
437 {}
438
439 /** apply the transformation
440 */
441 template <class V>
442 result_type operator()(V const & rgb) const
443 {
444 return TinyVector<To, 3>(
445 detail::sRGBCorrection<To>(rgb[0], max_),
446 detail::sRGBCorrection<To>(rgb[1], max_),
447 detail::sRGBCorrection<To>(rgb[2], max_));
448 }
449
450 static std::string targetColorSpace()
451 {
452 return "sRGB";
453 }
454
455 private:
456 component_type max_;
457 };
458
459 template <>
460 class RGB2sRGBFunctor<unsigned char, unsigned char>
461 {
462 unsigned char lut_[256];
463
464 public:
465
466 typedef TinyVector<unsigned char, 3> argument_type;
467
468 typedef TinyVector<unsigned char, 3> result_type;
469
470 typedef TinyVector<unsigned char, 3> value_type;
471
472 RGB2sRGBFunctor()
473 {
474 for(int i=0; i<256; ++i)
475 {
476 lut_[i] = detail::sRGBCorrection<unsigned char>(i, 255.0);
477 }
478 }
479
480 RGB2sRGBFunctor(double max)
481 {
482 for(int i=0; i<256; ++i)
483 {
484 lut_[i] = detail::sRGBCorrection<unsigned char>(i, max);
485 }
486 }
487
488 template <class V>
489 TinyVector<unsigned char, 3> operator()(V const & rgb) const
490 {
491 return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
492 }
493
494 static std::string targetColorSpace()
495 {
496 return "sRGB";
497 }
498 };
499
500 template <class From, class To>
501 class FunctorTraits<RGB2sRGBFunctor<From, To> >
502 : public FunctorTraitsBase<RGB2sRGBFunctor<From, To> >
503 {
504 public:
505 typedef VigraTrueType isUnaryFunctor;
506 };
507
508 /** \brief Convert non-linear (gamma corrected) R'G'B' into non-linear (raw) RGB.
509
510 <b>\#include</b> <vigra/colorconversions.hxx><br>
511 Namespace: vigra
512
513 The functor realizes the transformation
514
515 \f[
516 R = R_{max} \left(\frac{R'}{R_{max}} \right)^{1/0.45} \qquad
517 G = G_{max} \left(\frac{G'}{G_{max}} \right)^{1/0.45} \qquad
518 B = B_{max} \left(\frac{B'}{B_{max}} \right)^{1/0.45}
519 \f]
520
521 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
522 in the constructor. If both source and target color components are stored
523 as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
524
525 <b> Traits defined:</b>
526
527 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
528 */
529 template <class From, class To = From>
530 class RGBPrime2RGBFunctor
531 {
532 public:
533
534 /** the functor's argument type
535 */
536 typedef TinyVector<From, 3> argument_type;
537
538 /** the functor's result type
539 */
540 typedef TinyVector<To, 3> result_type;
541
542 /** \deprecated use argument_type and result_type
543 */
544 typedef TinyVector<To, 3> value_type;
545
546 /** the result component's promote type
547 */
548 typedef typename NumericTraits<To>::RealPromote component_type;
549
550 /** Default constructor.
551 The maximum value for each RGB component defaults to 255.
552 */
553 RGBPrime2RGBFunctor()
554 : max_(255.0), gamma_(1.0/0.45)
555 {}
556
557 /** constructor
558 \arg max - the maximum value for each RGB component
559 */
560 RGBPrime2RGBFunctor(component_type max)
561 : max_(max), gamma_(1.0/0.45)
562 {}
563
564 /** apply the transformation
565 */
566 result_type operator()(argument_type const & rgb) const
567 {
568 return TinyVector<To, 3>(
569 detail::gammaCorrection<To>(rgb[0], gamma_, max_),
570 detail::gammaCorrection<To>(rgb[1], gamma_, max_),
571 detail::gammaCorrection<To>(rgb[2], gamma_, max_));
572 }
573
574 static std::string targetColorSpace()
575 {
576 return "RGB";
577 }
578
579 private:
580 component_type max_;
581 double gamma_;
582 };
583
584 template <>
585 class RGBPrime2RGBFunctor<unsigned char, unsigned char>
586 {
587 unsigned char lut_[256];
588
589 public:
590
591 typedef TinyVector<unsigned char, 3> argument_type;
592
593 typedef TinyVector<unsigned char, 3> result_type;
594
595 typedef TinyVector<unsigned char, 3> value_type;
596
597 RGBPrime2RGBFunctor()
598 {
599 for(int i=0; i<256; ++i)
600 {
601 lut_[i] = detail::gammaCorrection<unsigned char>(i, 1.0/0.45, 255.0);
602 }
603 }
604
605 RGBPrime2RGBFunctor(double max)
606 {
607 for(int i=0; i<256; ++i)
608 {
609 lut_[i] = detail::gammaCorrection<unsigned char>(i, 1.0/0.45, max);
610 }
611 }
612
613 template <class V>
614 TinyVector<unsigned char, 3> operator()(V const & rgb) const
615 {
616 return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
617 }
618
619 static std::string targetColorSpace()
620 {
621 return "RGB";
622 }
623 };
624
625 template <class From, class To>
626 class FunctorTraits<RGBPrime2RGBFunctor<From, To> >
627 : public FunctorTraitsBase<RGBPrime2RGBFunctor<From, To> >
628 {
629 public:
630 typedef VigraTrueType isUnaryFunctor;
631 };
632
633 /** \brief Convert standardized sRGB into non-linear (raw) RGB.
634
635 <b>\#include</b> <vigra/colorconversions.hxx><br>
636 Namespace: vigra
637
638 The sRGB color space is a slight improvement over the R'G'B' space. Is is now a widely accepted
639 international standard (IEC 61966-2.1) which is used by most consumer products
640 (digital cameras, printers, and screens). The functor realizes the transformation
641
642 \f[
643 C_{RGB} = \left\{\begin{array}{ll}
644 C_{sRGB} / 12.92 & \textrm{if }\frac{C_{sRGB}}{C_{max}} \le 0.04045 \\
645 C_{max}\left( \frac{C_{sRGB}/C_{max}+0.055}{1.055}\right)^{2.4} & \textrm{otherwise}
646 \end{array}\right.
647 \f]
648
649 where C is one of the color channels R, G, or B, and \f$ C_{max}\f$ equals 255 by default (This default
650 can be overridden in the constructor). If both source and target color components are stored
651 as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
652
653 <b> Traits defined:</b>
654
655 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
656 */
657 template <class From, class To = From>
658 class sRGB2RGBFunctor
659 {
660 public:
661
662 /** the functor's argument type
663 */
664 typedef TinyVector<From, 3> argument_type;
665
666 /** the functor's result type
667 */
668 typedef TinyVector<To, 3> result_type;
669
670 /** \deprecated use argument_type and result_type
671 */
672 typedef TinyVector<To, 3> value_type;
673
674 /** the result component's promote type
675 */
676 typedef typename NumericTraits<To>::RealPromote component_type;
677
678 /** Default constructor.
679 The maximum value for each RGB component defaults to 255.
680 */
681 sRGB2RGBFunctor()
682 : max_(255.0)
683 {}
684
685 /** constructor
686 \arg max - the maximum value for each RGB component
687 */
688 sRGB2RGBFunctor(component_type max)
689 : max_(max)
690 {}
691
692 /** apply the transformation
693 */
694 result_type operator()(argument_type const & rgb) const
695 {
696 return TinyVector<To, 3>(
697 detail::inverse_sRGBCorrection<To>(rgb[0], max_),
698 detail::inverse_sRGBCorrection<To>(rgb[1], max_),
699 detail::inverse_sRGBCorrection<To>(rgb[2], max_));
700 }
701
702 static std::string targetColorSpace()
703 {
704 return "RGB";
705 }
706
707 private:
708 component_type max_;
709 };
710
711 template <>
712 class sRGB2RGBFunctor<unsigned char, unsigned char>
713 {
714 unsigned char lut_[256];
715
716 public:
717
718 typedef TinyVector<unsigned char, 3> argument_type;
719
720 typedef TinyVector<unsigned char, 3> result_type;
721
722 typedef TinyVector<unsigned char, 3> value_type;
723
724 sRGB2RGBFunctor()
725 {
726 for(int i=0; i<256; ++i)
727 {
728 lut_[i] = detail::inverse_sRGBCorrection<unsigned char>(i, 255.0);
729 }
730 }
731
732 sRGB2RGBFunctor(double max)
733 {
734 for(int i=0; i<256; ++i)
735 {
736 lut_[i] = detail::inverse_sRGBCorrection<unsigned char>(i, max);
737 }
738 }
739
740 template <class V>
741 TinyVector<unsigned char, 3> operator()(V const & rgb) const
742 {
743 return TinyVector<unsigned char, 3>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb[2]]);
744 }
745
746 static std::string targetColorSpace()
747 {
748 return "RGB";
749 }
750 };
751
752 template <class From, class To>
753 class FunctorTraits<sRGB2RGBFunctor<From, To> >
754 : public FunctorTraitsBase<sRGB2RGBFunctor<From, To> >
755 {
756 public:
757 typedef VigraTrueType isUnaryFunctor;
758 };
759
760 /** \brief Convert linear (raw) RGB into standardized tri-stimulus XYZ.
761
762 <b>\#include</b> <vigra/colorconversions.hxx><br>
763 Namespace: vigra
764
765 According to ITU-R Recommendation BT.709, the functor realizes the transformation
766
767 \f[
768 \begin{array}{rcl}
769 X & = & 0.412453\enspace R / R_{max} + 0.357580\enspace G / G_{max} + 0.180423\enspace B / B_{max}\\
770 Y & = & 0.212671\enspace R / R_{max} + 0.715160\enspace G / G_{max} + 0.072169\enspace B / B_{max} \\
771 Z & = & 0.019334\enspace R / R_{max} + 0.119193\enspace G / G_{max} + 0.950227\enspace B / B_{max}
772 \end{array}
773 \f]
774
775 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
776 in the constructor. X, Y, and Z are always positive and reach their maximum for white.
777 The white point is obtained by transforming RGB(255, 255, 255). It corresponds to the
778 D65 illuminant. Y represents the <em>luminance</em> ("brightness") of the color. The above
779 transformation is officially defined in connection with the sRGB color space (i.e. when the RGB values
780 are obtained by inverse gamma correction of sRGB), other color spaces use slightly different numbers
781 or another standard illuminant (which gives raise to significantly different numbers).
782
783 <b> Traits defined:</b>
784
785 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
786 */
787 template <class T>
788 class RGB2XYZFunctor
789 {
790 public:
791
792 /** the result's component type
793 */
794 typedef typename NumericTraits<T>::RealPromote component_type;
795
796 /** the functor's argument type
797 */
798 typedef TinyVector<T, 3> argument_type;
799
800 /** the functor's result type
801 */
802 typedef TinyVector<component_type, 3> result_type;
803
804 /** \deprecated use argument_type and result_type
805 */
806 typedef TinyVector<component_type, 3> value_type;
807
808 /** default constructor.
809 The maximum value for each RGB component defaults to 255.
810 */
811 RGB2XYZFunctor()
812 : max_(255.0)
813 {}
814
815 /** constructor
816 \arg max - the maximum value for each RGB component
817 */
818 RGB2XYZFunctor(component_type max)
819 : max_(max)
820 {}
821
822 /** apply the transformation
823 */
824 result_type operator()(argument_type const & rgb) const
825 {
826 typedef detail::RequiresExplicitCast<component_type> Convert;
827 component_type red = rgb[0] / max_;
828 component_type green = rgb[1] / max_;
829 component_type blue = rgb[2] / max_;
830 result_type result;
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);
834 return result;
835 }
836
837 static std::string targetColorSpace()
838 {
839 return "XYZ";
840 }
841
842 private:
843 component_type max_;
844 };
845
846 template <class T>
847 class FunctorTraits<RGB2XYZFunctor<T> >
848 : public FunctorTraitsBase<RGB2XYZFunctor<T> >
849 {
850 public:
851 typedef VigraTrueType isUnaryFunctor;
852 };
853
854 /** \brief Convert non-linear (gamma corrected) R'G'B' into standardized tri-stimulus XYZ.
855
856 <b>\#include</b> <vigra/colorconversions.hxx><br>
857 Namespace: vigra
858
859 The functor realizes the transformation
860
861 \f[
862 R'G'B' \Rightarrow RGB \Rightarrow XYZ
863 \f]
864
865 See vigra::RGBPrime2RGBFunctor and vigra::RGB2XYZFunctor for a description of the two
866 steps.
867
868 <b> Traits defined:</b>
869
870 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
871 */
872 template <class T>
873 class RGBPrime2XYZFunctor
874 {
875 public:
876
877 /** the result's component type
878 */
879 typedef typename NumericTraits<T>::RealPromote component_type;
880
881 /** the functor's argument type
882 */
883 typedef TinyVector<T, 3> argument_type;
884
885 /** the functor's result type
886 */
887 typedef TinyVector<component_type, 3> result_type;
888
889 /** \deprecated use argument_type and result_type
890 */
891 typedef TinyVector<component_type, 3> value_type;
892
893 /** default constructor
894 The maximum value for each RGB component defaults to 255.
895 */
896 RGBPrime2XYZFunctor()
897 : gamma_(1.0/ 0.45), max_(component_type(255.0))
898 {}
899
900 /** constructor
901 \arg max - the maximum value for each RGB component
902 */
903 RGBPrime2XYZFunctor(component_type max)
904 : gamma_(1.0/ 0.45), max_(max)
905 {}
906
907 /** apply the transformation
908 */
909 result_type operator()(argument_type const & rgb) const
910 {
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_);
915 result_type result;
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);
919 return result;
920 }
921
922 static std::string targetColorSpace()
923 {
924 return "XYZ";
925 }
926
927 private:
928 double gamma_;
929 component_type max_;
930 };
931
932 template <class T>
933 class FunctorTraits<RGBPrime2XYZFunctor<T> >
934 : public FunctorTraitsBase<RGBPrime2XYZFunctor<T> >
935 {
936 public:
937 typedef VigraTrueType isUnaryFunctor;
938 };
939
940 /** \brief Convert standardized tri-stimulus XYZ into linear (raw) RGB.
941
942 <b>\#include</b> <vigra/colorconversions.hxx><br>
943 Namespace: vigra
944
945 According to ITU-R Recommendation BT.709, the functor realizes the transformation
946
947 \f[
948 \begin{array}{rcl}
949 R & = & R_{max} (3.2404813432\enspace X - 1.5371515163\enspace Y - 0.4985363262\enspace Z) \\
950 G & = & G_{max} (-0.9692549500\enspace X + 1.8759900015\enspace Y + 0.0415559266\enspace Z) \\
951 B & = & B_{max} (0.0556466391\enspace X - 0.2040413384\enspace Y + 1.0573110696\enspace Z)
952 \end{array}
953 \f]
954
955 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
956 in the constructor. This is the inverse transform of vigra::RGB2XYZFunctor.
957
958 <b> Traits defined:</b>
959
960 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
961 */
962 template <class T>
963 class XYZ2RGBFunctor
964 {
965 typedef typename NumericTraits<T>::RealPromote component_type;
966
967 component_type max_;
968
969 public:
970 /** the functor's argument type. (Actually, the argument type
971 is more general: <TT>V</TT> with arbitrary
972 <TT>V</TT>. But this cannot be expressed in a typedef.)
973 */
974 typedef TinyVector<T, 3> argument_type;
975
976 /** the functor's result type
977 */
978 typedef TinyVector<T, 3> result_type;
979
980 /** \deprecated use argument_type and result_type
981 */
982 typedef TinyVector<T, 3> value_type;
983
984 /** default constructor.
985 The maximum value for each RGB component defaults to 255.
986 */
987 XYZ2RGBFunctor()
988 : max_(255.0)
989 {}
990
991 /** constructor
992 \arg max - the maximum value for each RGB component
993 */
994 XYZ2RGBFunctor(component_type max)
995 : max_(max)
996 {}
997
998 /** apply the transformation
999 */
1000 template <class V>
1001 result_type operator()(V const & xyz) const
1002 {
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_));
1010 }
1011
1012 static std::string targetColorSpace()
1013 {
1014 return "RGB";
1015 }
1016 };
1017
1018 template <class T>
1019 class FunctorTraits<XYZ2RGBFunctor<T> >
1020 : public FunctorTraitsBase<XYZ2RGBFunctor<T> >
1021 {
1022 public:
1023 typedef VigraTrueType isUnaryFunctor;
1024 };
1025
1026 /** \brief Convert standardized tri-stimulus XYZ into non-linear (gamma corrected) R'G'B'.
1027
1028 <b>\#include</b> <vigra/colorconversions.hxx><br>
1029 Namespace: vigra
1030
1031 The functor realizes the transformation
1032
1033 \f[
1034 XYZ \Rightarrow RGB \Rightarrow R'G'B'
1035 \f]
1036
1037 See vigra::XYZ2RGBFunctor and vigra::RGB2RGBPrimeFunctor for a description of the two
1038 steps.
1039
1040 <b> Traits defined:</b>
1041
1042 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1043 */
1044 template <class T>
1045 class XYZ2RGBPrimeFunctor
1046 {
1047 typedef typename NumericTraits<T>::RealPromote component_type;
1048
1049 double gamma_;
1050 component_type max_;
1051
1052 public:
1053
1054 public:
1055 /** the functor's argument type. (actually, the argument type
1056 can be any vector type with the same interface.
1057 But this cannot be expressed in a typedef.)
1058 */
1059 typedef TinyVector<T, 3> argument_type;
1060
1061 /** the functor's result type
1062 */
1063 typedef TinyVector<T, 3> result_type;
1064
1065 /** \deprecated use argument_type and result_type
1066 */
1067 typedef TinyVector<T, 3> value_type;
1068
1069 /** default constructor.
1070 The maximum value for each RGB component defaults to 255.
1071 */
1072 XYZ2RGBPrimeFunctor()
1073 : gamma_(0.45), max_(component_type(255.0))
1074 {}
1075
1076 /** constructor
1077 \arg max - the maximum value for each RGB component
1078 */
1079 XYZ2RGBPrimeFunctor(component_type max)
1080 : gamma_(0.45), max_(max)
1081 {}
1082
1083 /** apply the transformation
1084 */
1085 template <class V>
1086 result_type operator()(V const & xyz) const
1087 {
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_));
1095 }
1096
1097 static std::string targetColorSpace()
1098 {
1099 return "RGB'";
1100 }
1101 };
1102
1103 template <class T>
1104 class FunctorTraits<XYZ2RGBPrimeFunctor<T> >
1105 : public FunctorTraitsBase<XYZ2RGBPrimeFunctor<T> >
1106 {
1107 public:
1108 typedef VigraTrueType isUnaryFunctor;
1109 };
1110
1111 /** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CIE L*u*v*.
1112
1113 <b>\#include</b> <vigra/colorconversions.hxx><br>
1114 Namespace: vigra
1115
1116 The functor realizes the transformation
1117
1118 \f[
1119 \begin{array}{rcl}
1120 L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \mbox{if} \quad 0.008856 < \frac{Y}{Y_n}\\
1121 & & \\
1122 L^{*} & = & 903.3\enspace \frac{Y}{Y_n} \quad \mbox{otherwise} \\
1123 & & \\
1124
1125 u' & = & \frac{4 X}{X+15 Y + 3 Z}, \quad
1126 v' = \frac{9 Y}{X+15 Y + 3 Z}\\
1127 & & \\
1128 u^{*} & = & 13 L^{*} (u' - u_n'), \quad v^{*} = 13 L^{*} (v' - v_n')
1129 \end{array}
1130 \f]
1131
1132 where \f$(X_n, Y_n, Z_n) = (0.950456, 1.0, 1.088754)\f$ is the reference white point of standard illuminant D65,
1133 and \f$u_n' = 0.197839, v_n'=0.468342\f$ are the quantities \f$u', v'\f$ calculated for this point.
1134 \f$L^{*}\f$ represents the <em>lightness</em> ("brightness") of the color, and \f$u^{*}, v^{*}\f$ code the
1135 chromaticity. (Instead of the rationals \f$\frac{216}{24389}\f$ and \f$\frac{24389}{27}\f$, the original standard gives the
1136 rounded values 0.008856 and 903.3. As <a href="http://www.brucelindbloom.com/index.html?LContinuity.html">Bruce Lindbloom</a>
1137 points out, the rounded values give raise to a discontinuity which is removed by the accurate rationals. This bug will be fixed
1138 in future versions of the CIE Luv standard.)
1139
1140 <b> Traits defined:</b>
1141
1142 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1143 */
1144 template <class T>
1145 class XYZ2LuvFunctor
1146 {
1147 public:
1148
1149 /** the result's component type
1150 */
1151 typedef typename NumericTraits<T>::RealPromote component_type;
1152
1153 /** the functor's argument type
1154 */
1155 typedef TinyVector<T, 3> argument_type;
1156
1157 /** the functor's result type
1158 */
1159 typedef TinyVector<component_type, 3> result_type;
1160
1161 /** \deprecated use argument_type and result_type
1162 */
1163 typedef TinyVector<component_type, 3> value_type;
1164
1165 XYZ2LuvFunctor()
1166 : gamma_(1.0/3.0),
1167 kappa_(24389.0/27.0),
1168 epsilon_(216.0/24389.0)
1169 {}
1170
1171 template <class V>
1172 result_type operator()(V const & xyz) const
1173 {
1174 result_type result;
1175 if(xyz[1] == NumericTraits<T>::zero())
1176 {
1177 result[0] = NumericTraits<component_type>::zero();
1178 result[1] = NumericTraits<component_type>::zero();
1179 result[2] = NumericTraits<component_type>::zero();
1180 }
1181 else
1182 {
1183 typedef detail::RequiresExplicitCast<component_type> Convert;
1184 component_type L = Convert::cast(
1185 xyz[1] < epsilon_
1186 ? kappa_ * xyz[1]
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]);
1189 component_type uprime = Convert::cast(4.0 * xyz[0] / denom);
1190 component_type vprime = Convert::cast(9.0 * xyz[1] / denom);
1191 result[0] = L;
1192 result[1] = Convert::cast(13.0*L*(uprime - 0.197839));
1193 result[2] = Convert::cast(13.0*L*(vprime - 0.468342));
1194 }
1195 return result;
1196 }
1197
1198 static std::string targetColorSpace()
1199 {
1200 return "Luv";
1201 }
1202
1203 private:
1204 double gamma_, kappa_, epsilon_;
1205 };
1206
1207 template <class T>
1208 class FunctorTraits<XYZ2LuvFunctor<T> >
1209 : public FunctorTraitsBase<XYZ2LuvFunctor<T> >
1210 {
1211 public:
1212 typedef VigraTrueType isUnaryFunctor;
1213 };
1214
1215 /** \brief Convert perceptual uniform CIE L*u*v* into standardized tri-stimulus XYZ.
1216
1217 <b>\#include</b> <vigra/colorconversions.hxx><br>
1218 Namespace: vigra
1219
1220 The functor realizes the inverse of the transformation described in vigra::XYZ2LuvFunctor
1221
1222 <b> Traits defined:</b>
1223
1224 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1225 */
1226 template <class T>
1227 class Luv2XYZFunctor
1228 {
1229 public:
1230
1231 /** the result's component type
1232 */
1233 typedef typename NumericTraits<T>::RealPromote component_type;
1234
1235 /** the functor's argument type
1236 */
1237 typedef TinyVector<T, 3> argument_type;
1238
1239 /** the functor's result type
1240 */
1241 typedef TinyVector<component_type, 3> result_type;
1242
1243 /** \deprecated use argument_type and result_type
1244 */
1245 typedef TinyVector<component_type, 3> value_type;
1246
1247 Luv2XYZFunctor()
1248 : gamma_(3.0),
1249 ikappa_(27.0/24389.0)
1250 {}
1251
1252 /** apply the transformation
1253 */
1254 template <class V>
1255 result_type operator()(V const & luv) const
1256 {
1257 result_type result;
1258 if(luv[0] == NumericTraits<T>::zero())
1259 {
1260 result[0] = NumericTraits<component_type>::zero();
1261 result[1] = NumericTraits<component_type>::zero();
1262 result[2] = NumericTraits<component_type>::zero();
1263 }
1264 else
1265 {
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);
1269
1270 result[1] = Convert::cast(
1271 luv[0] < 8.0
1272 ? luv[0] * ikappa_
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);
1276 }
1277 return result;
1278 }
1279
1280 static std::string targetColorSpace()
1281 {
1282 return "XYZ";
1283 }
1284
1285 private:
1286 double gamma_, ikappa_;
1287 };
1288
1289 template <class T>
1290 class FunctorTraits<Luv2XYZFunctor<T> >
1291 : public FunctorTraitsBase<Luv2XYZFunctor<T> >
1292 {
1293 public:
1294 typedef VigraTrueType isUnaryFunctor;
1295 };
1296
1297 /** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CIE L*a*b*.
1298
1299 <b>\#include</b> <vigra/colorconversions.hxx><br>
1300 Namespace: vigra
1301
1302 The functor realizes the transformation
1303
1304 \f[
1305 \begin{array}{rcl}
1306 L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \mbox{if} \quad \frac{216}{24389} < \frac{Y}{Y_n}\\
1307 & & \\
1308 L^{*} & = & \frac{24389}{27} \enspace \frac{Y}{Y_n} \quad \mbox{otherwise} \\
1309 & & \\
1310 a^{*} & = & 500 \left[ \left( \frac{X}{X_n} \right)^\frac{1}{3} - \left( \frac{Y}{Y_n} \right)^\frac{1}{3} \right] \\
1311 & & \\
1312 b^{*} & = & 200 \left[ \left( \frac{Y}{Y_n} \right)^\frac{1}{3} - \left( \frac{Z}{Z_n} \right)^\frac{1}{3} \right] \\
1313 \end{array}
1314 \f]
1315
1316 where \f$(X_n, Y_n, Z_n) = (0.950456, 1.0, 1.088754)\f$ is the reference white point of standard illuminant D65.
1317 \f$L^{*}\f$ represents the <em>lightness</em> ("brightness") of the color, and \f$a^{*}, b^{*}\f$ code the
1318 chromaticity. (Instead of the rationals \f$\frac{216}{24389}\f$ and \f$\frac{24389}{27}\f$, the original standard gives the
1319 rounded values 0.008856 and 903.3. As <a href="http://www.brucelindbloom.com/index.html?LContinuity.html">Bruce Lindbloom</a>
1320 points out, the rounded values give raise to a discontinuity which is removed by the accurate rationals. This bug will be fixed
1321 in future versions of the CIE Lab standard.)
1322
1323 <b> Traits defined:</b>
1324
1325 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1326 */
1327 template <class T>
1328 class XYZ2LabFunctor
1329 {
1330 public:
1331
1332 /** the result's component type
1333 */
1334 typedef typename NumericTraits<T>::RealPromote component_type;
1335
1336 /** the functor's argument type
1337 */
1338 typedef TinyVector<T, 3> argument_type;
1339
1340 /** the functor's result type
1341 */
1342 typedef TinyVector<component_type, 3> result_type;
1343
1344 /** \deprecated use argument_type and result_type
1345 */
1346 typedef TinyVector<component_type, 3> value_type;
1347
1348 XYZ2LabFunctor()
1349 : gamma_(1.0/3.0),
1350 kappa_(24389.0/27.0),
1351 epsilon_(216.0/24389.0)
1352 {}
1353
1354 /** apply the transformation
1355 */
1356 template <class V>
1357 result_type operator()(V const & xyz) const
1358 {
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_));
1363 component_type L = Convert::cast(
1364 xyz[1] < epsilon_
1365 ? kappa_ * xyz[1]
1366 : 116.0 * ygamma - 16.0);
1367 result_type result;
1368 result[0] = L;
1369 result[1] = Convert::cast(500.0*(xgamma - ygamma));
1370 result[2] = Convert::cast(200.0*(ygamma - zgamma));
1371 return result;
1372 }
1373
1374 static std::string targetColorSpace()
1375 {
1376 return "Lab";
1377 }
1378
1379 private:
1380 double gamma_, kappa_, epsilon_;
1381 };
1382
1383 template <class T>
1384 class FunctorTraits<XYZ2LabFunctor<T> >
1385 : public FunctorTraitsBase<XYZ2LabFunctor<T> >
1386 {
1387 public:
1388 typedef VigraTrueType isUnaryFunctor;
1389 };
1390
1391 /** \brief Convert perceptual uniform CIE L*a*b* into standardized tri-stimulus XYZ.
1392
1393 <b>\#include</b> <vigra/colorconversions.hxx><br>
1394 Namespace: vigra
1395
1396 The functor realizes the inverse of the transformation described in vigra::XYZ2LabFunctor
1397
1398 <b> Traits defined:</b>
1399
1400 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1401 */
1402 template <class T>
1403 class Lab2XYZFunctor
1404 {
1405 public:
1406
1407 /** the result's component type
1408 */
1409 typedef typename NumericTraits<T>::RealPromote component_type;
1410
1411 /** the functor's argument type
1412 */
1413 typedef TinyVector<T, 3> argument_type;
1414
1415 /** the functor's result type
1416 */
1417 typedef TinyVector<component_type, 3> result_type;
1418
1419 /** \deprecated use argument_type and result_type
1420 */
1421 typedef TinyVector<component_type, 3> value_type;
1422
1423 /** the functor's value type
1424 */
1425 Lab2XYZFunctor()
1426 : gamma_(3.0),
1427 ikappa_(27.0/24389.0)
1428 {}
1429
1430 /** apply the transformation
1431 */
1432 template <class V>
1433 result_type operator()(V const & lab) const
1434 {
1435 typedef detail::RequiresExplicitCast<component_type> Convert;
1436 component_type Y = Convert::cast(
1437 lab[0] < 8.0
1438 ? lab[0] * ikappa_
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);
1443 result_type result;
1444 result[0] = X;
1445 result[1] = Y;
1446 result[2] = Z;
1447 return result;
1448 }
1449
1450 static std::string targetColorSpace()
1451 {
1452 return "XYZ";
1453 }
1454
1455 private:
1456 double gamma_, ikappa_;
1457 };
1458
1459 template <class T>
1460 class FunctorTraits<Lab2XYZFunctor<T> >
1461 : public FunctorTraitsBase<Lab2XYZFunctor<T> >
1462 {
1463 public:
1464 typedef VigraTrueType isUnaryFunctor;
1465 };
1466
1467 /** \brief Convert linear (raw) RGB into perceptual uniform CIE L*u*v*.
1468
1469 <b>\#include</b> <vigra/colorconversions.hxx><br>
1470 Namespace: vigra
1471
1472 The functor realizes the transformation
1473
1474 \f[
1475 RGB \Rightarrow XYZ \Rightarrow L^*u^*v^*
1476 \f]
1477
1478 See vigra::RGB2XYZFunctor and vigra::XYZ2LuvFunctor for a description of the two
1479 steps. The resulting color components will have the following bounds:
1480
1481 \f[
1482 \begin{array}{rcl}
1483 0 \leq & L^* & \leq 100 \\
1484 -83.077 \leq & u^* & \leq 175.015 \\
1485 -134.101 \leq & v^* & \leq 107.393
1486 \end{array}
1487 \f]
1488
1489 <b> Traits defined:</b>
1490
1491 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1492 */
1493 template <class T>
1494 class RGB2LuvFunctor
1495 {
1496 /*
1497 L in [0, 100]
1498 u in [-83.077, 175.015]
1499 v in [-134.101, 107.393]
1500 maximum saturation: 179.04
1501 red = [53.2406, 175.015, 37.7522]
1502 */
1503 public:
1504
1505 /** the result's component type
1506 */
1507 typedef typename NumericTraits<T>::RealPromote component_type;
1508
1509 /** the functor's argument type
1510 */
1511 typedef TinyVector<T, 3> argument_type;
1512
1513 /** the functor's result type
1514 */
1515 typedef typename XYZ2LuvFunctor<component_type>::result_type result_type;
1516
1517 /** \deprecated use argument_type and result_type
1518 */
1519 typedef typename XYZ2LuvFunctor<component_type>::result_type value_type;
1520
1521 /** default constructor.
1522 The maximum value for each RGB component defaults to 255.
1523 */
1524 RGB2LuvFunctor()
1525 : rgb2xyz(255.0)
1526 {}
1527
1528 /** constructor
1529 \arg max - the maximum value for each RGB component
1530 */
1531 RGB2LuvFunctor(component_type max)
1532 : rgb2xyz(max)
1533 {}
1534
1535 /** apply the transformation
1536 */
1537 template <class V>
1538 result_type operator()(V const & rgb) const
1539 {
1540 return xyz2luv(rgb2xyz(rgb));
1541 }
1542
1543 static std::string targetColorSpace()
1544 {
1545 return "Luv";
1546 }
1547
1548 private:
1549 RGB2XYZFunctor<T> rgb2xyz;
1550 XYZ2LuvFunctor<component_type> xyz2luv;
1551 };
1552
1553 template <class T>
1554 class FunctorTraits<RGB2LuvFunctor<T> >
1555 : public FunctorTraitsBase<RGB2LuvFunctor<T> >
1556 {
1557 public:
1558 typedef VigraTrueType isUnaryFunctor;
1559 };
1560
1561 /** \brief Convert linear (raw) RGB into perceptual uniform CIE L*a*b*.
1562
1563 <b>\#include</b> <vigra/colorconversions.hxx><br>
1564 Namespace: vigra
1565
1566 The functor realizes the transformation
1567
1568 \f[
1569 RGB \Rightarrow XYZ \Rightarrow L^*a^*b^*
1570 \f]
1571
1572 See vigra::RGB2XYZFunctor and vigra::XYZ2LabFunctor for a description of the two
1573 steps. The resulting color components will have the following bounds:
1574
1575 \f[
1576 \begin{array}{rcl}
1577 0 \leq & L^* & \leq 100 \\
1578 -86.1813 \leq & u^* & \leq 98.2352 \\
1579 -107.862 \leq & v^* & \leq 94.4758
1580 \end{array}
1581 \f]
1582
1583 <b> Traits defined:</b>
1584
1585 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1586 */
1587 template <class T>
1588 class RGB2LabFunctor
1589 {
1590 /*
1591 L in [0, 100]
1592 a in [-86.1813, 98.2352]
1593 b in [-107.862, 94.4758]
1594 maximum saturation: 133.809
1595 red = [53.2406, 80.0942, 67.2015]
1596 */
1597 public:
1598
1599 /** the result's component type
1600 */
1601 typedef typename NumericTraits<T>::RealPromote component_type;
1602
1603 /** the functor's argument type
1604 */
1605 typedef TinyVector<T, 3> argument_type;
1606
1607 /** the functor's result type
1608 */
1609 typedef typename XYZ2LabFunctor<component_type>::result_type result_type;
1610
1611 /** \deprecated use argument_type and result_type
1612 */
1613 typedef typename XYZ2LabFunctor<component_type>::result_type value_type;
1614
1615 /** default constructor.
1616 The maximum value for each RGB component defaults to 255.
1617 */
1618 RGB2LabFunctor()
1619 : rgb2xyz(255.0)
1620 {}
1621
1622 /** constructor
1623 \arg max - the maximum value for each RGB component
1624 */
1625 RGB2LabFunctor(component_type max)
1626 : rgb2xyz(max)
1627 {}
1628
1629 /** apply the transformation
1630 */
1631 template <class V>
1632 result_type operator()(V const & rgb) const
1633 {
1634 return xyz2lab(rgb2xyz(rgb));
1635 }
1636
1637 static std::string targetColorSpace()
1638 {
1639 return "Lab";
1640 }
1641
1642 private:
1643 RGB2XYZFunctor<T> rgb2xyz;
1644 XYZ2LabFunctor<component_type> xyz2lab;
1645 };
1646
1647 template <class T>
1648 class FunctorTraits<RGB2LabFunctor<T> >
1649 : public FunctorTraitsBase<RGB2LabFunctor<T> >
1650 {
1651 public:
1652 typedef VigraTrueType isUnaryFunctor;
1653 };
1654
1655 /** \brief Convert perceptual uniform CIE L*u*v* into linear (raw) RGB.
1656
1657 <b>\#include</b> <vigra/colorconversions.hxx><br>
1658 Namespace: vigra
1659
1660 The functor realizes the inverse of the transformation described in vigra::RGB2LuvFunctor
1661
1662 <b> Traits defined:</b>
1663
1664 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1665 */
1666 template <class T>
1667 class Luv2RGBFunctor
1668 {
1669 typedef typename NumericTraits<T>::RealPromote component_type;
1670
1671 XYZ2RGBFunctor<T> xyz2rgb;
1672 Luv2XYZFunctor<component_type> luv2xyz;
1673
1674 public:
1675 /** the functor's argument type. (Actually, the argument type
1676 can be any vector type with the same interface.
1677 But this cannot be expressed in a typedef.)
1678 */
1679 typedef TinyVector<T, 3> argument_type;
1680
1681 /** the functor's result type
1682 */
1683 typedef typename XYZ2RGBFunctor<T>::result_type result_type;
1684
1685 /** \deprecated use argument_type and result_type
1686 */
1687 typedef typename XYZ2RGBFunctor<T>::result_type value_type;
1688
1689 Luv2RGBFunctor()
1690 : xyz2rgb(255.0)
1691 {}
1692
1693 Luv2RGBFunctor(component_type max)
1694 : xyz2rgb(max)
1695 {}
1696
1697 /** apply the transformation
1698 */
1699 template <class V>
1700 result_type operator()(V const & luv) const
1701 {
1702 return xyz2rgb(luv2xyz(luv));
1703 }
1704
1705 static std::string targetColorSpace()
1706 {
1707 return "RGB";
1708 }
1709 };
1710
1711 template <class T>
1712 class FunctorTraits<Luv2RGBFunctor<T> >
1713 : public FunctorTraitsBase<Luv2RGBFunctor<T> >
1714 {
1715 public:
1716 typedef VigraTrueType isUnaryFunctor;
1717 };
1718
1719 /** \brief Convert perceptual uniform CIE L*a*b* into linear (raw) RGB.
1720
1721 <b>\#include</b> <vigra/colorconversions.hxx><br>
1722 Namespace: vigra
1723
1724 The functor realizes the inverse of the transformation described in vigra::RGB2LabFunctor
1725
1726 <b> Traits defined:</b>
1727
1728 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1729 */
1730 template <class T>
1731 class Lab2RGBFunctor
1732 {
1733 typedef typename NumericTraits<T>::RealPromote component_type;
1734
1735 XYZ2RGBFunctor<T> xyz2rgb;
1736 Lab2XYZFunctor<component_type> lab2xyz;
1737
1738 public:
1739
1740 /** the functor's argument type. (Actually, the argument type
1741 can be any vector type with the same interface.
1742 But this cannot be expressed in a typedef.)
1743 */
1744 typedef TinyVector<T, 3> argument_type;
1745
1746 /** the functor's result type
1747 */
1748 typedef typename XYZ2RGBFunctor<T>::result_type result_type;
1749
1750 /** \deprecated use argument_type and result_type
1751 */
1752 typedef typename XYZ2RGBFunctor<T>::result_type value_type;
1753
1754 /** default constructor.
1755 The maximum value for each RGB component defaults to 255.
1756 */
1757 Lab2RGBFunctor()
1758 : xyz2rgb(255.0)
1759 {}
1760
1761 /** constructor
1762 \arg max - the maximum value for each RGB component
1763 */
1764 Lab2RGBFunctor(component_type max)
1765 : xyz2rgb(max)
1766 {}
1767
1768 /** apply the transformation
1769 */
1770 template <class V>
1771 result_type operator()(V const & lab) const
1772 {
1773 return xyz2rgb(lab2xyz(lab));
1774 }
1775
1776 static std::string targetColorSpace()
1777 {
1778 return "RGB";
1779 }
1780 };
1781
1782 template <class T>
1783 class FunctorTraits<Lab2RGBFunctor<T> >
1784 : public FunctorTraitsBase<Lab2RGBFunctor<T> >
1785 {
1786 public:
1787 typedef VigraTrueType isUnaryFunctor;
1788 };
1789
1790 /** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual uniform CIE L*u*v*.
1791
1792 <b>\#include</b> <vigra/colorconversions.hxx><br>
1793 Namespace: vigra
1794
1795 The functor realizes the transformation
1796
1797 \f[
1798 R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*u^*v^*
1799 \f]
1800
1801 See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2LuvFunctor for a description of the three
1802 steps. The resulting color components will have the following bounds:
1803
1804 \f[
1805 \begin{array}{rcl}
1806 0 \leq & L^* & \leq 100 \\
1807 -83.077 \leq & u^* & \leq 175.015 \\
1808 -134.101 \leq & v^* & \leq 107.393
1809 \end{array}
1810 \f]
1811
1812 <b> Traits defined:</b>
1813
1814 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1815 */
1816 template <class T>
1817 class RGBPrime2LuvFunctor
1818 {
1819 public:
1820
1821 /** the result's component type
1822 */
1823 typedef typename NumericTraits<T>::RealPromote component_type;
1824
1825 /** the functor's argument type
1826 */
1827 typedef TinyVector<T, 3> argument_type;
1828
1829 /** the functor's result type
1830 */
1831 typedef typename XYZ2LuvFunctor<component_type>::result_type result_type;
1832
1833 /** \deprecated use argument_type and result_type
1834 */
1835 typedef typename XYZ2LuvFunctor<component_type>::result_type value_type;
1836
1837 /** default constructor.
1838 The maximum value for each RGB component defaults to 255.
1839 */
1840 RGBPrime2LuvFunctor()
1841 : rgb2xyz(255.0)
1842 {}
1843
1844 /** constructor
1845 \arg max - the maximum value for each RGB component
1846 */
1847 RGBPrime2LuvFunctor(component_type max)
1848 : rgb2xyz(max)
1849 {}
1850
1851 /** apply the transformation
1852 */
1853 template <class V>
1854 result_type operator()(V const & rgb) const
1855 {
1856 return xyz2luv(rgb2xyz(rgb));
1857 }
1858
1859 static std::string targetColorSpace()
1860 {
1861 return "Luv";
1862 }
1863
1864 private:
1865 RGBPrime2XYZFunctor<T> rgb2xyz;
1866 XYZ2LuvFunctor<component_type> xyz2luv;
1867 };
1868
1869 template <class T>
1870 class FunctorTraits<RGBPrime2LuvFunctor<T> >
1871 : public FunctorTraitsBase<RGBPrime2LuvFunctor<T> >
1872 {
1873 public:
1874 typedef VigraTrueType isUnaryFunctor;
1875 };
1876
1877 /** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual uniform CIE L*a*b*.
1878
1879 <b>\#include</b> <vigra/colorconversions.hxx><br>
1880 Namespace: vigra
1881
1882 The functor realizes the transformation
1883
1884 \f[
1885 R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*a^*b^*
1886 \f]
1887
1888 See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2LabFunctor for a description of the three
1889 steps. The resulting color components will have the following bounds:
1890
1891 \f[
1892 \begin{array}{rcl}
1893 0 \leq & L^* & \leq 100 \\
1894 -86.1813 \leq & u^* & \leq 98.2352 \\
1895 -107.862 \leq & v^* & \leq 94.4758
1896 \end{array}
1897 \f]
1898
1899 <b> Traits defined:</b>
1900
1901 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1902 */
1903 template <class T>
1904 class RGBPrime2LabFunctor
1905 {
1906 public:
1907
1908 /** the result's component type
1909 */
1910 typedef typename NumericTraits<T>::RealPromote component_type;
1911
1912 /** the functor's argument type
1913 */
1914 typedef TinyVector<T, 3> argument_type;
1915
1916 /** the functor's result type
1917 */
1918 typedef typename XYZ2LabFunctor<component_type>::result_type result_type;
1919
1920 /** \deprecated use argument_type and result_type
1921 */
1922 typedef typename XYZ2LabFunctor<component_type>::result_type value_type;
1923
1924 /** default constructor.
1925 The maximum value for each RGB component defaults to 255.
1926 */
1927 RGBPrime2LabFunctor()
1928 : rgb2xyz(255.0)
1929 {}
1930
1931 /** constructor
1932 \arg max - the maximum value for each RGB component
1933 */
1934 RGBPrime2LabFunctor(component_type max)
1935 : rgb2xyz(max)
1936 {}
1937
1938 /** apply the transformation
1939 */
1940 template <class V>
1941 result_type operator()(V const & rgb) const
1942 {
1943 return xyz2lab(rgb2xyz(rgb));
1944 }
1945
1946 static std::string targetColorSpace()
1947 {
1948 return "Lab";
1949 }
1950
1951 private:
1952 RGBPrime2XYZFunctor<T> rgb2xyz;
1953 XYZ2LabFunctor<component_type> xyz2lab;
1954 };
1955
1956 template <class T>
1957 class FunctorTraits<RGBPrime2LabFunctor<T> >
1958 : public FunctorTraitsBase<RGBPrime2LabFunctor<T> >
1959 {
1960 public:
1961 typedef VigraTrueType isUnaryFunctor;
1962 };
1963
1964 /** \brief Convert perceptual uniform CIE L*u*v* into non-linear (gamma corrected) R'G'B'.
1965
1966 <b>\#include</b> <vigra/colorconversions.hxx><br>
1967 Namespace: vigra
1968
1969 The functor realizes the inverse of the transformation described in vigra::RGBPrime2LuvFunctor
1970
1971 <b> Traits defined:</b>
1972
1973 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
1974 */
1975 template <class T>
1976 class Luv2RGBPrimeFunctor
1977 {
1978 typedef typename NumericTraits<T>::RealPromote component_type;
1979
1980 XYZ2RGBPrimeFunctor<T> xyz2rgb;
1981 Luv2XYZFunctor<component_type> luv2xyz;
1982
1983 public:
1984
1985 /** the functor's argument type. (Actually, the argument type
1986 can be any vector type with the same interface.
1987 But this cannot be expressed in a typedef.)
1988 */
1989 typedef TinyVector<T, 3> argument_type;
1990
1991 /** the functor's result type
1992 */
1993 typedef typename XYZ2RGBFunctor<T>::result_type result_type;
1994
1995 /** \deprecated use argument_type and result_type
1996 */
1997 typedef typename XYZ2RGBFunctor<T>::result_type value_type;
1998
1999 /** default constructor.
2000 The maximum value for each RGB component defaults to 255.
2001 */
2002 Luv2RGBPrimeFunctor()
2003 : xyz2rgb(255.0)
2004 {}
2005
2006 /** constructor
2007 \arg max - the maximum value for each RGB component
2008 */
2009 Luv2RGBPrimeFunctor(component_type max)
2010 : xyz2rgb(max)
2011 {}
2012
2013 /** apply the transformation
2014 */
2015 template <class V>
2016 result_type operator()(V const & luv) const
2017 {
2018 return xyz2rgb(luv2xyz(luv));
2019 }
2020
2021 static std::string targetColorSpace()
2022 {
2023 return "RGB'";
2024 }
2025 };
2026
2027 template <class T>
2028 class FunctorTraits<Luv2RGBPrimeFunctor<T> >
2029 : public FunctorTraitsBase<Luv2RGBPrimeFunctor<T> >
2030 {
2031 public:
2032 typedef VigraTrueType isUnaryFunctor;
2033 };
2034
2035 /** \brief Convert perceptual uniform CIE L*a*b* into non-linear (gamma corrected) R'G'B'.
2036
2037 <b>\#include</b> <vigra/colorconversions.hxx><br>
2038 Namespace: vigra
2039
2040 The functor realizes the inverse of the transformation described in vigra::RGBPrime2LabFunctor
2041
2042 <b> Traits defined:</b>
2043
2044 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2045 */
2046 template <class T>
2047 class Lab2RGBPrimeFunctor
2048 {
2049 typedef typename NumericTraits<T>::RealPromote component_type;
2050
2051 XYZ2RGBPrimeFunctor<T> xyz2rgb;
2052 Lab2XYZFunctor<component_type> lab2xyz;
2053
2054 public:
2055
2056 /** the functor's argument type. (Actually, the argument type
2057 can be any vector type with the same interface.
2058 But this cannot be expressed in a typedef.)
2059 */
2060 typedef TinyVector<T, 3> argument_type;
2061
2062 /** the functor's result type
2063 */
2064 typedef typename XYZ2RGBFunctor<T>::result_type result_type;
2065
2066 /** \deprecated use argument_type and result_type
2067 */
2068 typedef typename XYZ2RGBFunctor<T>::result_type value_type;
2069
2070 /** default constructor.
2071 The maximum value for each RGB component defaults to 255.
2072 */
2073 Lab2RGBPrimeFunctor()
2074 : xyz2rgb(255.0)
2075 {}
2076
2077 /** constructor
2078 \arg max - the maximum value for each RGB component
2079 */
2080 Lab2RGBPrimeFunctor(component_type max)
2081 : xyz2rgb(max)
2082 {}
2083
2084 /** apply the transformation
2085 */
2086 template <class V>
2087 result_type operator()(V const & lab) const
2088 {
2089 return xyz2rgb(lab2xyz(lab));
2090 }
2091
2092 static std::string targetColorSpace()
2093 {
2094 return "RGB'";
2095 }
2096 };
2097
2098 template <class T>
2099 class FunctorTraits<Lab2RGBPrimeFunctor<T> >
2100 : public FunctorTraitsBase<Lab2RGBPrimeFunctor<T> >
2101 {
2102 public:
2103 typedef VigraTrueType isUnaryFunctor;
2104 };
2105
2106 /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'PbPr color difference components.
2107
2108 <b>\#include</b> <vigra/colorconversions.hxx><br>
2109 Namespace: vigra
2110
2111 According to ITU-R Recommendation BT.601, the functor realizes the transformation
2112
2113 \f[
2114 \begin{array}{rcl}
2115 Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\
2116 Pb & = & -0.1687358916\enspace R / R_{max} + 0.3312641084\enspace G / G_{max} + 0.5\enspace B / B_{max} \\
2117 Pr & = & 0.5\enspace R / R_{max} + 0.4186875892\enspace G / G_{max} + 0.0813124108\enspace B / B_{max}
2118 \end{array}
2119 \f]
2120
2121 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
2122 in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color, and
2123 Pb and Pr are the blue (B'-Y') and red (R'-Y') color difference components.
2124 The transformation is scaled so that the following bounds apply:
2125
2126 \f[
2127 \begin{array}{rcl}
2128 0 \leq & Y' & \leq 1 \\
2129 -0.5 \leq & Pb & \leq 0.5 \\
2130 -0.5 \leq & Pr & \leq 0.5
2131 \end{array}
2132 \f]
2133
2134 <b> Traits defined:</b>
2135
2136 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2137 */
2138 template <class T>
2139 class RGBPrime2YPrimePbPrFunctor
2140 {
2141 /*
2142 Y in [0, 1]
2143 Pb in [-0.5, 0.5]
2144 Pr in [-0.5, 0.5]
2145 maximum saturation: 0.533887
2146 red = [0.299, -0.168736, 0.5]
2147 */
2148 public:
2149
2150 /** the result's component type
2151 */
2152 typedef typename NumericTraits<T>::RealPromote component_type;
2153
2154 /** the functor's argument type
2155 */
2156 typedef TinyVector<T, 3> argument_type;
2157
2158 /** the functor's result type
2159 */
2160 typedef TinyVector<component_type, 3> result_type;
2161
2162 /** \deprecated use argument_type and result_type
2163 */
2164 typedef TinyVector<component_type, 3> value_type;
2165
2166 /** default constructor.
2167 The maximum value for each RGB component defaults to 255.
2168 */
2169 RGBPrime2YPrimePbPrFunctor()
2170 : max_(255.0)
2171 {}
2172
2173 /** constructor
2174 \arg max - the maximum value for each RGB component
2175 */
2176 RGBPrime2YPrimePbPrFunctor(component_type max)
2177 : max_(max)
2178 {}
2179
2180 /** apply the transformation
2181 */
2182 template <class V>
2183 result_type operator()(V const & rgb) const
2184 {
2185 typedef detail::RequiresExplicitCast<component_type> Convert;
2186 component_type red = rgb[0] / max_;
2187 component_type green = rgb[1] / max_;
2188 component_type blue = rgb[2] / max_;
2189
2190 result_type result;
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);
2194 return result;
2195 }
2196
2197 static std::string targetColorSpace()
2198 {
2199 return "Y'PbPr";
2200 }
2201
2202 private:
2203 component_type max_;
2204 };
2205
2206 template <class T>
2207 class FunctorTraits<RGBPrime2YPrimePbPrFunctor<T> >
2208 : public FunctorTraitsBase<RGBPrime2YPrimePbPrFunctor<T> >
2209 {
2210 public:
2211 typedef VigraTrueType isUnaryFunctor;
2212 };
2213
2214 /** \brief Convert Y'PbPr color difference components into non-linear (gamma corrected) R'G'B'.
2215
2216 <b>\#include</b> <vigra/colorconversions.hxx><br>
2217 Namespace: vigra
2218
2219 The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimePbPrFunctor
2220
2221 <b> Traits defined:</b>
2222
2223 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2224 */
2225 template <class T>
2226 class YPrimePbPr2RGBPrimeFunctor
2227 {
2228 typedef typename NumericTraits<T>::RealPromote component_type;
2229
2230 component_type max_;
2231
2232 public:
2233
2234 /** the functor's argument type. (Actually, the argument type
2235 can be any vector type with the same interface.
2236 But this cannot be expressed in a typedef.)
2237 */
2238 typedef TinyVector<T, 3> argument_type;
2239
2240 /** the functor's result type
2241 */
2242 typedef TinyVector<T, 3> result_type;
2243
2244 /** \deprecated use argument_type and result_type
2245 */
2246 typedef TinyVector<T, 3> value_type;
2247
2248 /** default constructor.
2249 The maximum value for each RGB component defaults to 255.
2250 */
2251 YPrimePbPr2RGBPrimeFunctor()
2252 : max_(255.0)
2253 {}
2254
2255 /** constructor
2256 \arg max - the maximum value for each RGB component
2257 */
2258 YPrimePbPr2RGBPrimeFunctor(component_type max)
2259 : max_(max)
2260 {}
2261
2262 /** apply the transformation
2263 */
2264 template <class V>
2265 result_type operator()(V const & ypbpr) const
2266 {
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_));
2274 }
2275
2276 static std::string targetColorSpace()
2277 {
2278 return "RGB'";
2279 }
2280 };
2281
2282 template <class T>
2283 class FunctorTraits<YPrimePbPr2RGBPrimeFunctor<T> >
2284 : public FunctorTraitsBase<YPrimePbPr2RGBPrimeFunctor<T> >
2285 {
2286 public:
2287 typedef VigraTrueType isUnaryFunctor;
2288 };
2289
2290 /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'IQ components.
2291
2292 <b>\#include</b> <vigra/colorconversions.hxx><br>
2293 Namespace: vigra
2294
2295 According to the PAL analog video standard, the functor realizes the transformation
2296
2297 \f[
2298 \begin{array}{rcl}
2299 Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\
2300 I & = & 0.596\enspace R / R_{max} - 0.274\enspace G / G_{max} - 0.322\enspace B / B_{max} \\
2301 Q & = & 0.212\enspace R / R_{max} - 0.523\enspace G / G_{max} + 0.311\enspace B / B_{max}
2302 \end{array}
2303 \f]
2304
2305 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
2306 in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color.
2307 The transformation is scaled so that the following bounds apply:
2308
2309 \f[
2310 \begin{array}{rcl}
2311 0 \leq & Y' & \leq 1 \\
2312 -0.596 \leq & I & \leq 0.596 \\
2313 -0.523 \leq & Q & \leq 0.523
2314 \end{array}
2315 \f]
2316
2317 <b> Traits defined:</b>
2318
2319 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2320 */
2321 template <class T>
2322 class RGBPrime2YPrimeIQFunctor
2323 {
2324 /*
2325 Y in [0, 1]
2326 I in [-0.596, 0.596]
2327 Q in [-0.523, 0.523]
2328 maximum saturation: 0.632582
2329 red = [0.299, 0.596, 0.212]
2330 */
2331 public:
2332
2333 /** the result's component type
2334 */
2335 typedef typename NumericTraits<T>::RealPromote component_type;
2336
2337 /** the functor's argument type
2338 */
2339 typedef TinyVector<T, 3> argument_type;
2340
2341 /** the functor's result type
2342 */
2343 typedef TinyVector<component_type, 3> result_type;
2344
2345 /** \deprecated use argument_type and result_type
2346 */
2347 typedef TinyVector<component_type, 3> value_type;
2348
2349 /** default constructor.
2350 The maximum value for each RGB component defaults to 255.
2351 */
2352 RGBPrime2YPrimeIQFunctor()
2353 : max_(255.0)
2354 {}
2355
2356 /** constructor
2357 \arg max - the maximum value for each RGB component
2358 */
2359 RGBPrime2YPrimeIQFunctor(component_type max)
2360 : max_(max)
2361 {}
2362
2363 /** apply the transformation
2364 */
2365 template <class V>
2366 result_type operator()(V const & rgb) const
2367 {
2368 typedef detail::RequiresExplicitCast<component_type> Convert;
2369 component_type red = rgb[0] / max_;
2370 component_type green = rgb[1] / max_;
2371 component_type blue = rgb[2] / max_;
2372
2373 result_type result;
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);
2377 return result;
2378 }
2379
2380 static std::string targetColorSpace()
2381 {
2382 return "Y'IQ";
2383 }
2384
2385 private:
2386 component_type max_;
2387 };
2388
2389 template <class T>
2390 class FunctorTraits<RGBPrime2YPrimeIQFunctor<T> >
2391 : public FunctorTraitsBase<RGBPrime2YPrimeIQFunctor<T> >
2392 {
2393 public:
2394 typedef VigraTrueType isUnaryFunctor;
2395 };
2396
2397 /** \brief Convert Y'IQ color components into non-linear (gamma corrected) R'G'B'.
2398
2399 <b>\#include</b> <vigra/colorconversions.hxx><br>
2400 Namespace: vigra
2401
2402 The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeIQFunctor
2403
2404 <b> Traits defined:</b>
2405
2406 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2407 */
2408 template <class T>
2409 class YPrimeIQ2RGBPrimeFunctor
2410 {
2411 typedef typename NumericTraits<T>::RealPromote component_type;
2412
2413 component_type max_;
2414
2415 public:
2416
2417 /** the functor's argument type. (Actually, the argument type
2418 can be any vector type with the same interface.
2419 But this cannot be expressed in a typedef.)
2420 */
2421 typedef TinyVector<T, 3> argument_type;
2422
2423 /** the functor's result type
2424 */
2425 typedef TinyVector<T, 3> result_type;
2426
2427 /** \deprecated use argument_type and result_type
2428 */
2429 typedef TinyVector<T, 3> value_type;
2430
2431 /** default constructor.
2432 The maximum value for each RGB component defaults to 255.
2433 */
2434 YPrimeIQ2RGBPrimeFunctor()
2435 : max_(255.0)
2436 {}
2437
2438 /** constructor
2439 \arg max - the maximum value for each RGB component
2440 */
2441 YPrimeIQ2RGBPrimeFunctor(component_type max)
2442 : max_(max)
2443 {}
2444
2445 /** apply the transformation
2446 */
2447 template <class V>
2448 result_type operator()(V const & yiq) const
2449 {
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_));
2457 }
2458
2459 static std::string targetColorSpace()
2460 {
2461 return "RGB'";
2462 }
2463 };
2464
2465 template <class T>
2466 class FunctorTraits<YPrimeIQ2RGBPrimeFunctor<T> >
2467 : public FunctorTraitsBase<YPrimeIQ2RGBPrimeFunctor<T> >
2468 {
2469 public:
2470 typedef VigraTrueType isUnaryFunctor;
2471 };
2472
2473 /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'UV components.
2474
2475 <b>\#include</b> <vigra/colorconversions.hxx><br>
2476 Namespace: vigra
2477
2478 According to the NTSC analog video standard, the functor realizes the transformation
2479
2480 \f[
2481 \begin{array}{rcl}
2482 Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0.114\enspace B / B_{max}\\
2483 U & = & -0.147\enspace R / R_{max} - 0.289\enspace G / G_{max} + 0.436\enspace B / B_{max} \\
2484 V & = & 0.615\enspace R / R_{max} - 0.515\enspace G / G_{max} - 0.100\enspace B / B_{max}
2485 \end{array}
2486 \f]
2487
2488 By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
2489 in the constructor. Y' represents the <em>luminance</em> ("brightness") of the color.
2490 The transformation is scaled so that the following bounds apply:
2491
2492 \f[
2493 \begin{array}{rcl}
2494 0 \leq & Y' & \leq 1 \\
2495 -0.436 \leq & U & \leq 0.436 \\
2496 -0.615 \leq & V & \leq 0.615
2497 \end{array}
2498 \f]
2499
2500 <b> Traits defined:</b>
2501
2502 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2503 */
2504 template <class T>
2505 class RGBPrime2YPrimeUVFunctor
2506 {
2507 /*
2508 Y in [0, 1]
2509 U in [-0.436, 0.436]
2510 V in [-0.615, 0.615]
2511 maximum saturation: 0.632324
2512 red = [0.299, -0.147, 0.615]
2513 */
2514 public:
2515
2516 /** the result's component type
2517 */
2518 typedef typename NumericTraits<T>::RealPromote component_type;
2519
2520 /** the functor's argument type
2521 */
2522 typedef TinyVector<T, 3> argument_type;
2523
2524 /** the functor's result type
2525 */
2526 typedef TinyVector<component_type, 3> result_type;
2527
2528 /** \deprecated use argument_type and result_type
2529 */
2530 typedef TinyVector<component_type, 3> value_type;
2531
2532 /** default constructor.
2533 The maximum value for each RGB component defaults to 255.
2534 */
2535 RGBPrime2YPrimeUVFunctor()
2536 : max_(255.0)
2537 {}
2538
2539 /** constructor
2540 \arg max - the maximum value for each RGB component
2541 */
2542 RGBPrime2YPrimeUVFunctor(component_type max)
2543 : max_(max)
2544 {}
2545
2546 /** apply the transformation
2547 */
2548 template <class V>
2549 result_type operator()(V const & rgb) const
2550 {
2551 typedef detail::RequiresExplicitCast<component_type> Convert;
2552 component_type red = rgb[0] / max_;
2553 component_type green = rgb[1] / max_;
2554 component_type blue = rgb[2] / max_;
2555
2556 result_type result;
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);
2560 return result;
2561 }
2562
2563 static std::string targetColorSpace()
2564 {
2565 return "Y'UV";
2566 }
2567
2568 private:
2569 component_type max_;
2570 };
2571
2572 template <class T>
2573 class FunctorTraits<RGBPrime2YPrimeUVFunctor<T> >
2574 : public FunctorTraitsBase<RGBPrime2YPrimeUVFunctor<T> >
2575 {
2576 public:
2577 typedef VigraTrueType isUnaryFunctor;
2578 };
2579
2580 /** \brief Convert Y'UV color components into non-linear (gamma corrected) R'G'B'.
2581
2582 <b>\#include</b> <vigra/colorconversions.hxx><br>
2583 Namespace: vigra
2584
2585 The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeUVFunctor
2586
2587 <b> Traits defined:</b>
2588
2589 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2590 */
2591 template <class T>
2592 class YPrimeUV2RGBPrimeFunctor
2593 {
2594 typedef typename NumericTraits<T>::RealPromote component_type;
2595
2596 component_type max_;
2597
2598 public:
2599
2600 /** the functor's argument type. (Actually, the argument type
2601 can be any vector type with the same interface.
2602 But this cannot be expressed in a typedef.)
2603 */
2604 typedef TinyVector<T, 3> argument_type;
2605
2606 /** the functor's result type
2607 */
2608 typedef TinyVector<T, 3> result_type;
2609
2610 /** \deprecated use argument_type and result_type
2611 */
2612 typedef TinyVector<T, 3> value_type;
2613
2614 /** default constructor.
2615 The maximum value for each RGB component defaults to 255.
2616 */
2617 YPrimeUV2RGBPrimeFunctor()
2618 : max_(255.0)
2619 {}
2620
2621 /** constructor
2622 \arg max - the maximum value for each RGB component
2623 */
2624 YPrimeUV2RGBPrimeFunctor(component_type max)
2625 : max_(max)
2626 {}
2627
2628 /** apply the transformation
2629 */
2630 template <class V>
2631 result_type operator()(V const & yuv) const
2632 {
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_));
2640 }
2641
2642 static std::string targetColorSpace()
2643 {
2644 return "RGB'";
2645 }
2646 };
2647
2648 template <class T>
2649 class FunctorTraits<YPrimeUV2RGBPrimeFunctor<T> >
2650 : public FunctorTraitsBase<YPrimeUV2RGBPrimeFunctor<T> >
2651 {
2652 public:
2653 typedef VigraTrueType isUnaryFunctor;
2654 };
2655
2656 /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'CbCr color difference components.
2657
2658 <b>\#include</b> <vigra/colorconversions.hxx><br>
2659 Namespace: vigra
2660
2661 This functor basically applies the same transformation as vigra::RGBPrime2YPrimePbPrFunctor
2662 but the color components are scaled so that they can be coded as 8 bit integers with
2663 minimal loss of information:
2664
2665 \f[
2666 \begin{array}{rcl}
2667 16\leq & Y' & \leq 235 \\
2668 16 \leq & Cb & \leq 240 \\
2669 16 \leq & Cr & \leq 240
2670 \end{array}
2671 \f]
2672
2673 <b> Traits defined:</b>
2674
2675 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2676 */
2677 template <class T>
2678 class RGBPrime2YPrimeCbCrFunctor
2679 {
2680 /*
2681 Y in [16, 235]
2682 Cb in [16, 240]
2683 Cr in [16, 240]
2684 maximum saturation: 119.591
2685 red = [81.481, 90.203, 240]
2686 */
2687 public:
2688
2689 /** the result's component type
2690 */
2691 typedef typename NumericTraits<T>::RealPromote component_type;
2692
2693 /** the functor's argument type
2694 */
2695 typedef TinyVector<T, 3> argument_type;
2696
2697 /** the functor's result type
2698 */
2699 typedef TinyVector<component_type, 3> result_type;
2700
2701 /** \deprecated use argument_type and result_type
2702 */
2703 typedef TinyVector<component_type, 3> value_type;
2704
2705 /** default constructor.
2706 The maximum value for each RGB component defaults to 255.
2707 */
2708 RGBPrime2YPrimeCbCrFunctor()
2709 : max_(255.0)
2710 {}
2711
2712 /** constructor
2713 \arg max - the maximum value for each RGB component
2714 */
2715 RGBPrime2YPrimeCbCrFunctor(component_type max)
2716 : max_(max)
2717 {}
2718
2719 /** apply the transformation
2720 */
2721 template <class V>
2722 result_type operator()(V const & rgb) const
2723 {
2724 typedef detail::RequiresExplicitCast<component_type> Convert;
2725 component_type red = rgb[0] / max_;
2726 component_type green = rgb[1] / max_;
2727 component_type blue = rgb[2] / max_;
2728
2729 result_type result;
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);
2733 return result;
2734 }
2735
2736 static std::string targetColorSpace()
2737 {
2738 return "Y'CbCr";
2739 }
2740
2741 private:
2742 component_type max_;
2743 };
2744
2745 template <class T>
2746 class FunctorTraits<RGBPrime2YPrimeCbCrFunctor<T> >
2747 : public FunctorTraitsBase<RGBPrime2YPrimeCbCrFunctor<T> >
2748 {
2749 public:
2750 typedef VigraTrueType isUnaryFunctor;
2751 };
2752
2753 /** \brief Convert Y'CbCr color difference components into non-linear (gamma corrected) R'G'B'.
2754
2755 <b>\#include</b> <vigra/colorconversions.hxx><br>
2756 Namespace: vigra
2757
2758 The functor realizes the inverse of the transformation described in vigra::RGBPrime2YPrimeCbCrFunctor
2759
2760 <b> Traits defined:</b>
2761
2762 <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
2763 */
2764 template <class T>
2765 class YPrimeCbCr2RGBPrimeFunctor
2766 {
2767 typedef typename NumericTraits<T>::RealPromote component_type;
2768
2769 component_type max_;
2770
2771 public:
2772
2773 /** the functor's argument type. (Actually, the argument type
2774 can be any vector type with the same interface.
2775 But this cannot be expressed in a typedef.)
2776 */
2777 typedef TinyVector<T, 3> argument_type;
2778
2779 /** the functor's result type
2780 */
2781 typedef TinyVector<T, 3> result_type;
2782
2783 /** \deprecated use argument_type and result_type
2784 */
2785 typedef TinyVector<T, 3> value_type;
2786
2787 /** default constructor.
2788 The maximum value for each RGB component defaults to 255.
2789 */
2790 YPrimeCbCr2RGBPrimeFunctor()
2791 : max_(255.0)
2792 {}
2793
2794 /** constructor
2795 \arg max - the maximum value for each RGB component
2796 */
2797 YPrimeCbCr2RGBPrimeFunctor(component_type max)
2798 : max_(max)
2799 {}
2800
2801 /** apply the transformation
2802 */
2803 template <class V>
2804 result_type operator()(V const & ycbcr) const
2805 {
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);
2810
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_));
2817 }
2818
2819 static std::string targetColorSpace()
2820 {
2821 return "RGB'";
2822 }
2823 };
2824
2825 template <class T>
2826 class FunctorTraits<YPrimeCbCr2RGBPrimeFunctor<T> >
2827 : public FunctorTraitsBase<YPrimeCbCr2RGBPrimeFunctor<T> >
2828 {
2829 public:
2830 typedef VigraTrueType isUnaryFunctor;
2831 };
2832
2833 //@}
2834
2835 /*
2836 Polar coordinates of standard colors:
2837 =====================================
2838
2839 Lab: black = [320.002, 0, 0]
2840 Luv: black = [347.827, 0, 0]
2841 YPbPr: black = [341.352, 0, 0]
2842 YCbCr: black = [341.352, 0, 0]
2843 YIQ: black = [19.5807, 0, 0]
2844 YUV: black = [346.557, 0, 0]
2845 Lab: red = [1.20391e-05, 0.532406, 0.781353]
2846 Luv: red = [360, 0.532406, 1]
2847 YPbPr: red = [360, 0.299, 0.988419]
2848 YCbCr: red = [360, 0.299, 0.988417]
2849 YIQ: red = [360, 0.299, 1]
2850 YUV: red = [360, 0.299, 1]
2851 Lab: green = [96.0184, 0.877351, 0.895108]
2852 Luv: green = [115.552, 0.877351, 0.758352]
2853 YPbPr: green = [123.001, 0.587, 1]
2854 YCbCr: green = [123.001, 0.587, 0.999996]
2855 YIQ: green = [137.231, 0.587, 0.933362]
2856 YUV: green = [137.257, 0.587, 0.933931]
2857 Lab: blue = [266.287, 0.322957, 0.999997]
2858 Luv: blue = [253.7, 0.322957, 0.729883]
2859 YPbPr: blue = [242.115, 0.114, 0.948831]
2860 YCbCr: blue = [242.115, 0.114, 0.948829]
2861 YIQ: blue = [243.585, 0.114, 0.707681]
2862 YUV: blue = [243.639, 0.114, 0.707424]
2863 Lab: yellow = [62.8531, 0.971395, 0.724189]
2864 Luv: yellow = [73.7, 0.971395, 0.597953]
2865 YPbPr: yellow = [62.1151, 0.886, 0.948831]
2866 YCbCr: yellow = [62.1149, 0.886, 0.948829]
2867 YIQ: yellow = [63.5851, 0.886, 0.707681]
2868 YUV: yellow = [63.6393, 0.886, 0.707424]
2869 Lab: magenta = [288.237, 0.603235, 0.863482]
2870 Luv: magenta = [295.553, 0.603235, 0.767457]
2871 YPbPr: magenta = [303.001, 0.413, 1]
2872 YCbCr: magenta = [303.001, 0.413, 0.999996]
2873 YIQ: magenta = [317.231, 0.413, 0.933362]
2874 YUV: magenta = [317.257, 0.413, 0.933931]
2875 Lab: cyan = [156.378, 0.911133, 0.374577]
2876 Luv: cyan = [180, 0.911133, 0.402694]
2877 YPbPr: cyan = [180, 0.701, 0.988419]
2878 YCbCr: cyan = [180, 0.701, 0.988417]
2879 YIQ: cyan = [180, 0.701, 1]
2880 YUV: cyan = [180, 0.701, 1]
2881 Lab: white = [320.002, 1, 0]
2882 Luv: white = [14.3606, 1, 3.26357e-06]
2883 YPbPr: white = [341.352, 1, 0]
2884 YCbCr: white = [341.352, 1, 0]
2885 YIQ: white = [154.581, 1, 1.24102e-16]
2886 YUV: white = [229.992, 1, 9.81512e-17]
2887
2888 */
2889
2890 /** \ingroup ColorConversions
2891 \defgroup PolarColors Polar Color Coordinates
2892
2893 Transform colors from/to a polar representation (hue, brightness, saturation).
2894 In many situations, this is more intuitive than direct initialization in a
2895 particular color space. The polar coordinates are
2896 normalized so that a color angle of 0 degrees is always associated with red
2897 (green is at about 120 degrees, blue at about 240 degrees - exact values differ
2898 between color spaces). A saturation of 1 is the highest saturation that any RGB color
2899 gets after transformation into the respective color space, and saturation 0 corresponds to
2900 gray. Thus, different color spaces become somewhat comparable.
2901 */
2902 //@{
2903 /** \brief Init L*a*b* color triple from polar representation.
2904
2905 <b>\#include</b> <vigra/colorconversions.hxx><br>
2906 Namespace: vigra
2907
2908 <b> Declarations:</b>
2909
2910 \code
2911 TinyVector<float, 3>
2912 polar2Lab(double color, double brightness, double saturation);
2913
2914 TinyVector<float, 3>
2915 polar2Lab(TinyVector<float, 3> const & polar);
2916 \endcode
2917
2918 \arg color - the color angle in degrees
2919 \arg brightness - between 0 and 1
2920 \arg saturation - between 0 and 1
2921
2922 L*a*b* polar coordinates of some important colors:
2923
2924 \code
2925 black = [*, 0, 0] * - arbitrary
2926 white = [*, 1, 0] * - arbitrary
2927
2928 red = [ 0, 0.532406, 0.781353]
2929 yellow = [62.8531, 0.971395, 0.724189]
2930 green = [96.0184, 0.877351, 0.895108]
2931 cyan = [156.378, 0.911133, 0.374577]
2932 blue = [266.287, 0.322957, 0.999997]
2933 magenta = [288.237, 0.603235, 0.863482]
2934 \endcode
2935 */
2936 inline TinyVector<float, 3>
2937 polar2Lab(double color, double brightness, double saturation)
2938 {
2939 double angle = (color+39.9977)/180.0*M_PI;
2940 double normsat = saturation*133.809;
2941
2942 TinyVector<float, 3> result;
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));
2946 return result;
2947 }
2948
2949
2950 template <class V>
2951 TinyVector<float, 3>
2952 polar2Lab(V const & polar)
2953 {
2954 return polar2Lab(polar[0], polar[1], polar[2]);
2955 }
2956
2957 /** \brief Create polar representation form L*a*b*
2958
2959 <b> Declaration:</b>
2960
2961 \code
2962 namespace vigra {
2963 TinyVector<float, 3> lab2Polar(TinyVector<float, 3> const & lab);
2964 }
2965 \endcode
2966
2967 <b>\#include</b> <vigra/colorconversions.hxx><br>
2968 Namespace: vigra
2969
2970 This realizes the inverse of the transformation described in
2971 \ref polar2Lab().
2972 */
2973 template <class V>
2974 TinyVector<float, 3>
2975 lab2Polar(V const & lab)
2976 {
2977 TinyVector<float, 3> result;
2978 result[1] = float(lab[0]/100.0);
2979 double angle = (lab[1] == 0.0 && lab[2] == 0.0)
2980 ? 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) :
2984 float(angle);
2985 result[2] = float(VIGRA_CSTD::sqrt(lab[1]*lab[1] + lab[2]*lab[2])/133.809);
2986 return result;
2987 }
2988
2989 /** \brief Init L*u*v* color triple from polar representation.
2990
2991 <b>\#include</b> <vigra/colorconversions.hxx><br>
2992 Namespace: vigra
2993
2994 <b> Declarations:</b>
2995
2996 \code
2997 TinyVector<float, 3>
2998 polar2Luv(double color, double brightness, double saturation);
2999
3000 TinyVector<float, 3>
3001 polar2Luv(TinyVector<float, 3> const & polar);
3002 \endcode
3003
3004 \arg color - the color angle in degrees
3005 \arg brightness - between 0 and 1
3006 \arg saturation - between 0 and 1
3007
3008 L*u*v* polar coordinates of some important colors:
3009
3010 \code
3011 black = [*, 0, 0] * - arbitrary
3012 white = [*, 1, 0] * - arbitrary
3013
3014 red = [ 0, 0.532406, 1]
3015 yellow = [ 73.7, 0.971395, 0.597953]
3016 green = [115.552, 0.877351, 0.758352]
3017 cyan = [ 180.0, 0.911133, 0.402694]
3018 blue = [ 253.7, 0.322957, 0.729883]
3019 magenta = [295.553, 0.603235, 0.767457]
3020 \endcode
3021 */
3022 inline TinyVector<float, 3>
3023 polar2Luv(double color, double brightness, double saturation)
3024 {
3025 double angle = (color+12.1727)/180.0*M_PI;
3026 double normsat = saturation*179.04;
3027
3028 TinyVector<float, 3> result;
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));
3032 return result;
3033 }
3034
3035 template <class V>
3036 TinyVector<float, 3>
3037 polar2Luv(V const & polar)
3038 {
3039 return polar2Luv(polar[0], polar[1], polar[2]);
3040 }
3041
3042 /** \brief Create polar representation form L*u*v*
3043
3044 <b> Declaration:</b>
3045
3046 \code
3047 namespace vigra {
3048 TinyVector<float, 3> luv2Polar(TinyVector<float, 3> const & luv);
3049 }
3050 \endcode
3051
3052 <b>\#include</b> <vigra/colorconversions.hxx><br>
3053 Namespace: vigra
3054
3055 This realizes the inverse of the transformation described in
3056 \ref polar2Luv().
3057 */
3058 template <class V>
3059 TinyVector<float, 3>
3060 luv2Polar(V const & luv)
3061 {
3062 TinyVector<float, 3> result;
3063 result[1] = float(luv[0]/100.0);
3064 double angle = (luv[1] == 0.0 && luv[2] == 0.0)
3065 ? 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) :
3069 float(angle);
3070 result[2] = float(VIGRA_CSTD::sqrt(luv[1]*luv[1] + luv[2]*luv[2])/179.04);
3071 return result;
3072 }
3073
3074 /** \brief Init Y'PbPr color triple from polar representation.
3075
3076 <b>\#include</b> <vigra/colorconversions.hxx><br>
3077 Namespace: vigra
3078
3079 <b> Declarations:</b>
3080
3081 \code
3082 TinyVector<float, 3>
3083 polar2YPrimePbPr(double color, double brightness, double saturation);
3084
3085 TinyVector<float, 3>
3086 polar2YPrimePbPr(TinyVector<float, 3> const & polar);
3087 \endcode
3088
3089 \arg color - the color angle in degrees
3090 \arg brightness - between 0 and 1
3091 \arg saturation - between 0 and 1
3092
3093 Y'PbPr polar coordinates of some important colors:
3094
3095 \code
3096 black = [*, 0, 0] * - arbitrary
3097 white = [*, 1, 0] * - arbitrary
3098
3099 red = [ 0, 0.299, 0.988419]
3100 yellow = [62.1151, 0.886, 0.948831]
3101 green = [123.001, 0.587, 1]
3102 cyan = [ 180.0, 0.701, 0.988419]
3103 blue = [242.115, 0.114, 0.948831]
3104 magenta = [303.001, 0.413, 1]
3105 \endcode
3106 */
3107 inline TinyVector<float, 3>
3108 polar2YPrimePbPr(double color, double brightness, double saturation)
3109 {
3110 double angle = (color+18.6481)/180.0*M_PI;
3111 double normsat = saturation*0.533887;
3112
3113 TinyVector<float, 3> result;
3114 result[0] = float(brightness);
3115 result[1] = float(-normsat*VIGRA_CSTD::sin(angle));
3116 result[2] = float(normsat*VIGRA_CSTD::cos(angle));
3117 return result;
3118 }
3119
3120 template <class V>
3121 TinyVector<float, 3>
3122 polar2YPrimePbPr(V const & polar)
3123 {
3124 return polar2YPrimePbPr(polar[0], polar[1], polar[2]);
3125 }
3126
3127 /** \brief Create polar representation form Y'PbPr
3128
3129 <b> Declaration:</b>
3130
3131 \code
3132 namespace vigra {
3133 TinyVector<float, 3> yPrimePbPr2Polar(TinyVector<float, 3> const & ypbpr);
3134 }
3135 \endcode
3136
3137 <b>\#include</b> <vigra/colorconversions.hxx><br>
3138 Namespace: vigra
3139
3140 This realizes the inverse of the transformation described in
3141 \ref polar2YPrimePbPr().
3142 */
3143 template <class V>
3144 TinyVector<float, 3>
3145 yPrimePbPr2Polar(V const & ypbpr)
3146 {
3147 TinyVector<float, 3> result;
3148 result[1] = float(ypbpr[0]);
3149 double angle = (ypbpr[1] == 0.0 && ypbpr[2] == 0.0)
3150 ? 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) :
3154 float(angle);
3155 result[2] = float(VIGRA_CSTD::sqrt(ypbpr[1]*ypbpr[1] + ypbpr[2]*ypbpr[2])/0.533887);
3156 return result;
3157 }
3158
3159 /** \brief Init Y'CbCr color triple from polar representation.
3160
3161 <b>\#include</b> <vigra/colorconversions.hxx><br>
3162 Namespace: vigra
3163
3164 <b> Declarations:</b>
3165
3166 \code
3167 TinyVector<float, 3>
3168 polar2YPrimeCbCr(double color, double brightness, double saturation);
3169
3170 TinyVector<float, 3>
3171 polar2YPrimeCbCr(TinyVector<float, 3> const & polar);
3172 \endcode
3173
3174 \arg color - the color angle in degrees
3175 \arg brightness - between 0 and 1
3176 \arg saturation - between 0 and 1
3177
3178 Y'CbCr polar coordinates of some important colors:
3179
3180 \code
3181 black = [*, 0, 0] * - arbitrary
3182 white = [*, 1, 0] * - arbitrary
3183
3184 red = [ 0, 0.299, 0.988419]
3185 yellow = [62.1151, 0.886, 0.948831]
3186 green = [123.001, 0.587, 1]
3187 cyan = [ 180.0, 0.701, 0.988419]
3188 blue = [242.115, 0.114, 0.948831]
3189 magenta = [303.001, 0.413, 1]
3190 \endcode
3191 */
3192 inline TinyVector<float, 3>
3193 polar2YPrimeCbCr(double color, double brightness, double saturation)
3194 {
3195 double angle = (color+18.6482)/180.0*M_PI;
3196 double normsat = saturation*119.591;
3197
3198 TinyVector<float, 3> result;
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);
3202 return result;
3203 }
3204
3205 template <class V>
3206 TinyVector<float, 3>
3207 polar2YPrimeCbCr(V const & polar)
3208 {
3209 return polar2YPrimeCbCr(polar[0], polar[1], polar[2]);
3210 }
3211
3212 /** \brief Create polar representation form Y'CbCr
3213
3214 <b> Declaration:</b>
3215
3216 \code
3217 namespace vigra {
3218 TinyVector<float, 3> yPrimeCbCr2Polar(TinyVector<float, 3> const & ycbcr);
3219 }
3220 \endcode
3221
3222 <b>\#include</b> <vigra/colorconversions.hxx><br>
3223 Namespace: vigra
3224
3225 This realizes the inverse of the transformation described in
3226 \ref polar2YPrimeCbCr().
3227 */
3228 template <class V>
3229 TinyVector<float, 3>
3230 yPrimeCbCr2Polar(V const & ycbcr)
3231 {
3232 TinyVector<float, 3> result;
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)
3237 ? 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) :
3241 float(angle);
3242 result[2] = float(VIGRA_CSTD::sqrt(cb*cb + cr*cr)/119.591);
3243 return result;
3244 }
3245
3246 /** \brief Init Y'IQ color triple from polar representation.
3247
3248 <b>\#include</b> <vigra/colorconversions.hxx><br>
3249 Namespace: vigra
3250
3251 <b> Declarations:</b>
3252
3253 \code
3254 TinyVector<float, 3>
3255 polar2YPrimeIQ(double color, double brightness, double saturation);
3256
3257 TinyVector<float, 3>
3258 polar2YPrimeIQ(TinyVector<float, 3> const & polar);
3259 \endcode
3260
3261 \arg color - the color angle in degrees
3262 \arg brightness - between 0 and 1
3263 \arg saturation - between 0 and 1
3264
3265 Y'IQ polar coordinates of some important colors:
3266
3267 \code
3268 black = [*, 0, 0] * - arbitrary
3269 white = [*, 1, 0] * - arbitrary
3270
3271 red = [ 0, 0.299, 1]
3272 yellow = [63.5851, 0.886, 0.707681]
3273 green = [137.231, 0.587, 0.933362]
3274 cyan = [ 180.0, 0.701, 1]
3275 blue = [243.585, 0.114, 0.707681]
3276 magenta = [317.231, 0.413, 0.933362]
3277 \endcode
3278 */
3279 inline TinyVector<float, 3>
3280 polar2YPrimeIQ(double color, double brightness, double saturation)
3281 {
3282 double angle = (color-19.5807)/180.0*M_PI;
3283 double normsat = saturation*0.632582;
3284
3285 TinyVector<float, 3> result;
3286 result[0] = float(brightness);
3287 result[1] = float(normsat*VIGRA_CSTD::cos(angle));
3288 result[2] = float(-normsat*VIGRA_CSTD::sin(angle));
3289 return result;
3290 }
3291
3292 template <class V>
3293 TinyVector<float, 3>
3294 polar2YPrimeIQ(V const & polar)
3295 {
3296 return polar2YPrimeIQ(polar[0], polar[1], polar[2]);
3297 }
3298
3299 /** \brief Create polar representation form Y'IQ
3300
3301 <b> Declaration:</b>
3302
3303 \code
3304 namespace vigra {
3305 TinyVector<float, 3> yPrimeIQ2Polar(TinyVector<float, 3> const & yiq);
3306 }
3307 \endcode
3308
3309 <b>\#include</b> <vigra/colorconversions.hxx><br>
3310 Namespace: vigra
3311
3312 This realizes the inverse of the transformation described in
3313 \ref polar2YPrimeIQ().
3314 */
3315 template <class V>
3316 TinyVector<float, 3>
3317 yPrimeIQ2Polar(V const & yiq)
3318 {
3319 TinyVector<float, 3> result;
3320 result[1] = float(yiq[0]);
3321 double angle = (yiq[1] == 0.0 && yiq[2] == 0.0)
3322 ? 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) :
3326 float(angle);
3327 result[2] = float(VIGRA_CSTD::sqrt(yiq[1]*yiq[1] + yiq[2]*yiq[2])/0.632582);
3328 return result;
3329 }
3330
3331 /** \brief Init Y'UV color triple from polar representation.
3332
3333 <b>\#include</b> <vigra/colorconversions.hxx><br>
3334 Namespace: vigra
3335
3336 <b> Declarations:</b>
3337
3338 \code
3339 TinyVector<float, 3>
3340 polar2YPrimeUV(double color, double brightness, double saturation);
3341
3342 TinyVector<float, 3>
3343 polar2YPrimeUV(TinyVector<float, 3> const & polar);
3344 \endcode
3345
3346 \arg color - the color angle in degrees
3347 \arg brightness - between 0 and 1
3348 \arg saturation - between 0 and 1
3349
3350 Y'UV polar coordinates of some important colors:
3351
3352 \code
3353 black = [*, 0, 0] * - arbitrary
3354 white = [*, 1, 0] * - arbitrary
3355
3356 red = [ 0, 0.299, 1]
3357 yellow = [63.5851, 0.886, 0.707681]
3358 green = [137.231, 0.587, 0.933362]
3359 cyan = [ 180.0, 0.701, 1]
3360 blue = [243.585, 0.114, 0.707681]
3361 magenta = [317.231, 0.413, 0.933362]
3362 \endcode
3363 */
3364 inline TinyVector<float, 3>
3365 polar2YPrimeUV(double color, double brightness, double saturation)
3366 {
3367 double angle = (color+13.4569)/180.0*M_PI;
3368 double normsat = saturation*0.632324;
3369
3370 TinyVector<float, 3> result;
3371 result[0] = float(brightness);
3372 result[1] = float(-normsat*VIGRA_CSTD::sin(angle));
3373 result[2] = float(normsat*VIGRA_CSTD::cos(angle));
3374 return result;
3375 }
3376
3377 template <class V>
3378 TinyVector<float, 3>
3379 polar2YPrimeUV(V const & polar)
3380 {
3381 return polar2YPrimeUV(polar[0], polar[1], polar[2]);
3382 }
3383
3384 /** \brief Create polar representation form Y'UV
3385
3386 <b> Declaration:</b>
3387
3388 \code
3389 namespace vigra {
3390 TinyVector<float, 3> yPrimeUV2Polar(TinyVector<float, 3> const & yuv);
3391 }
3392 \endcode
3393
3394 <b>\#include</b> <vigra/colorconversions.hxx><br>
3395 Namespace: vigra
3396
3397 This realizes the inverse of the transformation described in
3398 \ref polar2YPrimeUV().
3399 */
3400 template <class V>
3401 TinyVector<float, 3>
3402 yPrimeUV2Polar(V const & yuv)
3403 {
3404 TinyVector<float, 3> result;
3405 result[1] = float(yuv[0]);
3406 double angle = (yuv[1] == 0.0 && yuv[2] == 0.0)
3407 ? 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) :
3411 float(angle);
3412 result[2] = float(VIGRA_CSTD::sqrt(yuv[1]*yuv[1] + yuv[2]*yuv[2])/0.632324);
3413 return result;
3414 }
3415
3416 //@}
3417
3418 } // namespace vigra
3419
3420 #endif /* VIGRA_COLORCONVERSIONS_HXX */
vigra::RGB2RGBPrimeFunctor::argument_type
TinyVector< From, 3 > argument_type
Definition: colorconversions.hxx:283
vigra::polar2YPrimeUV
TinyVector< float, 3 > polar2YPrimeUV(double color, double brightness, double saturation)
Init Y'UV color triple from polar representation.
Definition: colorconversions.hxx:3365
vigra::RGBPrime2LuvFunctor::RGBPrime2LuvFunctor
RGBPrime2LuvFunctor(component_type max)
Definition: colorconversions.hxx:1847
vigra::XYZ2RGBFunctor::operator()
result_type operator()(V const &xyz) const
Definition: colorconversions.hxx:1001
vigra::sRGB2RGBFunctor
Convert standardized sRGB into non-linear (raw) RGB.
Definition: colorconversions.hxx:658
vigra::yPrimePbPr2Polar
TinyVector< float, 3 > yPrimePbPr2Polar(V const &ypbpr)
Create polar representation form Y'PbPr.
Definition: colorconversions.hxx:3145
vigra::Lab2RGBPrimeFunctor::Lab2RGBPrimeFunctor
Lab2RGBPrimeFunctor(component_type max)
Definition: colorconversions.hxx:2080
vigra::RGBPrime2RGBFunctor::operator()
result_type operator()(argument_type const &rgb) const
Definition: colorconversions.hxx:566
vigra::XYZ2RGBPrimeFunctor::result_type
TinyVector< T, 3 > result_type
Definition: colorconversions.hxx:1063
vigra::sRGB2RGBFunctor::value_type
TinyVector< To, 3 > value_type
Definition: colorconversions.hxx:672
vigra::RGBPrime2YPrimeIQFunctor::RGBPrime2YPrimeIQFunctor
RGBPrime2YPrimeIQFunctor()
Definition: colorconversions.hxx:2352
vigra::YPrimeUV2RGBPrimeFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:2604
vigra::RGB2LabFunctor::result_type
XYZ2LabFunctor< component_type >::result_type result_type
Definition: colorconversions.hxx:1609
vigra::RGB2LabFunctor::component_type
NumericTraits< T >::RealPromote component_type
Definition: colorconversions.hxx:1601
vigra::sRGB2RGBFunctor::sRGB2RGBFunctor
sRGB2RGBFunctor(component_type max)
Definition: colorconversions.hxx:688
vigra::RGBPrime2LabFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:1914
vigra::Lab2XYZFunctor::result_type
TinyVector< component_type, 3 > result_type
Definition: colorconversions.hxx:1417
vigra::YPrimeIQ2RGBPrimeFunctor::result_type
TinyVector< T, 3 > result_type
Definition: colorconversions.hxx:2425
vigra::RGBPrime2RGBFunctor
Convert non-linear (gamma corrected) R'G'B' into non-linear (raw) RGB.
Definition: colorconversions.hxx:530
vigra::atan2
FixedPoint16< 2, OverflowHandling > atan2(FixedPoint16< IntBits, OverflowHandling > y, FixedPoint16< IntBits, OverflowHandling > x)
Arctangent. Accuracy better than 1/3 degree (9 significant bits).
Definition: fixedpoint.hxx:1654
vigra::RGBPrime2YPrimePbPrFunctor::component_type
NumericTraits< T >::RealPromote component_type
Definition: colorconversions.hxx:2152
vigra::RGB2sRGBFunctor::component_type
NumericTraits< To >::RealPromote component_type
Definition: colorconversions.hxx:423
vigra::Lab2XYZFunctor
Convert perceptual uniform CIE L*a*b* into standardized tri-stimulus XYZ.
Definition: colorconversions.hxx:1403
vigra::RGBPrime2YPrimeIQFunctor::value_type
TinyVector< component_type, 3 > value_type
Definition: colorconversions.hxx:2347
vigra::RGB2LabFunctor::operator()
result_type operator()(V const &rgb) const
Definition: colorconversions.hxx:1632
vigra::sRGB2RGBFunctor::argument_type
TinyVector< From, 3 > argument_type
Definition: colorconversions.hxx:664
vigra::RGBPrime2RGBFunctor::component_type
NumericTraits< To >::RealPromote component_type
Definition: colorconversions.hxx:548
vigra::RGBPrime2YPrimePbPrFunctor::RGBPrime2YPrimePbPrFunctor
RGBPrime2YPrimePbPrFunctor(component_type max)
Definition: colorconversions.hxx:2176
vigra::yPrimeCbCr2Polar
TinyVector< float, 3 > yPrimeCbCr2Polar(V const &ycbcr)
Create polar representation form Y'CbCr.
Definition: colorconversions.hxx:3230
vigra::sRGB2RGBFunctor::sRGB2RGBFunctor
sRGB2RGBFunctor()
Definition: colorconversions.hxx:681
vigra::RGBPrime2YPrimeCbCrFunctor::RGBPrime2YPrimeCbCrFunctor
RGBPrime2YPrimeCbCrFunctor()
Definition: colorconversions.hxx:2708
vigra::YPrimePbPr2RGBPrimeFunctor::operator()
result_type operator()(V const &ypbpr) const
Definition: colorconversions.hxx:2265
vigra::RGBPrime2RGBFunctor::value_type
TinyVector< To, 3 > value_type
Definition: colorconversions.hxx:544
vigra::RGB2LabFunctor::value_type
XYZ2LabFunctor< component_type >::result_type value_type
Definition: colorconversions.hxx:1613
vigra::RGBPrime2LabFunctor::RGBPrime2LabFunctor
RGBPrime2LabFunctor(component_type max)
Definition: colorconversions.hxx:1934
vigra::RGBPrime2LabFunctor
Convert non-linear (gamma corrected) R'G'B' into perceptual uniform CIE L*a*b*.
Definition: colorconversions.hxx:1904
vigra::RGBPrime2YPrimeCbCrFunctor::result_type
TinyVector< component_type, 3 > result_type
Definition: colorconversions.hxx:2699
vigra::YPrimeIQ2RGBPrimeFunctor::YPrimeIQ2RGBPrimeFunctor
YPrimeIQ2RGBPrimeFunctor()
Definition: colorconversions.hxx:2434
vigra::RGBPrime2YPrimeUVFunctor::operator()
result_type operator()(V const &rgb) const
Definition: colorconversions.hxx:2549
vigra::RGBPrime2YPrimeCbCrFunctor::operator()
result_type operator()(V const &rgb) const
Definition: colorconversions.hxx:2722
vigra::Luv2RGBPrimeFunctor::value_type
XYZ2RGBFunctor< T >::result_type value_type
Definition: colorconversions.hxx:1997
vigra::RGB2XYZFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:798
vigra::RGB2LuvFunctor::component_type
NumericTraits< T >::RealPromote component_type
Definition: colorconversions.hxx:1507
vigra::RGB2RGBPrimeFunctor::operator()
result_type operator()(V const &rgb) const
Definition: colorconversions.hxx:314
vigra::XYZ2RGBPrimeFunctor::XYZ2RGBPrimeFunctor
XYZ2RGBPrimeFunctor()
Definition: colorconversions.hxx:1072
vigra::linalg::sin
linalg::TemporaryMatrix< T > sin(MultiArrayView< 2, T, C > const &v)
vigra::Lab2XYZFunctor::component_type
NumericTraits< T >::RealPromote component_type
Definition: colorconversions.hxx:1409
vigra::RGB2sRGBFunctor::argument_type
TinyVector< From, 3 > argument_type
Definition: colorconversions.hxx:411
vigra::RGB2LuvFunctor::operator()
result_type operator()(V const &rgb) const
Definition: colorconversions.hxx:1538
vigra::RGB2sRGBFunctor::operator()
result_type operator()(V const &rgb) const
Definition: colorconversions.hxx:442
vigra::XYZ2RGBFunctor::XYZ2RGBFunctor
XYZ2RGBFunctor(component_type max)
Definition: colorconversions.hxx:994
vigra::XYZ2RGBPrimeFunctor::XYZ2RGBPrimeFunctor
XYZ2RGBPrimeFunctor(component_type max)
Definition: colorconversions.hxx:1079
vigra::Luv2RGBFunctor
Convert perceptual uniform CIE L*u*v* into linear (raw) RGB.
Definition: colorconversions.hxx:1667
vigra::XYZ2LuvFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:1155
vigra::RGB2sRGBFunctor::RGB2sRGBFunctor
RGB2sRGBFunctor()
Definition: colorconversions.hxx:428
vigra::XYZ2RGBPrimeFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:1059
vigra::Lab2RGBPrimeFunctor
Convert perceptual uniform CIE L*a*b* into non-linear (gamma corrected) R'G'B'.
Definition: colorconversions.hxx:2047
vigra::RGBPrime2YPrimePbPrFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:2156
vigra::XYZ2RGBFunctor::result_type
TinyVector< T, 3 > result_type
Definition: colorconversions.hxx:978
vigra::Luv2RGBFunctor::value_type
XYZ2RGBFunctor< T >::result_type value_type
Definition: colorconversions.hxx:1687
vigra::RGBPrime2YPrimeIQFunctor::result_type
TinyVector< component_type, 3 > result_type
Definition: colorconversions.hxx:2343
vigra::RGBPrime2YPrimeUVFunctor::RGBPrime2YPrimeUVFunctor
RGBPrime2YPrimeUVFunctor()
Definition: colorconversions.hxx:2535
vigra::RGBPrime2RGBFunctor::RGBPrime2RGBFunctor
RGBPrime2RGBFunctor(component_type max)
Definition: colorconversions.hxx:560
vigra::RGBPrime2YPrimeCbCrFunctor::value_type
TinyVector< component_type, 3 > value_type
Definition: colorconversions.hxx:2703
vigra::polar2YPrimeIQ
TinyVector< float, 3 > polar2YPrimeIQ(double color, double brightness, double saturation)
Init Y'IQ color triple from polar representation.
Definition: colorconversions.hxx:3280
vigra::Lab2RGBPrimeFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:2060
vigra::Luv2RGBPrimeFunctor::result_type
XYZ2RGBFunctor< T >::result_type result_type
Definition: colorconversions.hxx:1993
vigra::sRGB2RGBFunctor::component_type
NumericTraits< To >::RealPromote component_type
Definition: colorconversions.hxx:676
vigra::Luv2RGBPrimeFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:1989
vigra::RGBPrime2LabFunctor::value_type
XYZ2LabFunctor< component_type >::result_type value_type
Definition: colorconversions.hxx:1922
vigra::YPrimePbPr2RGBPrimeFunctor::YPrimePbPr2RGBPrimeFunctor
YPrimePbPr2RGBPrimeFunctor()
Definition: colorconversions.hxx:2251
vigra::YPrimeIQ2RGBPrimeFunctor::value_type
TinyVector< T, 3 > value_type
Definition: colorconversions.hxx:2429
vigra::RGBPrime2YPrimeUVFunctor::component_type
NumericTraits< T >::RealPromote component_type
Definition: colorconversions.hxx:2518
vigra::RGB2RGBPrimeFunctor::result_type
TinyVector< To, 3 > result_type
Definition: colorconversions.hxx:287
vigra::RGB2RGBPrimeFunctor::RGB2RGBPrimeFunctor
RGB2RGBPrimeFunctor()
Definition: colorconversions.hxx:300
vigra::RGBPrime2YPrimePbPrFunctor::RGBPrime2YPrimePbPrFunctor
RGBPrime2YPrimePbPrFunctor()
Definition: colorconversions.hxx:2169
vigra::RGBPrime2XYZFunctor
Convert non-linear (gamma corrected) R'G'B' into standardized tri-stimulus XYZ.
Definition: colorconversions.hxx:873
vigra::RGBPrime2LuvFunctor::RGBPrime2LuvFunctor
RGBPrime2LuvFunctor()
Definition: colorconversions.hxx:1840
vigra::RGBPrime2XYZFunctor::value_type
TinyVector< component_type, 3 > value_type
Definition: colorconversions.hxx:891
vigra::RGBPrime2YPrimeUVFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:2522
vigra::Lab2RGBFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:1744
vigra::lab2Polar
TinyVector< float, 3 > lab2Polar(V const &lab)
Create polar representation form L*a*b*.
Definition: colorconversions.hxx:2975
vigra::RGB2LabFunctor::RGB2LabFunctor
RGB2LabFunctor()
Definition: colorconversions.hxx:1618
vigra::RGBPrime2YPrimeUVFunctor::RGBPrime2YPrimeUVFunctor
RGBPrime2YPrimeUVFunctor(component_type max)
Definition: colorconversions.hxx:2542
vigra::RGB2LabFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:1605
vigra::RGB2LabFunctor::RGB2LabFunctor
RGB2LabFunctor(component_type max)
Definition: colorconversions.hxx:1625
vigra::YPrimeCbCr2RGBPrimeFunctor::value_type
TinyVector< T, 3 > value_type
Definition: colorconversions.hxx:2785
vigra::YPrimeUV2RGBPrimeFunctor::YPrimeUV2RGBPrimeFunctor
YPrimeUV2RGBPrimeFunctor(component_type max)
Definition: colorconversions.hxx:2624
vigra::RGBPrime2LuvFunctor
Convert non-linear (gamma corrected) R'G'B' into perceptual uniform CIE L*u*v*.
Definition: colorconversions.hxx:1817
vigra::Lab2XYZFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:1413
vigra::Lab2RGBFunctor::Lab2RGBFunctor
Lab2RGBFunctor(component_type max)
Definition: colorconversions.hxx:1764
vigra::YPrimeIQ2RGBPrimeFunctor::operator()
result_type operator()(V const &yiq) const
Definition: colorconversions.hxx:2448
vigra::YPrimeUV2RGBPrimeFunctor::result_type
TinyVector< T, 3 > result_type
Definition: colorconversions.hxx:2608
vigra::YPrimeUV2RGBPrimeFunctor::YPrimeUV2RGBPrimeFunctor
YPrimeUV2RGBPrimeFunctor()
Definition: colorconversions.hxx:2617
vigra::RGB2LuvFunctor::RGB2LuvFunctor
RGB2LuvFunctor(component_type max)
Definition: colorconversions.hxx:1531
vigra::RGB2RGBPrimeFunctor::component_type
NumericTraits< To >::RealPromote component_type
Definition: colorconversions.hxx:295
vigra::RGB2XYZFunctor::RGB2XYZFunctor
RGB2XYZFunctor()
Definition: colorconversions.hxx:811
vigra::RGBPrime2XYZFunctor::RGBPrime2XYZFunctor
RGBPrime2XYZFunctor()
Definition: colorconversions.hxx:896
vigra::YPrimePbPr2RGBPrimeFunctor
Convert Y'PbPr color difference components into non-linear (gamma corrected) R'G'B'.
Definition: colorconversions.hxx:2226
vigra::RGB2LuvFunctor::RGB2LuvFunctor
RGB2LuvFunctor()
Definition: colorconversions.hxx:1524
vigra::norm
FFTWComplex< R >::NormType norm(const FFTWComplex< R > &a)
norm (= magnitude)
Definition: fftw3.hxx:1037
vigra::RGBPrime2XYZFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:883
vigra::RGB2sRGBFunctor::RGB2sRGBFunctor
RGB2sRGBFunctor(component_type max)
Definition: colorconversions.hxx:435
vigra::RGBPrime2RGBFunctor::argument_type
TinyVector< From, 3 > argument_type
Definition: colorconversions.hxx:536
vigra::RGBPrime2YPrimePbPrFunctor::operator()
result_type operator()(V const &rgb) const
Definition: colorconversions.hxx:2183
vigra::Lab2RGBFunctor
Convert perceptual uniform CIE L*a*b* into linear (raw) RGB.
Definition: colorconversions.hxx:1731
vigra::RGBPrime2RGBFunctor::RGBPrime2RGBFunctor
RGBPrime2RGBFunctor()
Definition: colorconversions.hxx:553
vigra::RGB2XYZFunctor::RGB2XYZFunctor
RGB2XYZFunctor(component_type max)
Definition: colorconversions.hxx:818
vigra::RGB2LuvFunctor::value_type
XYZ2LuvFunctor< component_type >::result_type value_type
Definition: colorconversions.hxx:1519
vigra::Luv2RGBPrimeFunctor
Convert perceptual uniform CIE L*u*v* into non-linear (gamma corrected) R'G'B'.
Definition: colorconversions.hxx:1976
vigra::XYZ2LabFunctor
Convert standardized tri-stimulus XYZ into perceptual uniform CIE L*a*b*.
Definition: colorconversions.hxx:1328
vigra::RGBPrime2YPrimeCbCrFunctor::component_type
NumericTraits< T >::RealPromote component_type
Definition: colorconversions.hxx:2691
vigra::YPrimeCbCr2RGBPrimeFunctor::operator()
result_type operator()(V const &ycbcr) const
Definition: colorconversions.hxx:2804
vigra::XYZ2RGBFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:974
vigra::RGB2sRGBFunctor
Convert linear (raw) RGB into standardized sRGB.
Definition: colorconversions.hxx:405
vigra::XYZ2RGBFunctor::XYZ2RGBFunctor
XYZ2RGBFunctor()
Definition: colorconversions.hxx:987
vigra::RGBPrime2LabFunctor::component_type
NumericTraits< T >::RealPromote component_type
Definition: colorconversions.hxx:1910
vigra::polar2Luv
TinyVector< float, 3 > polar2Luv(double color, double brightness, double saturation)
Init L*u*v* color triple from polar representation.
Definition: colorconversions.hxx:3023
vigra::RGBPrime2YPrimeCbCrFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:2695
vigra::RGBPrime2YPrimePbPrFunctor::value_type
TinyVector< component_type, 3 > value_type
Definition: colorconversions.hxx:2164
vigra::YPrimePbPr2RGBPrimeFunctor::value_type
TinyVector< T, 3 > value_type
Definition: colorconversions.hxx:2246
vigra::Luv2RGBPrimeFunctor::Luv2RGBPrimeFunctor
Luv2RGBPrimeFunctor(component_type max)
Definition: colorconversions.hxx:2009
vigra::YPrimeCbCr2RGBPrimeFunctor::YPrimeCbCr2RGBPrimeFunctor
YPrimeCbCr2RGBPrimeFunctor()
Definition: colorconversions.hxx:2790
vigra::RGB2sRGBFunctor::result_type
TinyVector< To, 3 > result_type
Definition: colorconversions.hxx:415
vigra::RGBPrime2LuvFunctor::value_type
XYZ2LuvFunctor< component_type >::result_type value_type
Definition: colorconversions.hxx:1835
vigra::RGBPrime2XYZFunctor::result_type
TinyVector< component_type, 3 > result_type
Definition: colorconversions.hxx:887
vigra::Lab2RGBFunctor::operator()
result_type operator()(V const &lab) const
Definition: colorconversions.hxx:1771
vigra::YPrimeCbCr2RGBPrimeFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:2777
vigra::YPrimePbPr2RGBPrimeFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:2238
vigra::RGBPrime2LuvFunctor::operator()
result_type operator()(V const &rgb) const
Definition: colorconversions.hxx:1854
vigra::Luv2RGBFunctor::result_type
XYZ2RGBFunctor< T >::result_type result_type
Definition: colorconversions.hxx:1683
vigra::Luv2RGBPrimeFunctor::Luv2RGBPrimeFunctor
Luv2RGBPrimeFunctor()
Definition: colorconversions.hxx:2002
vigra::Lab2XYZFunctor::operator()
result_type operator()(V const &lab) const
Definition: colorconversions.hxx:1433
vigra::RGB2RGBPrimeFunctor::value_type
TinyVector< To, 3 > value_type
Definition: colorconversions.hxx:291
vigra::RGB2XYZFunctor::component_type
NumericTraits< T >::RealPromote component_type
Definition: colorconversions.hxx:794
vigra::yPrimeIQ2Polar
TinyVector< float, 3 > yPrimeIQ2Polar(V const &yiq)
Create polar representation form Y'IQ.
Definition: colorconversions.hxx:3317
vigra::XYZ2RGBPrimeFunctor
Convert standardized tri-stimulus XYZ into non-linear (gamma corrected) R'G'B'.
Definition: colorconversions.hxx:1045
vigra::RGB2LabFunctor
Convert linear (raw) RGB into perceptual uniform CIE L*a*b*.
Definition: colorconversions.hxx:1588
vigra::RGBPrime2YPrimeUVFunctor::value_type
TinyVector< component_type, 3 > value_type
Definition: colorconversions.hxx:2530
vigra::RGBPrime2LuvFunctor::component_type
NumericTraits< T >::RealPromote component_type
Definition: colorconversions.hxx:1823
vigra::XYZ2RGBPrimeFunctor::operator()
result_type operator()(V const &xyz) const
Definition: colorconversions.hxx:1086
vigra::RGBPrime2YPrimePbPrFunctor
Convert non-linear (gamma corrected) R'G'B' into Y'PbPr color difference components.
Definition: colorconversions.hxx:2139
vigra::polar2YPrimePbPr
TinyVector< float, 3 > polar2YPrimePbPr(double color, double brightness, double saturation)
Init Y'PbPr color triple from polar representation.
Definition: colorconversions.hxx:3108
vigra::Luv2RGBFunctor::operator()
result_type operator()(V const &luv) const
Definition: colorconversions.hxx:1700
vigra::RGBPrime2YPrimeIQFunctor
Convert non-linear (gamma corrected) R'G'B' into Y'IQ components.
Definition: colorconversions.hxx:2322
vigra::TinyVector
Class for fixed size vectors.This class contains an array of size SIZE of the specified VALUETYPE...
Definition: accessor.hxx:940
vigra::Luv2XYZFunctor::component_type
NumericTraits< T >::RealPromote component_type
Definition: colorconversions.hxx:1233
vigra::Lab2RGBFunctor::result_type
XYZ2RGBFunctor< T >::result_type result_type
Definition: colorconversions.hxx:1748
vigra::RGBPrime2YPrimePbPrFunctor::result_type
TinyVector< component_type, 3 > result_type
Definition: colorconversions.hxx:2160
vigra::RGBPrime2LuvFunctor::result_type
XYZ2LuvFunctor< component_type >::result_type result_type
Definition: colorconversions.hxx:1831
vigra::YPrimePbPr2RGBPrimeFunctor::result_type
TinyVector< T, 3 > result_type
Definition: colorconversions.hxx:2242
vigra::RGBPrime2LabFunctor::result_type
XYZ2LabFunctor< component_type >::result_type result_type
Definition: colorconversions.hxx:1918
vigra::RGB2RGBPrimeFunctor::RGB2RGBPrimeFunctor
RGB2RGBPrimeFunctor(component_type max)
Definition: colorconversions.hxx:307
vigra::RGB2XYZFunctor
Convert linear (raw) RGB into standardized tri-stimulus XYZ.
Definition: colorconversions.hxx:788
vigra::RGB2XYZFunctor::operator()
result_type operator()(argument_type const &rgb) const
Definition: colorconversions.hxx:824
vigra::Luv2XYZFunctor::result_type
TinyVector< component_type, 3 > result_type
Definition: colorconversions.hxx:1241
vigra::gamma
double gamma(double x)
The gamma function.
Definition: mathutil.hxx:1577
vigra::Lab2XYZFunctor::value_type
TinyVector< component_type, 3 > value_type
Definition: colorconversions.hxx:1421
vigra::XYZ2LuvFunctor::result_type
TinyVector< component_type, 3 > result_type
Definition: colorconversions.hxx:1159
vigra::Lab2RGBPrimeFunctor::Lab2RGBPrimeFunctor
Lab2RGBPrimeFunctor()
Definition: colorconversions.hxx:2073
vigra::RGB2RGBPrimeFunctor
Convert linear (raw) RGB into non-linear (gamma corrected) R'G'B'.
Definition: colorconversions.hxx:277
vigra::RGBPrime2LabFunctor::operator()
result_type operator()(V const &rgb) const
Definition: colorconversions.hxx:1941
vigra::XYZ2LabFunctor::value_type
TinyVector< component_type, 3 > value_type
Definition: colorconversions.hxx:1346
vigra::XYZ2LuvFunctor::value_type
TinyVector< component_type, 3 > value_type
Definition: colorconversions.hxx:1163
vigra::YPrimeCbCr2RGBPrimeFunctor::result_type
TinyVector< T, 3 > result_type
Definition: colorconversions.hxx:2781
vigra::Lab2RGBFunctor::value_type
XYZ2RGBFunctor< T >::result_type value_type
Definition: colorconversions.hxx:1752
vigra::yPrimeUV2Polar
TinyVector< float, 3 > yPrimeUV2Polar(V const &yuv)
Create polar representation form Y'UV.
Definition: colorconversions.hxx:3402
vigra::RGB2sRGBFunctor::value_type
TinyVector< To, 3 > value_type
Definition: colorconversions.hxx:419
vigra::Lab2XYZFunctor::Lab2XYZFunctor
Lab2XYZFunctor()
Definition: colorconversions.hxx:1425
vigra::XYZ2LabFunctor::result_type
TinyVector< component_type, 3 > result_type
Definition: colorconversions.hxx:1342
vigra::YPrimeIQ2RGBPrimeFunctor::YPrimeIQ2RGBPrimeFunctor
YPrimeIQ2RGBPrimeFunctor(component_type max)
Definition: colorconversions.hxx:2441
vigra::YPrimeCbCr2RGBPrimeFunctor
Convert Y'CbCr color difference components into non-linear (gamma corrected) R'G'B'.
Definition: colorconversions.hxx:2765
vigra::XYZ2LabFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:1338
vigra::YPrimeIQ2RGBPrimeFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:2421
vigra::RGBPrime2YPrimeCbCrFunctor::RGBPrime2YPrimeCbCrFunctor
RGBPrime2YPrimeCbCrFunctor(component_type max)
Definition: colorconversions.hxx:2715
vigra::RGB2XYZFunctor::value_type
TinyVector< component_type, 3 > value_type
Definition: colorconversions.hxx:806
vigra::Lab2RGBPrimeFunctor::value_type
XYZ2RGBFunctor< T >::result_type value_type
Definition: colorconversions.hxx:2068
vigra::YPrimeIQ2RGBPrimeFunctor
Convert Y'IQ color components into non-linear (gamma corrected) R'G'B'.
Definition: colorconversions.hxx:2409
vigra::sRGB2RGBFunctor::operator()
result_type operator()(argument_type const &rgb) const
Definition: colorconversions.hxx:694
vigra::RGBPrime2LuvFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:1827
vigra::luv2Polar
TinyVector< float, 3 > luv2Polar(V const &luv)
Create polar representation form L*u*v*.
Definition: colorconversions.hxx:3060
vigra::Luv2XYZFunctor::operator()
result_type operator()(V const &luv) const
Definition: colorconversions.hxx:1255
vigra::YPrimeUV2RGBPrimeFunctor::value_type
TinyVector< T, 3 > value_type
Definition: colorconversions.hxx:2612
vigra::RGBPrime2YPrimeIQFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:2339
vigra::RGB2LuvFunctor
Convert linear (raw) RGB into perceptual uniform CIE L*u*v*.
Definition: colorconversions.hxx:1494
vigra::YPrimePbPr2RGBPrimeFunctor::YPrimePbPr2RGBPrimeFunctor
YPrimePbPr2RGBPrimeFunctor(component_type max)
Definition: colorconversions.hxx:2258
vigra::RGBPrime2XYZFunctor::RGBPrime2XYZFunctor
RGBPrime2XYZFunctor(component_type max)
Definition: colorconversions.hxx:903
vigra::Luv2XYZFunctor::value_type
TinyVector< component_type, 3 > value_type
Definition: colorconversions.hxx:1245
vigra::YPrimeUV2RGBPrimeFunctor::operator()
result_type operator()(V const &yuv) const
Definition: colorconversions.hxx:2631
vigra::RGB2LuvFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:1511
vigra::Luv2XYZFunctor
Convert perceptual uniform CIE L*u*v* into standardized tri-stimulus XYZ.
Definition: colorconversions.hxx:1227
vigra::XYZ2LuvFunctor::component_type
NumericTraits< T >::RealPromote component_type
Definition: colorconversions.hxx:1151
vigra::YPrimeUV2RGBPrimeFunctor
Convert Y'UV color components into non-linear (gamma corrected) R'G'B'.
Definition: colorconversions.hxx:2592
vigra::RGBPrime2YPrimeCbCrFunctor
Convert non-linear (gamma corrected) R'G'B' into Y'CbCr color difference components.
Definition: colorconversions.hxx:2678
vigra::polar2Lab
TinyVector< float, 3 > polar2Lab(double color, double brightness, double saturation)
Init L*a*b* color triple from polar representation.
Definition: colorconversions.hxx:2937
vigra::RGBPrime2YPrimeUVFunctor
Convert non-linear (gamma corrected) R'G'B' into Y'UV components.
Definition: colorconversions.hxx:2505
vigra::sRGB2RGBFunctor::result_type
TinyVector< To, 3 > result_type
Definition: colorconversions.hxx:668
vigra::polar2YPrimeCbCr
TinyVector< float, 3 > polar2YPrimeCbCr(double color, double brightness, double saturation)
Init Y'CbCr color triple from polar representation.
Definition: colorconversions.hxx:3193
vigra::RGBPrime2YPrimeIQFunctor::operator()
result_type operator()(V const &rgb) const
Definition: colorconversions.hxx:2366
vigra::RGBPrime2XYZFunctor::operator()
result_type operator()(argument_type const &rgb) const
Definition: colorconversions.hxx:909
vigra::RGBPrime2YPrimeIQFunctor::component_type
NumericTraits< T >::RealPromote component_type
Definition: colorconversions.hxx:2335
vigra::YPrimeCbCr2RGBPrimeFunctor::YPrimeCbCr2RGBPrimeFunctor
YPrimeCbCr2RGBPrimeFunctor(component_type max)
Definition: colorconversions.hxx:2797
vigra::XYZ2LabFunctor::operator()
result_type operator()(V const &xyz) const
Definition: colorconversions.hxx:1357
vigra::Lab2RGBFunctor::Lab2RGBFunctor
Lab2RGBFunctor()
Definition: colorconversions.hxx:1757
vigra::RGBPrime2YPrimeUVFunctor::result_type
TinyVector< component_type, 3 > result_type
Definition: colorconversions.hxx:2526
vigra::linalg::cos
linalg::TemporaryMatrix< T > cos(MultiArrayView< 2, T, C > const &v)
vigra::XYZ2LuvFunctor
Convert standardized tri-stimulus XYZ into perceptual uniform CIE L*u*v*.
Definition: colorconversions.hxx:1145
vigra::RGBPrime2XYZFunctor::component_type
NumericTraits< T >::RealPromote component_type
Definition: colorconversions.hxx:879
vigra::RGBPrime2YPrimeIQFunctor::RGBPrime2YPrimeIQFunctor
RGBPrime2YPrimeIQFunctor(component_type max)
Definition: colorconversions.hxx:2359
vigra::RGBPrime2RGBFunctor::result_type
TinyVector< To, 3 > result_type
Definition: colorconversions.hxx:540
vigra::Luv2RGBPrimeFunctor::operator()
result_type operator()(V const &luv) const
Definition: colorconversions.hxx:2016
vigra::XYZ2RGBPrimeFunctor::value_type
TinyVector< T, 3 > value_type
Definition: colorconversions.hxx:1067
vigra::XYZ2RGBFunctor
Convert standardized tri-stimulus XYZ into linear (raw) RGB.
Definition: colorconversions.hxx:963
vigra::sqrt
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root.
Definition: fixedpoint.hxx:616
vigra::Lab2RGBPrimeFunctor::operator()
result_type operator()(V const &lab) const
Definition: colorconversions.hxx:2087
vigra::Luv2RGBFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:1679
vigra::XYZ2LabFunctor::component_type
NumericTraits< T >::RealPromote component_type
Definition: colorconversions.hxx:1334
vigra::RGBPrime2LabFunctor::RGBPrime2LabFunctor
RGBPrime2LabFunctor()
Definition: colorconversions.hxx:1927
vigra::Lab2RGBPrimeFunctor::result_type
XYZ2RGBFunctor< T >::result_type result_type
Definition: colorconversions.hxx:2064
vigra::RGB2LuvFunctor::result_type
XYZ2LuvFunctor< component_type >::result_type result_type
Definition: colorconversions.hxx:1515
vigra::RGB2XYZFunctor::result_type
TinyVector< component_type, 3 > result_type
Definition: colorconversions.hxx:802
vigra::Luv2XYZFunctor::argument_type
TinyVector< T, 3 > argument_type
Definition: colorconversions.hxx:1237
vigra::XYZ2RGBFunctor::value_type
TinyVector< T, 3 > value_type
Definition: colorconversions.hxx:982

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.11.0 (Thu Mar 17 2016)