diff --git a/src/factory.c b/src/factory.c index 469f9a85..41cfe6fa 100644 --- a/src/factory.c +++ b/src/factory.c @@ -711,12 +711,23 @@ int L_MatchColor2(lua_State* L) int c; int nb_args=lua_gettop(L); - LUA_ARG_LIMIT (3, "matchcolor2"); + if (nb_args < 3 || nb_args > 4) + { + return luaL_error(L, "matchcolor2: Expected 3 or 4 arguments, but found %d.", nb_args); + } LUA_ARG_NUMBER(1, "matchcolor2", r, -DBL_MAX, DBL_MAX); LUA_ARG_NUMBER(2, "matchcolor2", g, -DBL_MAX, DBL_MAX); LUA_ARG_NUMBER(3, "matchcolor2", b, -DBL_MAX, DBL_MAX); - - c = Best_color_perceptual(clamp_byte(r),clamp_byte(g),clamp_byte(b)); + if (nb_args == 3) + { + c = Best_color_perceptual(clamp_byte(r),clamp_byte(g),clamp_byte(b)); + } + else // nb_args == 4 + { + float weight; + LUA_ARG_NUMBER(4, "matchcolor2", weight, -DBL_MAX, DBL_MAX); + c = Best_color_perceptual_weighted(clamp_byte(r),clamp_byte(g),clamp_byte(b),weight); + } lua_pushinteger(L, c); return 1; } diff --git a/src/windows.c b/src/windows.c index e2e5fa27..a89fa54f 100644 --- a/src/windows.c +++ b/src/windows.c @@ -2720,6 +2720,49 @@ byte Best_color_perceptual(byte r,byte g,byte b) return best_color; } +byte Best_color_perceptual_weighted(byte r,byte g,byte b,float l_weight) +{ + + int col; + float best_diff=255.0*1.56905; + byte best_color=0; + float target_bri; + float bri; + float diff_b, diff_c, diff; + + // Similar to Perceptual_lightness(); + target_bri = sqrt(0.26*r*0.26*r + 0.55*g*0.55*g + 0.19*b*0.19*b); + + for (col=0; col<256; col++) + { + if (Exclude_color[col]) + continue; + + diff_c = sqrt( + (0.26*(Main_palette[col].R-r))* + (0.26*(Main_palette[col].R-r))+ + (0.55*(Main_palette[col].G-g))* + (0.55*(Main_palette[col].G-g))+ + (0.19*(Main_palette[col].B-b))* + (0.19*(Main_palette[col].B-b))); + // Exact match + if (diff_c==0) + return col; + + bri = sqrt(0.26*Main_palette[col].R*0.26*Main_palette[col].R + 0.55*Main_palette[col].G*0.55*Main_palette[col].G + 0.19*Main_palette[col].B*0.19*Main_palette[col].B); + diff_b = abs(target_bri-bri); + + diff=l_weight*(diff_b-diff_c)+diff_c; + if (diff