plug-ins: Import Legacy PSD Dropshadow

This patch adds support for loading and
applying active Legacy Dropshadow
layer styles in PSD images.
This commit is contained in:
Alx Sa 2025-05-28 13:28:44 +00:00
parent 65feecd32d
commit 3b775abc90
3 changed files with 140 additions and 31 deletions

View file

@ -786,41 +786,97 @@ load_resource_lrfx (const PSDlayerres *res_a,
return -1;
}
}
else if (memcmp (effectname, "dsdw", 4) == 0
|| memcmp (effectname, "isdw", 4) == 0)
else if (memcmp (effectname, "dsdw", 4) == 0)
{
PSDLayerStyleShadow shadow;
gchar bim[4];
guint16 spacer16;
if (memcmp (effectname, "dsdw", 4) == 0)
shadow = ls_a->dsdw;
else
shadow = ls_a->isdw;
if (psd_read (input, &shadow.size, 4, error) < 4 ||
psd_read (input, &shadow.ver, 4, error) < 4 ||
psd_read (input, &shadow.blur, 4, error) < 4 ||
psd_read (input, &shadow.intensity, 4, error) < 4 ||
psd_read (input, &shadow.angle, 4, error) < 4 ||
psd_read (input, &shadow.distance, 4, error) < 4 ||
psd_read (input, &shadow.color[0], 2, error) < 2 ||
psd_read (input, &shadow.color[1], 2, error) < 2 ||
psd_read (input, &shadow.color[2], 2, error) < 2 ||
psd_read (input, &shadow.color[3], 2, error) < 2 ||
psd_read (input, &shadow.color[4], 2, error) < 2 ||
psd_read (input, &shadow.blendsig, 4, error) < 4 ||
psd_read (input, &shadow.effect, 4, error) < 4 ||
psd_read (input, &shadow.effecton, 1, error) < 1 ||
psd_read (input, &shadow.anglefx, 1, error) < 1 ||
psd_read (input, &shadow.opacity, 1, error) < 1 ||
psd_read (input, &shadow.natcolor[0], 2, error) < 2 ||
psd_read (input, &shadow.natcolor[1], 2, error) < 2 ||
psd_read (input, &shadow.natcolor[2], 2, error) < 2 ||
psd_read (input, &shadow.natcolor[3], 2, error) < 2 ||
psd_read (input, &shadow.natcolor[4], 2, error) < 2)
if (psd_read (input, &ls_a->dsdw.size, 4, error) < 4 ||
psd_read (input, &ls_a->dsdw.ver, 4, error) < 4 ||
psd_read (input, &ls_a->dsdw.blur, 2, error) < 2 ||
psd_read (input, &ls_a->dsdw.intensity, 4, error) < 4 ||
psd_read (input, &ls_a->dsdw.angle, 4, error) < 4 ||
psd_read (input, &ls_a->dsdw.distance, 4, error) < 4 ||
psd_read (input, &spacer16, 2, error) < 2 ||
psd_read (input, &ls_a->dsdw.color[0], 2, error) < 2 ||
psd_read (input, &ls_a->dsdw.color[1], 2, error) < 2 ||
psd_read (input, &ls_a->dsdw.color[2], 2, error) < 2 ||
psd_read (input, &ls_a->dsdw.color[3], 2, error) < 2 ||
psd_read (input, &ls_a->dsdw.color[4], 2, error) < 2 ||
psd_read (input, &bim, 4, error) < 4 ||
psd_read (input, &ls_a->dsdw.blendsig, 4, error) < 4 ||
psd_read (input, &ls_a->dsdw.effecton, 1, error) < 1 ||
psd_read (input, &ls_a->dsdw.anglefx, 1, error) < 1 ||
psd_read (input, &ls_a->dsdw.opacity, 1, error) < 1)
{
psd_set_error (error);
return -1;
}
ls_a->dsdw.size = GUINT32_TO_BE (ls_a->dsdw.size);
ls_a->dsdw.ver = GUINT32_TO_BE (ls_a->dsdw.ver);
ls_a->dsdw.blur = GUINT16_TO_BE (ls_a->dsdw.blur);
ls_a->dsdw.intensity = GUINT32_TO_BE (ls_a->dsdw.intensity);
ls_a->dsdw.angle = GINT32_TO_BE (ls_a->dsdw.angle);
ls_a->dsdw.distance = GUINT32_TO_BE (ls_a->dsdw.distance);
if (ls_a->dsdw.ver == 2)
{
if (psd_read (input, &ls_a->dsdw.natcolor[0], 2, error) < 2 ||
psd_read (input, &ls_a->dsdw.natcolor[1], 2, error) < 2 ||
psd_read (input, &ls_a->dsdw.natcolor[2], 2, error) < 2 ||
psd_read (input, &ls_a->dsdw.natcolor[3], 2, error) < 2 ||
psd_read (input, &ls_a->dsdw.natcolor[4], 2, error) < 2)
{
psd_set_error (error);
return -1;
}
}
}
else if (memcmp (effectname, "isdw", 4) == 0)
{
gchar bim[4];
guint16 spacer16;
if (psd_read (input, &ls_a->isdw.size, 4, error) < 4 ||
psd_read (input, &ls_a->isdw.ver, 4, error) < 4 ||
psd_read (input, &ls_a->isdw.blur, 2, error) < 2 ||
psd_read (input, &ls_a->isdw.intensity, 4, error) < 4 ||
psd_read (input, &ls_a->isdw.angle, 4, error) < 4 ||
psd_read (input, &ls_a->isdw.distance, 4, error) < 4 ||
psd_read (input, &spacer16, 2, error) < 2 ||
psd_read (input, &ls_a->isdw.color[0], 2, error) < 2 ||
psd_read (input, &ls_a->isdw.color[1], 2, error) < 2 ||
psd_read (input, &ls_a->isdw.color[2], 2, error) < 2 ||
psd_read (input, &ls_a->isdw.color[3], 2, error) < 2 ||
psd_read (input, &ls_a->isdw.color[4], 2, error) < 2 ||
psd_read (input, &bim, 4, error) < 4 ||
psd_read (input, &ls_a->isdw.blendsig, 4, error) < 4 ||
psd_read (input, &ls_a->isdw.effecton, 1, error) < 1 ||
psd_read (input, &ls_a->isdw.anglefx, 1, error) < 1 ||
psd_read (input, &ls_a->isdw.opacity, 1, error) < 1)
{
psd_set_error (error);
return -1;
}
ls_a->isdw.size = GUINT32_TO_BE (ls_a->isdw.size);
ls_a->isdw.ver = GUINT32_TO_BE (ls_a->isdw.ver);
ls_a->isdw.blur = GUINT16_TO_BE (ls_a->isdw.blur);
ls_a->isdw.intensity = GUINT32_TO_BE (ls_a->isdw.intensity);
ls_a->isdw.angle = GINT32_TO_BE (ls_a->isdw.angle);
ls_a->isdw.distance = GUINT32_TO_BE (ls_a->isdw.distance);
if (ls_a->isdw.ver == 2)
{
if (psd_read (input, &ls_a->isdw.natcolor[0], 2, error) < 2 ||
psd_read (input, &ls_a->isdw.natcolor[1], 2, error) < 2 ||
psd_read (input, &ls_a->isdw.natcolor[2], 2, error) < 2 ||
psd_read (input, &ls_a->isdw.natcolor[3], 2, error) < 2 ||
psd_read (input, &ls_a->isdw.natcolor[4], 2, error) < 2)
{
psd_set_error (error);
return -1;
}
}
}
else if (memcmp (effectname, "oglw", 4) == 0)
{

View file

@ -2795,6 +2795,60 @@ add_legacy_layer_effects (GimpLayer *layer,
g_object_unref (filter);
g_object_unref (color);
}
if (lyr_a->layer_styles->dsdw.effecton == 1)
{
PSDLayerStyleShadow dsdw;
GimpLayerMode mode;
GimpDrawableFilter *filter;
GeglColor *color = gegl_color_new ("none");
gdouble x;
gdouble y;
gdouble blur;
gdouble radians;
dsdw = lyr_a->layer_styles->dsdw;
/* Photoshop uses an angle slider that goes from 0 to 180,
* then -179 to 0. Since GEGL uses X/Y coordinates for distance,
* we convert the Photoshop angle and distance and then flip the
* sign based on the quadrant of the angle */
radians = (M_PI / 180) * dsdw.angle;
x = dsdw.distance * cos (radians);
y = dsdw.distance * sin (radians);
if (dsdw.angle >= 0xFF00)
dsdw.angle = (dsdw.angle - 0xFF00) * -1;
if (dsdw.angle > 90 && dsdw.angle < 180)
y *= -1;
else if (dsdw.angle < -90 && dsdw.angle > -180)
x *= -1;
blur = (dsdw.blur / 250.0) * 100.0;
if (dsdw.ver == 0)
convert_legacy_psd_color (color, dsdw.color, space, ibm_pc_format);
else if (dsdw.ver == 2)
convert_legacy_psd_color (color, dsdw.natcolor, space, ibm_pc_format);
convert_psd_mode (dsdw.blendsig, &mode);
filter = gimp_drawable_append_new_filter (GIMP_DRAWABLE (layer),
"gegl:dropshadow",
NULL,
GIMP_LAYER_MODE_REPLACE,
1.0,
"x", x,
"y", y,
"radius", blur,
"color", color,
"opacity", dsdw.opacity / 255.0,
NULL);
g_object_unref (filter);
g_object_unref (color);
}
}
static gint

View file

@ -592,13 +592,12 @@ typedef struct
{
guint32 size;
guint32 ver;
guint32 blur;
guint16 blur;
guint32 intensity;
gint32 angle;
guint32 distance;
guint16 color[5];
gchar blendsig[4];
guint32 effect;
guchar effecton;
guchar anglefx;
guchar opacity;