Crop ratios and selection start, Vignette on empty layers, text colour previews (12.10c); mutation runs use 12 cores
This commit is contained in:
1 parent
7a873eb9c7
commit
ffba1753c6
27 files changed
+555
-55
No files matched your search
+36
-16
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user