mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Minor improvements to image algorithms
- loop Y around X - use float over double
This commit is contained in:
parent
486fb7cc4d
commit
377fa5bb14
2 changed files with 41 additions and 41 deletions
|
@ -229,8 +229,8 @@ static video::SColor imageAverageColorInline(const video::IImage *src)
|
|||
// limit runtime cost
|
||||
const u32 stepx = std::max(1U, dim.Width / 16),
|
||||
stepy = std::max(1U, dim.Height / 16);
|
||||
for (u32 x = 0; x < dim.Width; x += stepx) {
|
||||
for (u32 y = 0; y < dim.Height; y += stepy) {
|
||||
for (u32 y = 0; y < dim.Height; y += stepy) {
|
||||
for (u32 x = 0; x < dim.Width; x += stepx) {
|
||||
video::SColor c = get_pixel(x, y);
|
||||
if (c.getAlpha() > 0) {
|
||||
total++;
|
||||
|
@ -261,15 +261,15 @@ video::SColor imageAverageColor(const video::IImage *img)
|
|||
|
||||
void imageScaleNNAA(video::IImage *src, const core::rect<s32> &srcrect, video::IImage *dest)
|
||||
{
|
||||
double sx, sy, minsx, maxsx, minsy, maxsy, area, ra, ga, ba, aa, pw, ph, pa;
|
||||
f32 sx, sy, minsx, maxsx, minsy, maxsy, area, ra, ga, ba, aa, pw, ph, pa;
|
||||
u32 dy, dx;
|
||||
video::SColor pxl;
|
||||
|
||||
// Cache rectangle boundaries.
|
||||
double sox = srcrect.UpperLeftCorner.X * 1.0;
|
||||
double soy = srcrect.UpperLeftCorner.Y * 1.0;
|
||||
double sw = srcrect.getWidth() * 1.0;
|
||||
double sh = srcrect.getHeight() * 1.0;
|
||||
const f32 sox = srcrect.UpperLeftCorner.X;
|
||||
const f32 soy = srcrect.UpperLeftCorner.Y;
|
||||
const f32 sw = srcrect.getWidth();
|
||||
const f32 sh = srcrect.getHeight();
|
||||
|
||||
// Walk each destination image pixel.
|
||||
// Note: loop y around x for better cache locality.
|
||||
|
@ -302,8 +302,8 @@ void imageScaleNNAA(video::IImage *src, const core::rect<s32> &srcrect, video::I
|
|||
aa = 0;
|
||||
|
||||
// Loop over the integral pixel positions described by those bounds.
|
||||
for (sy = floor(minsy); sy < maxsy; sy++)
|
||||
for (sx = floor(minsx); sx < maxsx; sx++) {
|
||||
for (sy = std::floor(minsy); sy < maxsy; sy++)
|
||||
for (sx = std::floor(minsx); sx < maxsx; sx++) {
|
||||
|
||||
// Calculate width, height, then area of dest pixel
|
||||
// that's covered by this source pixel.
|
||||
|
@ -331,10 +331,10 @@ void imageScaleNNAA(video::IImage *src, const core::rect<s32> &srcrect, video::I
|
|||
|
||||
// Set the destination image pixel to the average color.
|
||||
if (area > 0) {
|
||||
pxl.setRed(ra / area + 0.5);
|
||||
pxl.setGreen(ga / area + 0.5);
|
||||
pxl.setBlue(ba / area + 0.5);
|
||||
pxl.setAlpha(aa / area + 0.5);
|
||||
pxl.setRed(ra / area + 0.5f);
|
||||
pxl.setGreen(ga / area + 0.5f);
|
||||
pxl.setBlue(ba / area + 0.5f);
|
||||
pxl.setAlpha(aa / area + 0.5f);
|
||||
} else {
|
||||
pxl.setRed(0);
|
||||
pxl.setGreen(0);
|
||||
|
|
|
@ -601,7 +601,7 @@ static void apply_hue_saturation(video::IImage *dst, v2u32 dst_pos, v2u32 size,
|
|||
}
|
||||
|
||||
// Apply the specified HSL adjustments
|
||||
hsl.Hue = fmod(hsl.Hue + hue, 360);
|
||||
hsl.Hue = fmodf(hsl.Hue + hue, 360);
|
||||
if (hsl.Hue < 0)
|
||||
hsl.Hue += 360;
|
||||
|
||||
|
@ -632,19 +632,19 @@ static void apply_overlay(video::IImage *blend, video::IImage *dst,
|
|||
video::SColor blend_c =
|
||||
blend_layer->getPixel(x + blend_layer_pos.X, y + blend_layer_pos.Y);
|
||||
video::SColor base_c = base_layer->getPixel(base_x, base_y);
|
||||
double blend_r = blend_c.getRed() / 255.0;
|
||||
double blend_g = blend_c.getGreen() / 255.0;
|
||||
double blend_b = blend_c.getBlue() / 255.0;
|
||||
double base_r = base_c.getRed() / 255.0;
|
||||
double base_g = base_c.getGreen() / 255.0;
|
||||
double base_b = base_c.getBlue() / 255.0;
|
||||
f32 blend_r = blend_c.getRed() / 255.0f;
|
||||
f32 blend_g = blend_c.getGreen() / 255.0f;
|
||||
f32 blend_b = blend_c.getBlue() / 255.0f;
|
||||
f32 base_r = base_c.getRed() / 255.0f;
|
||||
f32 base_g = base_c.getGreen() / 255.0f;
|
||||
f32 base_b = base_c.getBlue() / 255.0f;
|
||||
|
||||
base_c.set(
|
||||
base_c.getAlpha(),
|
||||
// Do a Multiply blend if less that 0.5, otherwise do a Screen blend
|
||||
(u32)((base_r < 0.5 ? 2 * base_r * blend_r : 1 - 2 * (1 - base_r) * (1 - blend_r)) * 255),
|
||||
(u32)((base_g < 0.5 ? 2 * base_g * blend_g : 1 - 2 * (1 - base_g) * (1 - blend_g)) * 255),
|
||||
(u32)((base_b < 0.5 ? 2 * base_b * blend_b : 1 - 2 * (1 - base_b) * (1 - blend_b)) * 255)
|
||||
(u32)((base_r < 0.5f ? 2 * base_r * blend_r : 1 - 2 * (1 - base_r) * (1 - blend_r)) * 255),
|
||||
(u32)((base_g < 0.5f ? 2 * base_g * blend_g : 1 - 2 * (1 - base_g) * (1 - blend_g)) * 255),
|
||||
(u32)((base_b < 0.5f ? 2 * base_b * blend_b : 1 - 2 * (1 - base_b) * (1 - blend_b)) * 255)
|
||||
);
|
||||
dst->setPixel(base_x, base_y, base_c);
|
||||
}
|
||||
|
@ -659,38 +659,38 @@ static void apply_overlay(video::IImage *blend, video::IImage *dst,
|
|||
static void apply_brightness_contrast(video::IImage *dst, v2u32 dst_pos, v2u32 size,
|
||||
s32 brightness, s32 contrast)
|
||||
{
|
||||
video::SColor dst_c;
|
||||
// Only allow normalized contrast to get as high as 127/128 to avoid infinite slope.
|
||||
// (we could technically allow -128/128 here as that would just result in 0 slope)
|
||||
double norm_c = core::clamp(contrast, -127, 127) / 128.0;
|
||||
double norm_b = core::clamp(brightness, -127, 127) / 127.0;
|
||||
f32 norm_c = core::clamp(contrast, -127, 127) / 128.0f;
|
||||
f32 norm_b = core::clamp(brightness, -127, 127) / 127.0f;
|
||||
|
||||
// Scale brightness so its range is -127.5 to 127.5, otherwise brightness
|
||||
// adjustments will outputs values from 0.5 to 254.5 instead of 0 to 255.
|
||||
double scaled_b = brightness * 127.5 / 127;
|
||||
f32 scaled_b = brightness * 127.5f / 127;
|
||||
|
||||
// Calculate a contrast slope such that that no colors will get clamped due
|
||||
// to the brightness setting.
|
||||
// This allows the texture modifier to used as a brightness modifier without
|
||||
// the user having to calculate a contrast to avoid clipping at that brightness.
|
||||
double slope = 1 - fabs(norm_b);
|
||||
f32 slope = 1 - std::fabs(norm_b);
|
||||
|
||||
// Apply the user's contrast adjustment to the calculated slope, such that
|
||||
// -127 will make it near-vertical and +127 will make it horizontal
|
||||
double angle = atan(slope);
|
||||
f32 angle = std::atan(slope);
|
||||
angle += norm_c <= 0
|
||||
? norm_c * angle // allow contrast slope to be lowered to 0
|
||||
: norm_c * (M_PI_2 - angle); // allow contrast slope to be raised almost vert.
|
||||
slope = tan(angle);
|
||||
slope = std::tan(angle);
|
||||
|
||||
double c = slope <= 1
|
||||
? -slope * 127.5 + 127.5 + scaled_b // shift up/down when slope is horiz.
|
||||
: -slope * (127.5 - scaled_b) + 127.5; // shift left/right when slope is vert.
|
||||
f32 c = slope <= 1
|
||||
? -slope * 127.5f + 127.5f + scaled_b // shift up/down when slope is horiz.
|
||||
: -slope * (127.5f - scaled_b) + 127.5f; // shift left/right when slope is vert.
|
||||
|
||||
// add 0.5 to c so that when the final result is cast to int, it is effectively
|
||||
// rounded rather than trunc'd.
|
||||
c += 0.5;
|
||||
c += 0.5f;
|
||||
|
||||
video::SColor dst_c;
|
||||
for (u32 y = dst_pos.Y; y < dst_pos.Y + size.Y; y++)
|
||||
for (u32 x = dst_pos.X; x < dst_pos.X + size.X; x++) {
|
||||
dst_c = dst->getPixel(x, y);
|
||||
|
@ -805,7 +805,7 @@ static void draw_crack(video::IImage *crack, video::IImage *dst,
|
|||
|
||||
static void brighten(video::IImage *image)
|
||||
{
|
||||
if (image == NULL)
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
core::dimension2d<u32> dim = image->getDimension();
|
||||
|
@ -814,9 +814,9 @@ static void brighten(video::IImage *image)
|
|||
for (u32 x=0; x<dim.Width; x++)
|
||||
{
|
||||
video::SColor c = image->getPixel(x,y);
|
||||
c.setRed(0.5 * 255 + 0.5 * (float)c.getRed());
|
||||
c.setGreen(0.5 * 255 + 0.5 * (float)c.getGreen());
|
||||
c.setBlue(0.5 * 255 + 0.5 * (float)c.getBlue());
|
||||
c.setRed(127.5f + 0.5f * c.getRed());
|
||||
c.setGreen(127.5f + 0.5f * c.getGreen());
|
||||
c.setBlue(127.5f + 0.5f * c.getBlue());
|
||||
image->setPixel(x,y,c);
|
||||
}
|
||||
}
|
||||
|
@ -881,7 +881,7 @@ static core::dimension2du imageTransformDimension(u32 transform, core::dimension
|
|||
|
||||
static void imageTransform(u32 transform, video::IImage *src, video::IImage *dst)
|
||||
{
|
||||
if (src == NULL || dst == NULL)
|
||||
if (!src || !dst)
|
||||
return;
|
||||
|
||||
core::dimension2d<u32> dstdim = dst->getDimension();
|
||||
|
@ -1280,7 +1280,7 @@ bool ImageSource::generateImagePart(std::string_view part_of_name,
|
|||
video::IImage *img_left = generateImage(imagename_left, source_image_names);
|
||||
video::IImage *img_right = generateImage(imagename_right, source_image_names);
|
||||
|
||||
if (img_top == NULL || img_left == NULL || img_right == NULL) {
|
||||
if (!img_top || !img_left || !img_right) {
|
||||
errorstream << "generateImagePart(): Failed to create textures"
|
||||
<< " for inventorycube \"" << part_of_name << "\""
|
||||
<< std::endl;
|
||||
|
@ -1896,7 +1896,7 @@ video::IImage* ImageSource::generateImage(std::string_view name,
|
|||
}
|
||||
|
||||
// If no resulting image, print a warning
|
||||
if (baseimg == NULL) {
|
||||
if (!baseimg) {
|
||||
errorstream << "generateImage(): baseimg is NULL (attempted to"
|
||||
" create texture \"" << name << "\")" << std::endl;
|
||||
} else if (baseimg->getDimension().Width == 0 ||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue