/**
* @file colorspace.c
* @author Pascal Getreuer 2005-2010 <getreuer@gmail.com>
*
* == Summary ==
* This file implements routines for color transformations between the spaces
* sRGB, Y'UV, Y'CbCr, Y'PbPr, Y'DbDr, Y'IQ, HSV, HSL, HSI, CIEXYZ, CIELAB,
* CIELUV, CIELCH, and CIECAT02 LMS.
*
* == Usage ==
* First call GetColorTransform, specifying the source and destination color
* spaces as "dest<-src" or "src->dest". Then call ApplyColorTransform to
* perform the transform:
@code
num S[3] = {173, 0.8, 0.5};
num D[3];
colortransform Trans;
if(!(GetColorTransform(&Trans, "HSI -> Lab")))
{
printf("Invalid syntax or unknown color space\n");
return;
}
ApplyColorTransform(Trans, &D[0], &D[1], &D[2], S[0], S[1], S[2]);
@endcode
* "num" is a typedef defined at the beginning of colorspace.h that may be set
* to either double or float, depending on the application.
*
* Specific transformation routines can also be called directly. The following
* converts an sRGB color to CIELAB and then back to sRGB:
@code
num R = 0.85, G = 0.32, B = 0.5;
num L, a, b;
Rgb2Lab(&L, &a, &b, R, G, B);
Lab2Rgb(&R, &G, &B, L, a, b);
@endcode
* Generally, the calling syntax is
@code
Foo2Bar(&B0, &B1, &B2, F0, F1, F2);
@endcode
* where (F0,F1,F2) are the coordinates of a color in space "Foo" and
* (B0,B1,B2) are the transformed coordinates in space "Bar." For any
* transformation routine, its inverse has the sytax
@code
Bar2Foo(&F0, &F1, &F2, B0, B1, B2);
@endcode
*
* The conversion routines are consistently named with the first letter of a
* color space capitalized with following letters in lower case and omitting
* prime symbols. For example, "Rgb2Ydbdr" converts sRGB to Y'DbDr. For
* any transformation routine Foo2Bar, its inverse is Bar2Foo.
*
* All transformations assume a two degree observer angle and a D65 illuminant.
* The white point can be changed by modifying the WHITEPOINT_X, WHITEPOINT_Y,
* WHITEPOINT_Z definitions at the beginning of colorspace.h.
*
* == List of transformation routines ==
* - Rgb2Yuv(num *Y, num *U, num *V, num R, num G, num B)
* - Rgb2Ycbcr(num *Y, num *Cb, num *Cr, num R, num G, num B)
* - Rgb2Jpegycbcr(num *Y, num *Cb, num *Cr, num R, num G, num B)
* - Rgb2Ypbpr(num *Y, num *Pb, num *Pr, num R, num G, num B)
* - Rgb2Ydbdr(num *Y, num *Db, num *Dr, num R, num G, num B)
* - Rgb2Yiq(num *Y, num *I, num *Q, num R, num G, num B)
* - Rgb2Hsv(num *H, num *S, num *V, num R, num G, num B)
* - Rgb2Hsl(num *H, num *S, num *L, num R, num G, num B)
* - Rgb2Hsi(num *H, num *S, num *I, num R, num G, num B)
* - Rgb2Xyz(num *X, num *Y, num *Z, num R, num G, num B)
* - Xyz2Lab(num *L, num *a, num *b, num X, num Y, num Z)
* - Xyz2Luv(num *L, num *u, num *v, num X, num Y, num Z)
* - Xyz2Lch(num *L, num *C, num *h, num X, num Y, num Z)
* - Xyz2Cat02lms(num *L, num *M, num *S, num X, num Y, num Z)
* - Rgb2Lab(num *L, num *a, num *b, num R, num G, num B)
* - Rgb2Luv(num *L, num *u, num *v, num R, num G, num B)
* - Rgb2Lch(num *L, num *C, num *h, num R, num G, num B)
* - Rgb2Cat02lms(num *L, num *M, num *S, num R, num G, num B)
* (Similarly for the inverse transformations.)
*
* It is possible to transform between two arbitrary color spaces by first
* transforming from the source space to sRGB and then transforming from
* sRGB to the desired destination space. For transformations between CIE
* color spaces, it is convenient to use XYZ as the intermediate space. This
* is the strategy used by GetColorTransform and ApplyColorTransform.
*
* == References ==
* The definitions of these spaces and the many of the transformation formulas
* can be found in
*
* Poynton, "Frequently Asked Questions About Gamma"
* http://www.poynton.com/notes/colour_and_gamma/GammaFAQ.html
*
* Poynton, "Frequently Asked Questions About Color"
* http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html
*
* and Wikipedia articles
* http://en.wikipedia.org/wiki/SRGB
* http://en.wikipedia.org/wiki/YUV
* http://en.wikipedia.org/wiki/YCbCr
* http://en.wikipedia.org/wiki/YPbPr
* http://en.wikipedia.org/wiki/YDbDr
* http://en.wikipedia.org/wiki/YIQ
* http://en.wikipedia.org/wiki/HSL_and_HSV
* http://en.wikipedia.org/wiki/CIE_1931_color_space
* http://en.wikipedia.org/wiki/Lab_color_space
* http://en.wikipedia.org/wiki/CIELUV_color_space
* http://en.wikipedia.org/wiki/LMS_color_space
*
* == License (BSD) ==
* Copyright (c) 2005-2010, Pascal Getreuer
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "colorspace.h"
#ifdef MATLAB_MEX_FILE
#include "mex.h"
#endif
/** @brief Min of A and B */
#define MIN(A,B) (((A) <= (B)) ? (A) : (B))
/** @brief Max of A and B */
#define MAX(A,B) (((A) >= (B)) ? (A) : (B))
/** @brief Min of A, B, and C */
#define MIN3(A,B,C) (((A) <= (B)) ? MIN(A,C) : MIN(B,C))
/** @brief Max of A, B, and C */
#define MAX3(A,B,C) (((A) >= (B)) ? MAX(A,C) : MAX(B,C))
#ifndef M_PI
/** @brief The constant pi */
#define M_PI 3.14159265358979323846264338327950288
#endif
/**
* @brief sRGB gamma correction, transforms R to R'
* http://en.wikipedia.org/wiki/SRGB
*/
#define GAMMACORRECTION(t) \
(((t) <= 0.0031306684425005883) ? \
(12.92*(t)) : (1.055*pow((t), 0.416666666666666667) - 0.055))
/**
* @brief Inverse sRGB gamma correction, transforms R' to R
*/
#define INVGAMMACORRECTION(t) \
(((t) <= 0.0404482362771076) ? \
((t)/12.92) : pow(((t) + 0.055)/1.055, 2.4))
/**
* @brief CIE L*a*b* f function (used to convert XYZ to L*a*b*)
* http://en.wikipedia.org/wiki/Lab_color_space
*/
#define LABF(t) \
((t >= 8.85645167903563082e-3) ? \
pow(t,0.333333333333333) : (841.0/108.0)*(t) + (4.0/29.0))
/**
* @brief CIE L*a*b* inverse f function
* http://en.wikipedia.org/wiki/Lab_color_space
*/
#define LABINVF(t) \
((t >= 0.206896551724137931) ? \
((t)*(t)*(t)) : (108.0/841.0)*((t) - (4.0/29.0)))
/** @brief u'v' coordinates of the white point for CIE Lu*v* */
#define WHITEPOINT_U ((4*WHITEPOINT_X) \
/(WHITEPOINT_X + 15*WHITEPOINT_Y + 3*WHITEPOINT_Z))
#define WHITEPOINT_V ((9*WHITEPOINT_Y) \
/(WHITEPOINT_X + 15*WHITEPOINT_Y + 3*WHITEPOINT_Z))
/** @brief Enumeration of the supported color spaces */
#define UNKNOWN_SPACE 0
#define RGB_SPACE 1
#define YUV_SPACE 2
#define YCBCR_SPACE 3
#define JPEGYCBCR_SPACE 4
#define YPBPR_SPACE 5
#define YDBDR_SPACE 6
#define YIQ_SPACE 7
#define HSV_SPACE 8
#define HSL_SPACE 9
#define HSI_S
colorspace Converting between RGB, YUV, HSV, CIE Lab
5星 · 超过95%的资源 需积分: 9 49 浏览量
2011-04-22
18:25:16
上传
评论
收藏 65KB ZIP 举报
xslai
- 粉丝: 0
- 资源: 9
- 1
- 2
前往页