satdump/src-core/common/image/xfr.cpp
2022-05-12 18:19:01 +02:00

158 lines
No EOL
4.6 KiB
C++

#include "xfr.h"
#include <fstream>
#include <vector>
#include <sstream>
#include <cmath>
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];
}
}
}
void applyXFR(XFR &xfr, Image<uint16_t> &r, Image<uint16_t> &g, Image<uint16_t> &b)
{
// Apply XFR
for (size_t i = 0; i < r.height() * r.width(); i++)
{
unsigned short &currentR = r.data()[i];
unsigned short &currentG = g.data()[i];
unsigned short &currentB = 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;
}
}
void applyXFR(XFR &xfr, Image<uint16_t> &image)
{
// Apply XFR
for (size_t i = 0; i < image.height() * image.width(); i++)
{
unsigned short &currentR = image.data()[image.height() * image.width() * 0 + i];
unsigned short &currentG = image.data()[image.height() * image.width() * 1 + i];
unsigned short &currentB = 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;
}
}
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);
}
}
}