diff --git a/app/operations/gimpcurvesconfig.c b/app/operations/gimpcurvesconfig.c index c5f41cc00b..5e6c3972c9 100644 --- a/app/operations/gimpcurvesconfig.c +++ b/app/operations/gimpcurvesconfig.c @@ -712,3 +712,101 @@ gimp_curves_config_save_cruft (GimpCurvesConfig *config, return TRUE; } + +#define PS_CURVE_N_MAX_POINTS 19 + +/* Loads Photoshop .acv Curves preset */ +gboolean +gimp_curves_config_load_acv (GimpCurvesConfig *config, + GInputStream *input, + GError **error) +{ + GDataInputStream *data_input; + guint16 version = 0; + guint16 count = 0; + gint in[5][PS_CURVE_N_MAX_POINTS]; + gint out[5][PS_CURVE_N_MAX_POINTS]; + + g_return_val_if_fail (GIMP_IS_CURVES_CONFIG (config), FALSE); + g_return_val_if_fail (G_IS_INPUT_STREAM (input), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + data_input = g_data_input_stream_new (input); + + g_data_input_stream_set_byte_order (data_input, + G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN); + + version = g_data_input_stream_read_uint16 (data_input, NULL, error); + if (! version) + goto error; + + count = g_data_input_stream_read_uint16 (data_input, NULL, error); + if (! count) + goto error; + + count = CLAMP (count, 1, 5); + for (gint i = 0; i < count; i++) + { + guint16 points = 0; + + points = g_data_input_stream_read_uint16 (data_input, NULL, error); + if (! points || points > PS_CURVE_N_MAX_POINTS) + goto error; + + for (gint j = 0; j < points; j++) + { + /* Curves can start at 0, 0, so we'll check for an error instead */ + out[i][j] = g_data_input_stream_read_uint16 (data_input, NULL, error); + if (error && *error) + goto error; + + in[i][j] = g_data_input_stream_read_uint16 (data_input, NULL, error); + if (error && *error) + goto error; + } + if (points < PS_CURVE_N_MAX_POINTS) + { + in[i][points] = -1; + out[i][points] = -1; + } + } + + g_object_unref (data_input); + g_object_freeze_notify (G_OBJECT (config)); + + for (gint i = 0; i < count; i++) + { + GimpCurve *curve = config->curve[i]; + + gimp_data_freeze (GIMP_DATA (curve)); + + gimp_curve_set_curve_type (curve, GIMP_CURVE_SMOOTH); + gimp_curve_clear_points (curve); + + for (gint j = 0; j < PS_CURVE_N_MAX_POINTS; j++) + { + if (in[i][j] > -1 && out[i][j] > -1) + gimp_curve_add_point (curve, in[i][j] / 255.0, out[i][j] / 255.0); + else + break; + } + gimp_data_thaw (GIMP_DATA (curve)); + } + + config->trc = GIMP_TRC_NON_LINEAR; + g_object_notify (G_OBJECT (config), "trc"); + + g_object_thaw_notify (G_OBJECT (config)); + + return TRUE; + + error: + if (error && *error) + g_prefix_error (error, _("Could not read header: ")); + else + g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, + _("Could not read header: ")); + g_object_unref (data_input); + + return FALSE; +} diff --git a/app/operations/gimpcurvesconfig.h b/app/operations/gimpcurvesconfig.h index d5808471c9..ce21379a58 100644 --- a/app/operations/gimpcurvesconfig.h +++ b/app/operations/gimpcurvesconfig.h @@ -77,5 +77,8 @@ gboolean gimp_curves_config_save_cruft (GimpCurvesConfig *config, GOutputStream *output, GError **error); +gboolean gimp_curves_config_load_acv (GimpCurvesConfig *config, + GInputStream *input, + GError **error); #endif /* __GIMP_CURVES_CONFIG_H__ */ diff --git a/app/tools/gimpcurvestool.c b/app/tools/gimpcurvestool.c index 886e42d4cf..d373585a70 100644 --- a/app/tools/gimpcurvestool.c +++ b/app/tools/gimpcurvestool.c @@ -752,6 +752,16 @@ gimp_curves_tool_settings_import (GimpFilterTool *filter_tool, &bytes_read, NULL, error) || bytes_read != sizeof (header)) { + /* A Photoshop .acv curves preset file might be smaller than + * 64 bytes, so we'll check if that's the case */ + if (bytes_read > 2 && header[0] == 0 && + (header[1] == 1 || header[1] == 4)) + { + g_seekable_seek (G_SEEKABLE (input), 0, G_SEEK_SET, NULL, NULL); + + return gimp_curves_config_load_acv (config, input, error); + } + if (error && *error) g_prefix_error (error, _("Could not read header: ")); else @@ -765,6 +775,10 @@ gimp_curves_tool_settings_import (GimpFilterTool *filter_tool, if (g_str_has_prefix (header, "# GIMP Curves File\n")) return gimp_curves_config_load_cruft (config, input, error); + if (bytes_read > 2 && header[0] == 0 && + (header[1] == 1 || header[1] == 4)) + return gimp_curves_config_load_acv (config, input, error); + return GIMP_FILTER_TOOL_CLASS (parent_class)->settings_import (filter_tool, input, error);