Skip to content

Commit

Permalink
conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
gywn committed Nov 14, 2017
1 parent 4211b58 commit 8d89579
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 70 deletions.
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ project(color)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_library(CIEDE2000 SHARED src/CIEDE2000.cpp)
target_include_directories(CIEDE2000 PUBLIC include)
add_library(color SHARED src/color.cpp src/conversion.cpp src/CIEDE2000.cpp)
target_include_directories(color PUBLIC include)

add_executable(testCIEDE2000 test/testCIEDE2000.cpp)
target_link_libraries(testCIEDE2000 CIEDE2000)
target_link_libraries(testCIEDE2000 color)
63 changes: 8 additions & 55 deletions include/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,13 @@
#define M_PI 3.14159265358979323846264338327950288 /* pi */
#endif

/** Namespace containing all necessary objects and methods for color */
namespace color {
/***********************************************************************
* Types.
**********************************************************************/

/** A color in CIELAB colorspace */
struct LAB {
/** Lightness */
double l;
/** Color-opponent a dimension */
double a;
/** Color-opponent b dimension */
double b;
};
/** Convenience definition for struct LAB */
using LAB = struct LAB;

/** A color in CIEXYZ colorspace */
Expand All @@ -37,7 +28,6 @@ struct XYZ {
double y;
double z;
};
/** Convenience definition for struct XYZ */
using XYZ = struct XYZ;

/** A color in CIERGB colorspace */
Expand All @@ -46,13 +36,8 @@ struct RGB {
double g;
double b;
};
/** Convenience definition for struct RGB */
using RGB = struct RGB;

/***********************************************************************
* Operations.
**********************************************************************/

/**
* @brief
* Obtain Delta-E 2000 value.
Expand All @@ -72,51 +57,19 @@ using RGB = struct RGB;
*/
double CIEDE2000(const LAB &lab1, const LAB &lab2);

/***********************************************************************
* Conversions.
**********************************************************************/

/**
* @brief
* Convert degrees to radians.
*
* @param deg
* Angle in degrees.
*
* @return
* deg in radians.
*/
constexpr double deg2Rad(const double deg);

/**
* @brief
* Convert radians to degrees.
*
* @param rad
* Angle in radians.
*
* @return
* rad in degrees.
*/
constexpr double rad2Deg(const double rad);

/*******************************************************************************
* Conversions.
******************************************************************************/
RGB XYZtoRGB(const XYZ &xyz);
XYZ LABtoXYZ(const LAB &lab);
RGB LABtoRGB(const LAB &lab);

bool offRGB(const LAB &lab);

} // namespace color
/**
* @brief
* LAB output stream operator.
*
* @param s
* Output stream.
* @param labColor
* Color to output.
*
* @return
* s with labColor appended.
*/

std::ostream &operator<<(std::ostream &s, const color::LAB &labColor);
std::ostream &operator<<(std::ostream &s, const color::XYZ &labColor);
std::ostream &operator<<(std::ostream &s, const color::RGB &labColor);

#endif /* GPF_COLOR_H_ */
22 changes: 22 additions & 0 deletions include/constant.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef ICC_CONSTANT_H_
#define ICC_CONSTANT_H_

namespace color {
/* ICC's PCS illuminant */
const double PCS_X = 31595. / 32768.;
const double PCS_Y = 1;
const double PCS_Z = 27030. / 32768.;

/* Macbook's LCD color profile for XYZ -> RGB */
const double A11 = 3.98875596;
const double A12 = -2.41598659;
const double A13 = -0.52021109;
const double A21 = -1.40052984;
const double A22 = 2.37728799;
const double A23 = -0.03294208;
const double A31 = -0.03269638;
const double A32 = -0.18259425;
const double A33 = 1.4716528;
} // namespace color

#endif /* ICC_CONSTANT_H_ */
11 changes: 1 addition & 10 deletions src/CIEDE2000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,4 @@ double color::CIEDE2000(const LAB &lab1, const LAB &lab2) {
(R_T * (deltaCPrime / (k_C * S_C)) * (deltaHPrime / (k_H * S_H))));

return (deltaE);
}

/*******************************************************************************
* Operators.
******************************************************************************/

std::ostream &operator<<(std::ostream &s, const color::LAB &labColor) {
return (s << "CIELAB(" << labColor.l << "," << labColor.a << "," << labColor.b
<< ")");
}
}
13 changes: 13 additions & 0 deletions src/color.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <color.h>

std::ostream &operator<<(std::ostream &s, const color::LAB &lab) {
return (s << "LAB(" << lab.l << "," << lab.a << "," << lab.b << ")");
}

std::ostream &operator<<(std::ostream &s, const color::XYZ &xyz) {
return (s << "XYZ(" << xyz.x << "," << xyz.y << "," << xyz.z << ")");
}

