mirror of https://github.com/GNOME/gimp.git
plug-ins: Add method to load external PSD metadata
Creates a new public procedure that can be used by JPEG/TIFF files to load any PSD-formatted metadata they have. This consolidates code to the PSD plug-in, and lets JPEG/TIFF get immediate updates as the PSD plug-in improves its own metadata support. Note that only Macintosh formatted metadata is currently supported by the PSD plug-in; IBM PC formatted metadata is reversed and not yet interpreted.
This commit is contained in:
parent
8bd07e468b
commit
b788513bcc
|
@ -57,6 +57,10 @@ static PSDlayer ** read_layer_block (PSDimage *img_a,
|
|||
GInputStream *input,
|
||||
GError **error);
|
||||
|
||||
static PSDlayer ** read_layer_info (PSDimage *img_a,
|
||||
GInputStream *input,
|
||||
GError **error);
|
||||
|
||||
static gint read_merged_image_block (PSDimage *img_a,
|
||||
GInputStream *input,
|
||||
GError **error);
|
||||
|
@ -205,6 +209,7 @@ load_image (GFile *file,
|
|||
/* ----- Read the PSD file Layer & Mask block ----- */
|
||||
IFDBG(2) g_debug ("Read layer & mask block at offset %" G_GOFFSET_FORMAT,
|
||||
PSD_TELL(input));
|
||||
img_a.mask_layer_len = 0;
|
||||
lyr_a = read_layer_block (&img_a, input, &error);
|
||||
|
||||
if (merged_image_only)
|
||||
|
@ -297,6 +302,137 @@ load_image (GFile *file,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Loading metadata for external file formats */
|
||||
GimpImage * load_image_metadata (GFile *file,
|
||||
gint data_length,
|
||||
GimpImage *image,
|
||||
gboolean for_layers,
|
||||
gboolean is_cmyk,
|
||||
PSDSupport *unsupported_features,
|
||||
GError **error)
|
||||
{
|
||||
GInputStream *input;
|
||||
PSDimage img_a;
|
||||
gboolean profile_loaded;
|
||||
gboolean resolution_loaded;
|
||||
|
||||
/* Convert metadata file to PSD format */
|
||||
input = G_INPUT_STREAM (g_file_read (file, NULL, error));
|
||||
if (! input)
|
||||
{
|
||||
g_object_unref (input);
|
||||
return image;
|
||||
}
|
||||
|
||||
/* Load metadata for external file format */
|
||||
img_a.image_res_len = data_length;
|
||||
img_a.image_res_start = 0;
|
||||
img_a.version = 1;
|
||||
img_a.layer_selection = NULL;
|
||||
img_a.columns = gimp_image_get_width (image);
|
||||
img_a.rows = gimp_image_get_height(image);
|
||||
img_a.base_type = gimp_image_get_base_type (image);
|
||||
img_a.merged_image_only = FALSE;
|
||||
img_a.alpha_names = NULL;
|
||||
|
||||
initialize_unsupported (unsupported_features);
|
||||
img_a.unsupported_features = unsupported_features;
|
||||
|
||||
if (! for_layers)
|
||||
{
|
||||
PSDimageres res_a;
|
||||
|
||||
while (PSD_TELL (input) < img_a.image_res_start + img_a.image_res_len)
|
||||
{
|
||||
if (get_image_resource_header (&res_a, input, error) < 0)
|
||||
break;
|
||||
|
||||
if (res_a.data_start + res_a.data_len >
|
||||
img_a.image_res_start + img_a.image_res_len)
|
||||
{
|
||||
IFDBG(1) g_debug ("Unexpected end of image resource data");
|
||||
break;
|
||||
}
|
||||
|
||||
if (load_image_resource (&res_a, image, &img_a, input,
|
||||
&profile_loaded, &resolution_loaded,
|
||||
error) < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PSDlayer **lyr_a = NULL;
|
||||
guint64 skip;
|
||||
gchar key[4];
|
||||
|
||||
/* Skip the first 8 bytes to get it in the correct
|
||||
* format for the layer block */
|
||||
if (! psd_read_len (input, &skip, img_a.version, error))
|
||||
{
|
||||
g_object_unref (input);
|
||||
return image;
|
||||
}
|
||||
if (psd_read (input, &key, 4, error) < 4)
|
||||
{
|
||||
g_object_unref (input);
|
||||
return image;
|
||||
}
|
||||
|
||||
/* Setting up PSDImage structure */
|
||||
if (memcmp (key, "Layr", 4) == 0)
|
||||
{
|
||||
img_a.bps = 8;
|
||||
}
|
||||
else if (memcmp (key, "Lr16", 4) == 0)
|
||||
{
|
||||
img_a.bps = 16;
|
||||
}
|
||||
else if (memcmp (key, "Lr32", 4) == 0)
|
||||
{
|
||||
img_a.bps = 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_object_unref (input);
|
||||
return image;
|
||||
}
|
||||
|
||||
switch (gimp_image_get_base_type (image))
|
||||
{
|
||||
case GIMP_RGB:
|
||||
img_a.color_mode = PSD_RGB;
|
||||
break;
|
||||
|
||||
case GIMP_GRAY:
|
||||
img_a.color_mode = PSD_GRAYSCALE;
|
||||
break;
|
||||
|
||||
case GIMP_INDEXED:
|
||||
img_a.color_mode = PSD_INDEXED;
|
||||
break;
|
||||
}
|
||||
if (is_cmyk)
|
||||
img_a.color_mode = PSD_CMYK;
|
||||
|
||||
/* Set layer block size from metadata */
|
||||
img_a.mask_layer_len = data_length;
|
||||
lyr_a = read_layer_block (&img_a, input, error);
|
||||
|
||||
if (! lyr_a)
|
||||
{
|
||||
g_object_unref (input);
|
||||
return image;
|
||||
}
|
||||
|
||||
add_layers (image, &img_a, lyr_a, input, error);
|
||||
}
|
||||
|
||||
g_object_unref (input);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
/* Local functions */
|
||||
|
||||
|
@ -1082,13 +1218,20 @@ read_layer_block (PSDimage *img_a,
|
|||
guint64 block_end;
|
||||
gint block_len_size = (img_a->version == 1 ? 4 : 8);
|
||||
|
||||
/* If layer data is being loaded for non-PSD files (like TIFF),
|
||||
* then mask_layer_len will have its size preloaded */
|
||||
if (img_a->mask_layer_len == 0)
|
||||
{
|
||||
if (! psd_read_len (input, &block_len, img_a->version, error))
|
||||
{
|
||||
img_a->num_layers = -1;
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
img_a->mask_layer_len = block_len;
|
||||
}
|
||||
}
|
||||
|
||||
IFDBG(1) g_debug ("Layer and mask block size = %" G_GOFFSET_FORMAT, img_a->mask_layer_len);
|
||||
|
||||
|
|
|
@ -29,6 +29,15 @@ GimpImage * load_image (GFile *file,
|
|||
PSDSupport *unsupported_features,
|
||||
GError **error);
|
||||
|
||||
GimpImage * load_image_metadata
|
||||
(GFile *file,
|
||||
gint data_length,
|
||||
GimpImage *image,
|
||||
gboolean for_layers,
|
||||
gboolean is_cmyk,
|
||||
PSDSupport *unsupported_features,
|
||||
GError **error);
|
||||
|
||||
void load_dialog (PSDSupport *unsupported_features);
|
||||
|
||||
|
||||
|
|
|
@ -74,6 +74,11 @@ static GimpValueArray * psd_save (GimpProcedure *procedure,
|
|||
GFile *file,
|
||||
const GimpValueArray *args,
|
||||
gpointer run_data);
|
||||
static GimpValueArray * psd_load_metadata (GimpProcedure *procedure,
|
||||
GimpRunMode run_mode,
|
||||
GFile *file,
|
||||
const GimpValueArray *args,
|
||||
gpointer run_data);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (Psd, psd, GIMP_TYPE_PLUG_IN)
|
||||
|
@ -106,6 +111,7 @@ psd_query_procedures (GimpPlugIn *plug_in)
|
|||
list = g_list_append (list, g_strdup (LOAD_PROC));
|
||||
list = g_list_append (list, g_strdup (LOAD_MERGED_PROC));
|
||||
list = g_list_append (list, g_strdup (SAVE_PROC));
|
||||
list = g_list_append (list, g_strdup (LOAD_METADATA_PROC));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
@ -258,6 +264,46 @@ psd_create_procedure (GimpPlugIn *plug_in,
|
|||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
}
|
||||
else if (! strcmp (name, LOAD_METADATA_PROC))
|
||||
{
|
||||
procedure = gimp_load_procedure_new (plug_in, name,
|
||||
GIMP_PDB_PROC_TYPE_PLUGIN,
|
||||
psd_load_metadata, NULL, NULL);
|
||||
|
||||
gimp_procedure_set_documentation (procedure,
|
||||
"Loads Photoshop-format metadata "
|
||||
"from other file formats.",
|
||||
"Loads Photoshop-format metadata "
|
||||
"from other file formats.",
|
||||
name);
|
||||
gimp_procedure_set_attribution (procedure,
|
||||
"John Marshall",
|
||||
"John Marshall",
|
||||
"2007");
|
||||
GIMP_PROC_ARG_INT (procedure, "size",
|
||||
"Metadata size",
|
||||
NULL,
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_image ("image",
|
||||
"image",
|
||||
"The image",
|
||||
FALSE,
|
||||
GIMP_PARAM_READWRITE));
|
||||
GIMP_PROC_ARG_BOOLEAN (procedure, "metadata-type",
|
||||
"Metadata type",
|
||||
"If the metadata contains image or "
|
||||
"layer PSD resources.",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
GIMP_PROC_ARG_BOOLEAN (procedure, "cmyk",
|
||||
"CMYK",
|
||||
"If the layer metadata needs to be "
|
||||
"converted from CMYK colorspace.",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
}
|
||||
|
||||
return procedure;
|
||||
}
|
||||
|
@ -453,3 +499,55 @@ psd_save (GimpProcedure *procedure,
|
|||
|
||||
return gimp_procedure_new_return_values (procedure, status, error);
|
||||
}
|
||||
|
||||
static GimpValueArray *
|
||||
psd_load_metadata (GimpProcedure *procedure,
|
||||
GimpRunMode run_mode,
|
||||
GFile *file,
|
||||
const GimpValueArray *args,
|
||||
gpointer run_data)
|
||||
{
|
||||
GimpValueArray *return_vals;
|
||||
GimpImage *image;
|
||||
gint data_length;
|
||||
PSDSupport unsupported_features;
|
||||
gboolean is_layer = FALSE;
|
||||
gboolean is_cmyk = FALSE;
|
||||
GError *error = NULL;
|
||||
|
||||
gegl_init (NULL, NULL);
|
||||
|
||||
/* Retrieve image */
|
||||
if (gimp_value_array_length (args) > 1)
|
||||
{
|
||||
data_length = g_value_get_int (gimp_value_array_index (args, 0));
|
||||
image = g_value_get_object (gimp_value_array_index (args, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
return gimp_procedure_new_return_values (procedure,
|
||||
GIMP_PDB_EXECUTION_ERROR,
|
||||
error);
|
||||
}
|
||||
|
||||
if (gimp_value_array_length (args) > 2)
|
||||
is_layer = g_value_get_boolean (gimp_value_array_index (args, 2));
|
||||
if (gimp_value_array_length (args) > 3)
|
||||
is_cmyk = g_value_get_boolean (gimp_value_array_index (args, 3));
|
||||
|
||||
image = load_image_metadata (file, data_length, image, is_layer, is_cmyk,
|
||||
&unsupported_features, &error);
|
||||
|
||||
if (! image)
|
||||
return gimp_procedure_new_return_values (procedure,
|
||||
GIMP_PDB_EXECUTION_ERROR,
|
||||
error);
|
||||
|
||||
return_vals = gimp_procedure_new_return_values (procedure,
|
||||
GIMP_PDB_SUCCESS,
|
||||
NULL);
|
||||
|
||||
GIMP_VALUES_SET_IMAGE (return_vals, 1, image);
|
||||
|
||||
return return_vals;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#define LOAD_MERGED_PROC "file-psd-load-merged"
|
||||
#define LOAD_THUMB_PROC "file-psd-load-thumb"
|
||||
#define SAVE_PROC "file-psd-save"
|
||||
#define LOAD_METADATA_PROC "file-psd-load-metadata"
|
||||
#define PLUG_IN_BINARY "file-psd"
|
||||
#define PLUG_IN_ROLE "gimp-file-psd"
|
||||
|
||||
|
|
Loading…
Reference in New Issue