2021-05-23 23:16:36 +02:00
|
|
|
#include "xfr.h"
|
|
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <sstream>
|
2021-12-22 21:00:11 +01:00
|
|
|
#include <cmath>
|
2021-05-23 23:16:36 +02:00
|
|
|
|
|
|
|
|
namespace image
|
|
|
|
|
{
|
|
|
|
|
namespace xfr
|
|
|
|
|
{
|
|
|
|
|
XFR::XFR(float r1, float r2, float r3, float g1, float g2, float g3, float b1, float b2, float b3)
|
|
|
|
|
{
|
|
|
|
|
// Red values
|
|
|
|
|
R[0] = r1;
|
|
|
|
|
R[1] = r2;
|
|
|
|
|
R[2] = 1.0f / (r3 / 100.0f);
|
|
|
|
|
|
|
|
|
|
// Green values
|
|
|
|
|
G[0] = g1;
|
|
|
|
|
G[1] = g2;
|
|
|
|
|
G[2] = 1.0f / (g3 / 100.0f);
|
|
|
|
|
|
|
|
|
|
// Blue values
|
|
|
|
|
B[0] = b1;
|
|
|
|
|
B[1] = b2;
|
|
|
|
|
B[2] = 1.0f / (b3 / 100.0f);
|
|
|
|
|
|
|
|
|
|
// Generate LUTs
|
|
|
|
|
for (int i = 0; i < 1024; i++)
|
|
|
|
|
{
|
|
|
|
|
if (i < R[0])
|
|
|
|
|
{
|
|
|
|
|
red_lut[i] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
else if (i > R[1])
|
|
|
|
|
{
|
|
|
|
|
red_lut[i] = 1023.0f;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
red_lut[i] = ((powf((i - R[0]) / (R[1] - R[0]), R[2]) * (R[1] - R[0])) + R[0]) * 1023.0f / R[1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (i < G[0])
|
|
|
|
|
{
|
|
|
|
|
green_lut[i] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
else if (i > G[1])
|
|
|
|
|
{
|
|
|
|
|
green_lut[i] = 1023.0f;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
green_lut[i] = ((powf((i - G[0]) / (G[1] - G[0]), G[2]) * (G[1] - G[0])) + G[0]) * 1023.0f / G[1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (i < B[0])
|
|
|
|
|
{
|
|
|
|
|
blue_lut[i] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
else if (i > B[1])
|
|
|
|
|
{
|
|
|
|
|
blue_lut[i] = 1023.0f;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
blue_lut[i] = ((powf((i - B[0]) / (B[1] - B[0]), B[2]) * (B[1] - B[0])) + B[0]) * 1023.0f / B[1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-22 21:00:11 +01:00
|
|
|
void applyXFR(XFR &xfr, Image<uint16_t> &r, Image<uint16_t> &g, Image<uint16_t> &b)
|
2021-05-23 23:16:36 +02:00
|
|
|
{
|
|
|
|
|
// Apply XFR
|
2022-05-12 18:19:01 +02:00
|
|
|
for (size_t i = 0; i < r.height() * r.width(); i++)
|
2021-05-23 23:16:36 +02:00
|
|
|
{
|
|
|
|
|
unsigned short ¤tR = r.data()[i];
|
|
|
|
|
unsigned short ¤tG = g.data()[i];
|
|
|
|
|
unsigned short ¤tB = b.data()[i];
|
|
|
|
|
|
|
|
|
|
currentR /= 60.0f;
|
|
|
|
|
currentG /= 60.0f;
|
|
|
|
|
currentB /= 60.0f;
|
|
|
|
|
|
|
|
|
|
currentR = xfr.red_lut[currentR] * 60.0f;
|
|
|
|
|
currentG = xfr.green_lut[currentG] * 60.0f;
|
|
|
|
|
currentB = xfr.blue_lut[currentB] * 60.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-22 21:00:11 +01:00
|
|
|
void applyXFR(XFR &xfr, Image<uint16_t> &image)
|
2021-09-30 17:33:32 +02:00
|
|
|
{
|
|
|
|
|
// Apply XFR
|
2022-05-12 18:19:01 +02:00
|
|
|
for (size_t i = 0; i < image.height() * image.width(); i++)
|
2021-09-30 17:33:32 +02:00
|
|
|
{
|
|
|
|
|
unsigned short ¤tR = image.data()[image.height() * image.width() * 0 + i];
|
|
|
|
|
unsigned short ¤tG = image.data()[image.height() * image.width() * 1 + i];
|
|
|
|
|
unsigned short ¤tB = image.data()[image.height() * image.width() * 2 + i];
|
|
|
|
|
|
|
|
|
|
currentR /= 60.0f;
|
|
|
|
|
currentG /= 60.0f;
|
|
|
|
|
currentB /= 60.0f;
|
|
|
|
|
|
|
|
|
|
currentR = xfr.red_lut[currentR] * 60.0f;
|
|
|
|
|
currentG = xfr.green_lut[currentG] * 60.0f;
|
|
|
|
|
currentB = xfr.blue_lut[currentB] * 60.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-23 23:16:36 +02:00
|
|
|
XFR loadXFRFromFile(std::string path)
|
|
|
|
|
{
|
|
|
|
|
std::ifstream xfrFile(path);
|
|
|
|
|
|
|
|
|
|
std::string currentLine;
|
|
|
|
|
int lineCount = 0;
|
|
|
|
|
|
|
|
|
|
float r1 = 0, r2 = 0, r3 = 0;
|
|
|
|
|
float g1 = 0, g2 = 0, g3 = 0;
|
|
|
|
|
float b1 = 0, b2 = 0, b3 = 0;
|
|
|
|
|
|
|
|
|
|
while (std::getline(xfrFile, currentLine))
|
|
|
|
|
{
|
|
|
|
|
std::vector<std::string> values;
|
|
|
|
|
std::string seg;
|
|
|
|
|
std::stringstream line(currentLine);
|
|
|
|
|
|
|
|
|
|
while (std::getline(line, seg, ' '))
|
|
|
|
|
values.push_back(seg);
|
|
|
|
|
|
|
|
|
|
if (lineCount == 1)
|
|
|
|
|
{
|
|
|
|
|
r1 = std::stof(values[1]);
|
|
|
|
|
r2 = std::stof(values[2]);
|
|
|
|
|
r3 = std::stof(values[3]);
|
|
|
|
|
}
|
|
|
|
|
else if (lineCount == 2)
|
|
|
|
|
{
|
|
|
|
|
g1 = std::stof(values[1]);
|
|
|
|
|
g2 = std::stof(values[2]);
|
|
|
|
|
g3 = std::stof(values[3]);
|
|
|
|
|
}
|
|
|
|
|
else if (lineCount == 3)
|
|
|
|
|
{
|
|
|
|
|
b1 = std::stof(values[1]);
|
|
|
|
|
b2 = std::stof(values[2]);
|
|
|
|
|
b3 = std::stof(values[3]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lineCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xfrFile.close();
|
|
|
|
|
|
|
|
|
|
return XFR(r1, r2, r3, g1, g2, g3, b1, b2, b3);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|