diff --git a/plug-ins/file-psd/psd-image-res-load.c b/plug-ins/file-psd/psd-image-res-load.c index 171e752f30..234c9abc39 100644 --- a/plug-ins/file-psd/psd-image-res-load.c +++ b/plug-ins/file-psd/psd-image-res-load.c @@ -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, diff --git a/plug-ins/file-psd/psd-layer-res-load.c b/plug-ins/file-psd/psd-layer-res-load.c index f839f3272e..802c63eeaf 100644 --- a/plug-ins/file-psd/psd-layer-res-load.c +++ b/plug-ins/file-psd/psd-layer-res-load.c @@ -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])); diff --git a/plug-ins/file-psd/psd-load.c b/plug-ins/file-psd/psd-load.c index f7003a00b1..f5a7650028 100644 --- a/plug-ins/file-psd/psd-load.c +++ b/plug-ins/file-psd/psd-load.c @@ -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); diff --git a/plug-ins/file-psd/psd.h b/plug-ins/file-psd/psd.h index 92723ba59f..8c32d1f7e0 100644 --- a/plug-ins/file-psd/psd.h +++ b/plug-ins/file-psd/psd.h @@ -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;