mirror of
https://github.com/LNH-team/pico-launcher.git
synced 2026-06-02 09:06:54 +02:00
Initial commit
This commit is contained in:
173
arm9/source/material/utils/utils.cpp
Normal file
173
arm9/source/material/utils/utils.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "material/utils/utils.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
// #include "absl/strings/str_cat.h"
|
||||
|
||||
namespace material_color_utilities {
|
||||
|
||||
int RedFromInt(const Argb argb) { return (argb & 0x00ff0000) >> 16; }
|
||||
|
||||
int GreenFromInt(const Argb argb) { return (argb & 0x0000ff00) >> 8; }
|
||||
|
||||
int BlueFromInt(const Argb argb) { return (argb & 0x000000ff); }
|
||||
|
||||
Argb ArgbFromRgb(const int red, const int green, const int blue) {
|
||||
return 0xFF000000 | ((red & 0xff) << 16) | ((green & 0xff) << 8) |
|
||||
(blue & 0xff);
|
||||
}
|
||||
|
||||
// Converts a color from linear RGB components to ARGB format.
|
||||
Argb ArgbFromLinrgb(Vec3 linrgb) {
|
||||
int r = Delinearized(linrgb.a);
|
||||
int g = Delinearized(linrgb.b);
|
||||
int b = Delinearized(linrgb.c);
|
||||
|
||||
return 0xFF000000 | ((r & 0x0ff) << 16) | ((g & 0x0ff) << 8) | (b & 0x0ff);
|
||||
}
|
||||
|
||||
int Delinearized(const double rgb_component) {
|
||||
double normalized = rgb_component / 100;
|
||||
double delinearized;
|
||||
if (normalized <= 0.0031308) {
|
||||
delinearized = normalized * 12.92;
|
||||
} else {
|
||||
delinearized = 1.055 * std::pow(normalized, 1.0 / 2.4) - 0.055;
|
||||
}
|
||||
return std::clamp((int)round(delinearized * 255.0), 0, 255);
|
||||
}
|
||||
|
||||
double Linearized(const int rgb_component) {
|
||||
double normalized = rgb_component / 255.0;
|
||||
if (normalized <= 0.040449936) {
|
||||
return normalized / 12.92 * 100.0;
|
||||
} else {
|
||||
return std::pow((normalized + 0.055) / 1.055, 2.4) * 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
int AlphaFromInt(Argb argb) { return (argb & 0xff000000) >> 24; }
|
||||
|
||||
bool IsOpaque(Argb argb) { return AlphaFromInt(argb) == 255; }
|
||||
|
||||
double LstarFromArgb(Argb argb) {
|
||||
// xyz from argb
|
||||
int red = (argb & 0x00ff0000) >> 16;
|
||||
int green = (argb & 0x0000ff00) >> 8;
|
||||
int blue = (argb & 0x000000ff);
|
||||
double red_l = Linearized(red);
|
||||
double green_l = Linearized(green);
|
||||
double blue_l = Linearized(blue);
|
||||
double y = 0.2126 * red_l + 0.7152 * green_l + 0.0722 * blue_l;
|
||||
return LstarFromY(y);
|
||||
}
|
||||
|
||||
double YFromLstar(double lstar) {
|
||||
static const double ke = 8.0;
|
||||
if (lstar > ke) {
|
||||
double cube_root = (lstar + 16.0) / 116.0;
|
||||
double cube = cube_root * cube_root * cube_root;
|
||||
return cube * 100.0;
|
||||
} else {
|
||||
return lstar / (24389.0 / 27.0) * 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
double LstarFromY(double y) {
|
||||
static const double e = 216.0 / 24389.0;
|
||||
double yNormalized = y / 100.0;
|
||||
if (yNormalized <= e) {
|
||||
return (24389.0 / 27.0) * yNormalized;
|
||||
} else {
|
||||
return 116.0 * std::pow(yNormalized, 1.0 / 3.0) - 16.0;
|
||||
}
|
||||
}
|
||||
|
||||
int SanitizeDegreesInt(const int degrees) {
|
||||
if (degrees < 0) {
|
||||
return (degrees % 360) + 360;
|
||||
} else if (degrees >= 360.0) {
|
||||
return degrees % 360;
|
||||
} else {
|
||||
return degrees;
|
||||
}
|
||||
}
|
||||
|
||||
// Sanitizes a degree measure as a floating-point number.
|
||||
//
|
||||
// Returns a degree measure between 0.0 (inclusive) and 360.0 (exclusive).
|
||||
double SanitizeDegreesDouble(const double degrees) {
|
||||
if (degrees < 0.0) {
|
||||
return fmod(degrees, 360.0) + 360;
|
||||
} else if (degrees >= 360.0) {
|
||||
return fmod(degrees, 360.0);
|
||||
} else {
|
||||
return degrees;
|
||||
}
|
||||
}
|
||||
|
||||
double DiffDegrees(const double a, const double b) {
|
||||
return 180.0 - abs(abs(a - b) - 180.0);
|
||||
}
|
||||
|
||||
double RotationDirection(const double from, const double to) {
|
||||
double increasing_difference = SanitizeDegreesDouble(to - from);
|
||||
return increasing_difference <= 180.0 ? 1.0 : -1.0;
|
||||
}
|
||||
|
||||
// Converts a color in ARGB format to a hexadecimal string in lowercase.
|
||||
//
|
||||
// For instance: hex_from_argb(0xff012345) == "ff012345"
|
||||
// std::string HexFromArgb(Argb argb) { return absl::StrCat(absl::Hex(argb)); }
|
||||
|
||||
Argb IntFromLstar(const double lstar) {
|
||||
double y = YFromLstar(lstar);
|
||||
int component = Delinearized(y);
|
||||
return ArgbFromRgb(component, component, component);
|
||||
}
|
||||
|
||||
// The signum function.
|
||||
//
|
||||
// Returns 1 if num > 0, -1 if num < 0, and 0 if num = 0
|
||||
int Signum(double num) {
|
||||
if (num < 0) {
|
||||
return -1;
|
||||
} else if (num == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
Vec3 MatrixMultiply(Vec3 input, const double matrix[3][3]) {
|
||||
double a =
|
||||
input.a * matrix[0][0] + input.b * matrix[0][1] + input.c * matrix[0][2];
|
||||
double b =
|
||||
input.a * matrix[1][0] + input.b * matrix[1][1] + input.c * matrix[1][2];
|
||||
double c =
|
||||
input.a * matrix[2][0] + input.b * matrix[2][1] + input.c * matrix[2][2];
|
||||
return (Vec3){a, b, c};
|
||||
}
|
||||
} // namespace material_color_utilities
|
||||
204
arm9/source/material/utils/utils.h
Normal file
204
arm9/source/material/utils/utils.h
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef CPP_UTILS_UTILS_H_
|
||||
#define CPP_UTILS_UTILS_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace material_color_utilities {
|
||||
|
||||
using Argb = uint32_t;
|
||||
|
||||
/**
|
||||
* A vector with three floating-point numbers as components.
|
||||
*/
|
||||
struct Vec3 {
|
||||
double a = 0.0;
|
||||
double b = 0.0;
|
||||
double c = 0.0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Value of pi.
|
||||
*/
|
||||
inline constexpr double kPi = 3.141592653589793;
|
||||
|
||||
/**
|
||||
* Returns the standard white point; white on a sunny day.
|
||||
*/
|
||||
inline constexpr double kWhitePointD65[] = {95.047, 100.0, 108.883};
|
||||
|
||||
/**
|
||||
* Returns the red component of a color in ARGB format.
|
||||
*/
|
||||
int RedFromInt(const Argb argb);
|
||||
|
||||
/**
|
||||
* Returns the green component of a color in ARGB format.
|
||||
*/
|
||||
int GreenFromInt(const Argb argb);
|
||||
|
||||
/**
|
||||
* Returns the blue component of a color in ARGB format.
|
||||
*/
|
||||
int BlueFromInt(const Argb argb);
|
||||
|
||||
/**
|
||||
* Returns the alpha component of a color in ARGB format.
|
||||
*/
|
||||
int AlphaFromInt(const Argb argb);
|
||||
|
||||
/**
|
||||
* Converts a color from RGB components to ARGB format.
|
||||
*/
|
||||
Argb ArgbFromRgb(const int red, const int green, const int blue);
|
||||
|
||||
/**
|
||||
* Converts a color from linear RGB components to ARGB format.
|
||||
*/
|
||||
Argb ArgbFromLinrgb(Vec3 linrgb);
|
||||
|
||||
/**
|
||||
* Returns whether a color in ARGB format is opaque.
|
||||
*/
|
||||
bool IsOpaque(const Argb argb);
|
||||
|
||||
/**
|
||||
* Sanitizes a degree measure as an integer.
|
||||
*
|
||||
* @return a degree measure between 0 (inclusive) and 360 (exclusive).
|
||||
*/
|
||||
int SanitizeDegreesInt(const int degrees);
|
||||
|
||||
/**
|
||||
* Sanitizes a degree measure as an floating-point number.
|
||||
*
|
||||
* @return a degree measure between 0.0 (inclusive) and 360.0 (exclusive).
|
||||
*/
|
||||
double SanitizeDegreesDouble(const double degrees);
|
||||
|
||||
/**
|
||||
* Distance of two points on a circle, represented using degrees.
|
||||
*/
|
||||
double DiffDegrees(const double a, const double b);
|
||||
|
||||
/**
|
||||
* Sign of direction change needed to travel from one angle to
|
||||
* another.
|
||||
*
|
||||
* For angles that are 180 degrees apart from each other, both
|
||||
* directions have the same travel distance, so either direction is
|
||||
* shortest. The value 1.0 is returned in this case.
|
||||
*
|
||||
* @param from The angle travel starts from, in degrees.
|
||||
*
|
||||
* @param to The angle travel ends at, in degrees.
|
||||
*
|
||||
* @return -1 if decreasing from leads to the shortest travel
|
||||
* distance, 1 if increasing from leads to the shortest travel
|
||||
* distance.
|
||||
*/
|
||||
double RotationDirection(const double from, const double to);
|
||||
|
||||
/**
|
||||
* Computes the L* value of a color in ARGB representation.
|
||||
*
|
||||
* @param argb ARGB representation of a color
|
||||
*
|
||||
* @return L*, from L*a*b*, coordinate of the color
|
||||
*/
|
||||
double LstarFromArgb(const Argb argb);
|
||||
|
||||
/**
|
||||
* Returns the hexadecimal representation of a color.
|
||||
*/
|
||||
// std::string HexFromArgb(Argb argb);
|
||||
|
||||
/**
|
||||
* Linearizes an RGB component.
|
||||
*
|
||||
* @param rgb_component 0 <= rgb_component <= 255, represents R/G/B
|
||||
* channel
|
||||
*
|
||||
* @return 0.0 <= output <= 100.0, color channel converted to
|
||||
* linear RGB space
|
||||
*/
|
||||
double Linearized(const int rgb_component);
|
||||
|
||||
/**
|
||||
* Delinearizes an RGB component.
|
||||
*
|
||||
* @param rgb_component 0.0 <= rgb_component <= 100.0, represents linear
|
||||
* R/G/B channel
|
||||
*
|
||||
* @return 0 <= output <= 255, color channel converted to regular
|
||||
* RGB space
|
||||
*/
|
||||
int Delinearized(const double rgb_component);
|
||||
|
||||
/**
|
||||
* Converts an L* value to a Y value.
|
||||
*
|
||||
* L* in L*a*b* and Y in XYZ measure the same quantity, luminance.
|
||||
*
|
||||
* L* measures perceptual luminance, a linear scale. Y in XYZ
|
||||
* measures relative luminance, a logarithmic scale.
|
||||
*
|
||||
* @param lstar L* in L*a*b*. 0.0 <= L* <= 100.0
|
||||
*
|
||||
* @return Y in XYZ. 0.0 <= Y <= 100.0
|
||||
*/
|
||||
double YFromLstar(const double lstar);
|
||||
|
||||
/**
|
||||
* Converts a Y value to an L* value.
|
||||
*
|
||||
* L* in L*a*b* and Y in XYZ measure the same quantity, luminance.
|
||||
*
|
||||
* L* measures perceptual luminance, a linear scale. Y in XYZ
|
||||
* measures relative luminance, a logarithmic scale.
|
||||
*
|
||||
* @param y Y in XYZ. 0.0 <= Y <= 100.0
|
||||
*
|
||||
* @return L* in L*a*b*. 0.0 <= L* <= 100.0
|
||||
*/
|
||||
double LstarFromY(const double y);
|
||||
|
||||
/**
|
||||
* Converts an L* value to an ARGB representation.
|
||||
*
|
||||
* @param lstar L* in L*a*b*. 0.0 <= L* <= 100.0
|
||||
*
|
||||
* @return ARGB representation of grayscale color with lightness matching L*
|
||||
*/
|
||||
Argb IntFromLstar(const double lstar);
|
||||
|
||||
/**
|
||||
* The signum function.
|
||||
*
|
||||
* @return 1 if num > 0, -1 if num < 0, and 0 if num = 0
|
||||
*/
|
||||
int Signum(double num);
|
||||
|
||||
/**
|
||||
* Multiplies a 1x3 row vector with a 3x3 matrix, returning the product.
|
||||
*/
|
||||
Vec3 MatrixMultiply(Vec3 input, const double matrix[3][3]);
|
||||
|
||||
} // namespace material_color_utilities
|
||||
#endif // CPP_UTILS_UTILS_H_
|
||||
Reference in New Issue
Block a user