Crop ratios and selection start, Vignette on empty layers, text colour previews (12.10c); mutation runs use 12 cores

This commit is contained in:
雷电芽衣 committed 2026-09-28 21:03:16 -04:00
1 parent 7a873eb9c7
commit ffba1753c6
27 files changed
+555 -55

No files matched your search

+36 -16
View File
@@ -408,10 +408,11 @@ static void effects_dehaze(double *r, double *g, double *b, double amount) {
*b = camera_clamp(y2 + (*b - y2) * sat);
}
static double vignette_mask(size_t x, size_t y, size_t width, size_t height,
double midpoint, double roundness, double feather) {
double nx = ((double)x + 0.5) / (double)width * 2.0 - 1.0;
double ny = ((double)y + 0.5) / (double)height * 2.0 - 1.0;
/// The vignette's strength at a point `px`, `py` of a `width` × `height` frame (0 at its middle, 1 past its edges).
static double vignette_mask_at(double px, double py, double width, double height,
double midpoint, double roundness, double feather) {
double nx = px / width * 2.0 - 1.0;
double ny = py / height * 2.0 - 1.0;
double square = fmax(fabs(nx), fabs(ny));
double circle = hypot(nx, ny) / sqrt(2.0);
double shape = (1.0 - roundness / 100.0) * 0.5;
@@ -424,6 +425,11 @@ static double vignette_mask(size_t x, size_t y, size_t width, size_t height,
return t * t * (3.0 - 2.0 * t);
}
static double vignette_mask(size_t x, size_t y, size_t width, size_t height,
double midpoint, double roundness, double feather) {
return vignette_mask_at((double)x + 0.5, (double)y + 0.5, (double)width, (double)height, midpoint, roundness, feather);
}
static void effects_vignette(double *r, double *g, double *b, size_t x, size_t y, size_t width, size_t height,
double amount, double midpoint, double roundness, double feather, double highlights,
int style) {
@@ -453,28 +459,42 @@ static void effects_vignette(double *r, double *g, double *b, size_t x, size_t y
}
void adjust_colored_vignette(uint8_t *rgba, size_t width, size_t height, size_t stride,
double frameX, double frameY, double frameWidth, double frameHeight, int fillsClear,
double amount, double midpoint, double roundness, double feather,
double highlights, double red, double green, double blue) {
if (!rgba || amount <= 0 || width == 0 || height == 0) return;
if (!rgba || amount <= 0 || width == 0 || height == 0 || frameWidth <= 0 || frameHeight <= 0) return;
double strength = camera_clamp(amount / 100.0);
red = camera_clamp(red); green = camera_clamp(green); blue = camera_clamp(blue);
for (size_t y = 0; y < height; ++y) {
uint8_t *row = rgba + y * stride;
for (size_t x = 0; x < width; ++x) {
uint8_t *p = row + x * 4;
double alpha = p[3];
if (!alpha) continue;
double mask = vignette_mask(x, y, width, height, midpoint, roundness, feather);
if (!p[3] && !fillsClear) continue;
double mask = vignette_mask_at((double)x + 0.5 - frameX, (double)y + 0.5 - frameY, frameWidth, frameHeight,
midpoint, roundness, feather);
if (mask <= 0) continue;
double r = fmin(1.0, p[0] / alpha);
double g = fmin(1.0, p[1] / alpha);
double b = fmin(1.0, p[2] / alpha);
double bright = camera_clamp((rec709(r, g, b) - 0.45) / 0.55);
double alpha = p[3] / 255.0;
double r = 0, g = 0, b = 0, bright = 0;
if (p[3]) {
r = fmin(1.0, p[0] / (double)p[3]);
g = fmin(1.0, p[1] / (double)p[3]);
b = fmin(1.0, p[2] / (double)p[3]);
bright = camera_clamp((rec709(r, g, b) - 0.45) / 0.55);
}
double effect = strength * mask * (1.0 - (highlights / 100.0) * bright);
r += (red - r) * effect;
g += (green - g) * effect;
b += (blue - b) * effect;
write_premultiplied(p, r, g, b, alpha);
if (!fillsClear) {
// Only the pixels that are there change color; their coverage stays as it was.
write_premultiplied(p, r + (red - r) * effect, g + (green - g) * effect, b + (blue - b) * effect, p[3]);
continue;
}
// The color painted over the pixel at `effect`: an opaque pixel moves toward it, a clear one takes it on.
double out = alpha + effect * (1.0 - alpha);
if (out <= 0) continue;
r = (red * effect + r * alpha * (1.0 - effect)) / out;
g = (green * effect + g * alpha * (1.0 - effect)) / out;
b = (blue * effect + b * alpha * (1.0 - effect)) / out;
p[3] = (uint8_t)fmin(255.0, round(out * 255.0));
write_premultiplied(p, r, g, b, p[3]);
}
}
}