std::ostream &operator<<(std::ostream &s, const color::RGB &rgb) {
return (s << "RGB(" << rgb.r << "," << rgb.g << "," << rgb.b << ")");
}
47 changes: 47 additions & 0 deletions src/conversion.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#define _USE_MATH_DEFINES
#include <cmath>
#include <color.h>
#include <constant.h>

namespace color {
double sgn(double val) { return (0. < val) - (val < 0.); }
constexpr inline double pow3(double x) { return x * x * x; }

RGB XYZtoRGB(const XYZ &xyz) {
double r = xyz.x * A11 + xyz.y * A12 + xyz.z * A13;
double g = xyz.x * A21 + xyz.y * A22 + xyz.z * A23;
double b = xyz.x * A31 + xyz.y * A32 + xyz.z * A33;

r = ((abs(r) > 0.0031308) ? sgn(r) * (1.055 * pow(abs(r), 1 / 2.4) - 0.055) : (12.92 * r));
g = ((abs(g) > 0.0031308) ? sgn(g) * (1.055 * pow(abs(g), 1 / 2.4) - 0.055) : (12.92 * g));
b = ((abs(b) > 0.0031308) ? sgn(b) * (1.055 * pow(abs(b), 1 / 2.4) - 0.055) : (12.92 * b));

return RGB{r, g, b};
}

XYZ LABtoXYZ(const LAB &lab) {
double y = (lab.l + 16.0) / 116.0;
double x = lab.a / 500.0 + y;
double z = y - lab.b / 200.0;

double x3 = pow3(x);
double y3 = pow3(y);
double z3 = pow3(z);

x = ((x3 > 0.008856) ? x3 : ((x - 16.0 / 116.0) / 7.787)) * PCS_X;
y = ((y3 > 0.008856) ? y3 : ((y - 16.0 / 116.0) / 7.787)) * PCS_Y;
z = ((z3 > 0.008856) ? z3 : ((z - 16.0 / 116.0) / 7.787)) * PCS_Z;

return XYZ{x, y, z};
}

RGB LABtoRGB(const LAB &lab) { return XYZtoRGB(LABtoXYZ(lab)); }

bool offRGB(const LAB &lab) {
const RGB rgb{LABtoRGB(lab)};

return rgb.r >= 0 && rgb.r <= 1 && rgb.g >= 0 && rgb.g <= 1 && rgb.b >= 0 &&
rgb.b <= 1;
}

} // namespace color
32 changes: 30 additions & 2 deletions test/testCIEDE2000.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* See LICENSE for details.
*/

#include <cmath>
#include <iostream>
#include <string>
#include <vector>
Expand All @@ -23,11 +24,38 @@ int main(int argc, char *argv[]) { return (testcolor()); }

int testcolor() {
color::LAB lab1, lab2;
double expectedResult, myResult;
color::RGB rgb1, rgb_expected;
unsigned int line = 1;
std::vector<bool> passFail;

lab1 = {100, 0, 0};
rgb1 = color::LABtoRGB(lab1);
rgb_expected = {1, 1, 1};

passFail.push_back(std::abs(rgb1.r - rgb_expected.r) < 1e-3);
std::cout << line << ": " << rgb1.r << " vs " << rgb_expected.r << '\t'
<< (passFail[line - 1] ? "PASS" : "FAIL") << std::endl;
++line;

passFail.push_back(std::abs(rgb1.g - rgb_expected.g) < 1e-3);
std::cout << line << ": " << rgb1.g << " vs " << rgb_expected.g << '\t'
<< (passFail[line - 1] ? "PASS" : "FAIL") << std::endl;
++line;

passFail.push_back(std::abs(rgb1.b - rgb_expected.b) < 1e-3);
std::cout << line << ": " << rgb1.b << " vs " << rgb_expected.b << '\t'
<< (passFail[line - 1] ? "PASS" : "FAIL") << std::endl;
++line;

std::cout << color::LABtoRGB(color::LAB{50, 0, 0}) << std::endl;
std::cout << color::LABtoRGB(color::LAB{50, 1000, 0}) << std::endl;
std::cout << color::LABtoRGB(color::LAB{50, -1000, 0}) << std::endl;
std::cout << color::LABtoRGB(color::LAB{50, 0, 1000}) << std::endl;
std::cout << color::LABtoRGB(color::LAB{50, 0, -1000}) << std::endl;

double expectedResult, myResult;
char myBuffer[64], expectedBuffer[64];
std::string myStr, expectedStr;
std::vector<bool> passFail;

lab1 = {50.0000, 2.6772, -79.7751};
lab2 = {50.0000, 0.0000, -82.7485};
Expand Down

0 comments on commit 8d89579

Please sign in to comment.