From 377fa5bb1434da24c1792a869d570bc94851ac7e Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 3 May 2025 11:59:08 +0200 Subject: [PATCH] Minor improvements to image algorithms - loop Y around X - use float over double --- src/client/imagefilters.cpp | 26 ++++++++--------- src/client/imagesource.cpp | 56 ++++++++++++++++++------------------- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/client/imagefilters.cpp b/src/client/imagefilters.cpp index 1277ea426..8b38e9ad9 100644 --- a/src/client/imagefilters.cpp +++ b/src/client/imagefilters.cpp @@ -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 &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 &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 &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); diff --git a/src/client/imagesource.cpp b/src/client/imagesource.cpp index e39dc2955..466d15d28 100644 --- a/src/client/imagesource.cpp +++ b/src/client/imagesource.cpp @@ -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 dim = image->getDimension(); @@ -814,9 +814,9 @@ static void brighten(video::IImage *image) for (u32 x=0; xgetPixel(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 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 ||