plug-ins: fix incorrect psd dropshadow offsets
Some dropshadow offsets were incorrect when loading PSD's. Photoshop has a global lighting angle that can override the angle set for a dropshadow and we did not account for that. This also showed that our computation of the X and Y values needed to be adjusted. Besides that I noticed a weird offset with angle values > 0xFF00 that happened because we interpreted angle as unsigned when it should be signed. This adds support for loading the Global Lighting Angle, and using that value in the legacy dropshadow effect. We read the angle by using GUINT16_TO_BE because it's a signed int; that also removes the need to check for 0xFF00. Next we adjust the way we compute X and Y.
This commit is contained in:
parent
058ada8f3f
commit
87e071300a
4 changed files with 75 additions and 26 deletions
|
|
@ -198,6 +198,12 @@ static gint load_resource_1033 (const PSDimageres *res_a,
|
|||
GInputStream *input,
|
||||
GError **error);
|
||||
|
||||
static gint load_resource_1037 (const PSDimageres *res_a,
|
||||
PSDimage *img_a,
|
||||
GimpImage *image,
|
||||
GInputStream *input,
|
||||
GError **error);
|
||||
|
||||
static gint load_resource_1039 (const PSDimageres *res_a,
|
||||
PSDimage *img_a,
|
||||
GimpImage *image,
|
||||
|
|
@ -381,7 +387,11 @@ load_image_resource (PSDimageres *res_a,
|
|||
load_resource_1032 (res_a, image, input, error);
|
||||
break;
|
||||
|
||||
case PSD_ICC_PROFILE:
|
||||
case PSD_GLOBAL_ANGLE:
|
||||
load_resource_1037 (res_a, img_a, image, input, error);
|
||||
break;
|
||||
|
||||
case PSD_ICC_PROFILE:
|
||||
if (! load_resource_1039 (res_a, img_a, image, input, error))
|
||||
*profile_loaded = TRUE;
|
||||
break;
|
||||
|
|
@ -1157,6 +1167,34 @@ load_resource_1033 (const PSDimageres *res_a,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* (Photoshop 5.0) Global Angle. 4 bytes that contain an integer between 0 and 359,
|
||||
* which is the global lighting angle for effects layer. If not present, assumed to be 30.
|
||||
* The above official text seems to be incorrect. I have seen a negative value,
|
||||
* which isn't a surprise since layer effect angles can be negative.
|
||||
*/
|
||||
static gint
|
||||
load_resource_1037 (const PSDimageres *res_a,
|
||||
PSDimage *img_a,
|
||||
GimpImage *image,
|
||||
GInputStream *input,
|
||||
GError **error)
|
||||
{
|
||||
gint32 global_angle = 30;
|
||||
|
||||
IFDBG(2) g_debug ("Process image resource block: 1037: Global Lighting Angle");
|
||||
|
||||
if (psd_read (input, &global_angle, 4, error) < 4)
|
||||
{
|
||||
psd_set_error (error);
|
||||
return -1;
|
||||
}
|
||||
img_a->global_light_angle = GINT32_FROM_BE (global_angle);
|
||||
|
||||
IFDBG(3) g_debug ("Global angle: %d", img_a->global_light_angle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint
|
||||
load_resource_1039 (const PSDimageres *res_a,
|
||||
PSDimage *img_a,
|
||||
|
|
|
|||
|
|
@ -825,8 +825,8 @@ load_resource_lrfx (const PSDlayerres *res_a,
|
|||
GUINT16_TO_BE (temp[1]));
|
||||
shadow->intensity = FIXED_TO_FLOAT (GUINT16_TO_BE (temp[2]),
|
||||
GUINT16_TO_BE (temp[3]));
|
||||
shadow->angle = FIXED_TO_FLOAT (GUINT16_TO_BE (temp[4]),
|
||||
GUINT16_TO_BE (temp[5]));
|
||||
shadow->angle = FIXED_TO_FLOAT (GINT16_TO_BE (temp[4]),
|
||||
GINT16_TO_BE (temp[5]));
|
||||
shadow->distance = FIXED_TO_FLOAT (GUINT16_TO_BE (temp[6]),
|
||||
GUINT16_TO_BE (temp[7]));
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ static gint add_layers (GimpImage *image,
|
|||
|
||||
static void add_legacy_layer_effects (GimpLayer *layer,
|
||||
PSDlayer *lyr_a,
|
||||
gboolean ibm_pc_format);
|
||||
PSDimage *img_a);
|
||||
|
||||
static gint add_merged_image (GimpImage *image,
|
||||
PSDimage *img_a,
|
||||
|
|
@ -1691,6 +1691,7 @@ add_image_resources (GimpImage *image,
|
|||
img_a->alpha_id = NULL;
|
||||
img_a->alpha_id_count = 0;
|
||||
img_a->quick_mask_id = 0;
|
||||
img_a->global_light_angle = 30;
|
||||
|
||||
while (PSD_TELL(input) < img_a->image_res_start + img_a->image_res_len)
|
||||
{
|
||||
|
|
@ -2735,8 +2736,7 @@ add_layers (GimpImage *image,
|
|||
* TODO: When we can load modern layer styles, only load these if
|
||||
* the file doesn't have modern layer style data. */
|
||||
if (lyr_a[lidx]->layer_styles->count > 0)
|
||||
add_legacy_layer_effects (layer, lyr_a[lidx],
|
||||
img_a->ibm_pc_format);
|
||||
add_legacy_layer_effects (layer, lyr_a[lidx], img_a);
|
||||
|
||||
/* Insert the layer */
|
||||
if (lyr_a[lidx]->group_type == 0 || /* normal layer */
|
||||
|
|
@ -2766,7 +2766,7 @@ add_layers (GimpImage *image,
|
|||
static void
|
||||
add_legacy_layer_effects (GimpLayer *layer,
|
||||
PSDlayer *lyr_a,
|
||||
gboolean ibm_pc_format)
|
||||
PSDimage *img_a)
|
||||
{
|
||||
const Babl *format = gimp_drawable_get_format (GIMP_DRAWABLE (layer));
|
||||
const Babl *space = babl_format_get_space (format);
|
||||
|
|
@ -2781,7 +2781,7 @@ add_legacy_layer_effects (GimpLayer *layer,
|
|||
|
||||
sofi = lyr_a->layer_styles->sofi;
|
||||
|
||||
convert_legacy_psd_color (color, sofi.natcolor, space, ibm_pc_format);
|
||||
convert_legacy_psd_color (color, sofi.natcolor, space, img_a->ibm_pc_format);
|
||||
convert_psd_mode (sofi.blend, &mode);
|
||||
|
||||
filter = gimp_drawable_append_new_filter (GIMP_DRAWABLE (layer),
|
||||
|
|
@ -2809,9 +2809,9 @@ add_legacy_layer_effects (GimpLayer *layer,
|
|||
blur = (oglw.blur / 250.0) * 100.0;
|
||||
|
||||
if (oglw.ver == 0)
|
||||
convert_legacy_psd_color (color, oglw.color, space, ibm_pc_format);
|
||||
convert_legacy_psd_color (color, oglw.color, space, img_a->ibm_pc_format);
|
||||
else if (oglw.ver == 2)
|
||||
convert_legacy_psd_color (color, oglw.natcolor, space, ibm_pc_format);
|
||||
convert_legacy_psd_color (color, oglw.natcolor, space, img_a->ibm_pc_format);
|
||||
|
||||
convert_psd_mode (oglw.blendsig, &mode);
|
||||
|
||||
|
|
@ -2854,20 +2854,25 @@ add_legacy_layer_effects (GimpLayer *layer,
|
|||
x = isdw.distance * cos (radians);
|
||||
y = isdw.distance * sin (radians);
|
||||
|
||||
if (isdw.angle >= 0xFF00)
|
||||
isdw.angle = (isdw.angle - 0xFF00) * -1;
|
||||
if (isdw.anglefx)
|
||||
isdw.angle = (gfloat) img_a->global_light_angle;
|
||||
|
||||
if (isdw.angle > 90 && isdw.angle < 180)
|
||||
y *= -1;
|
||||
else if (isdw.angle < -90 && isdw.angle > -180)
|
||||
x *= -1;
|
||||
if (isdw.angle < 0.0)
|
||||
y = fabs (y) * -1.0;
|
||||
else
|
||||
y = fabs (y);
|
||||
if ((isdw.angle > 90.0 && isdw.angle < 180.0) ||
|
||||
(isdw.angle > -90.0 && isdw.angle < 0.0))
|
||||
x = fabs (x) * -1.0;
|
||||
else
|
||||
x = fabs (x);
|
||||
|
||||
blur = (isdw.blur / 250.0) * 50.0;
|
||||
|
||||
if (isdw.ver == 0)
|
||||
convert_legacy_psd_color (color, isdw.color, space, ibm_pc_format);
|
||||
convert_legacy_psd_color (color, isdw.color, space, img_a->ibm_pc_format);
|
||||
else if (isdw.ver == 2)
|
||||
convert_legacy_psd_color (color, isdw.natcolor, space, ibm_pc_format);
|
||||
convert_legacy_psd_color (color, isdw.natcolor, space, img_a->ibm_pc_format);
|
||||
|
||||
convert_psd_mode (isdw.blendsig, &mode);
|
||||
|
||||
|
|
@ -2910,20 +2915,25 @@ add_legacy_layer_effects (GimpLayer *layer,
|
|||
x = dsdw.distance * cos (radians);
|
||||
y = dsdw.distance * sin (radians);
|
||||
|
||||
if (dsdw.angle >= 0xFF00)
|
||||
dsdw.angle = (dsdw.angle - 0xFF00) * -1;
|
||||
if (dsdw.anglefx)
|
||||
dsdw.angle = img_a->global_light_angle;
|
||||
|
||||
if (dsdw.angle > 90 && dsdw.angle < 180)
|
||||
y *= -1;
|
||||
else if (dsdw.angle < -90 && dsdw.angle > -180)
|
||||
x *= -1;
|
||||
if (dsdw.angle < 0.0)
|
||||
y = fabs (y) * -1.0;
|
||||
else
|
||||
y = fabs (y);
|
||||
if ((dsdw.angle > 90.0 && dsdw.angle < 180.0) ||
|
||||
(dsdw.angle > -90.0 && dsdw.angle < 0.0))
|
||||
x = fabs (x) * -1.0;
|
||||
else
|
||||
x = fabs (x);
|
||||
|
||||
blur = (dsdw.blur / 250.0) * 100.0;
|
||||
|
||||
if (dsdw.ver == 0)
|
||||
convert_legacy_psd_color (color, dsdw.color, space, ibm_pc_format);
|
||||
convert_legacy_psd_color (color, dsdw.color, space, img_a->ibm_pc_format);
|
||||
else if (dsdw.ver == 2)
|
||||
convert_legacy_psd_color (color, dsdw.natcolor, space, ibm_pc_format);
|
||||
convert_legacy_psd_color (color, dsdw.natcolor, space, img_a->ibm_pc_format);
|
||||
|
||||
convert_psd_mode (dsdw.blendsig, &mode);
|
||||
|
||||
|
|
|
|||
|
|
@ -796,6 +796,7 @@ typedef struct
|
|||
guint32 *alpha_id; /* Alpha channel ids (tattoos) */
|
||||
guint16 alpha_id_count; /* Number of alpha channel id items */
|
||||
guint16 quick_mask_id; /* Channel number containing quick mask */
|
||||
gint32 global_light_angle; /* Global Lighting Angle for Effect layers */
|
||||
|
||||
GimpColorProfile *cmyk_profile;
|
||||
gpointer cmyk_transform;
|
||||
|
|
|
|||
Loading…
Reference in a new issue