mirror of https://github.com/GNOME/gimp.git
plug-ins: in file-psd, read and write group-layer masks
Add support for loading and saving group-layer masks from/to PSD files.
This commit is contained in:
parent
7e661d3ca9
commit
af6b891b64
|
@ -1399,6 +1399,11 @@ add_layers (gint32 image_id,
|
||||||
*/
|
*/
|
||||||
g_array_remove_index (parent_group_stack,
|
g_array_remove_index (parent_group_stack,
|
||||||
parent_group_stack->len - 1);
|
parent_group_stack->len - 1);
|
||||||
|
|
||||||
|
gimp_drawable_offsets (layer_id, &l_x, &l_y);
|
||||||
|
|
||||||
|
l_w = gimp_drawable_width (layer_id);
|
||||||
|
l_h = gimp_drawable_height (layer_id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1529,7 +1534,7 @@ add_layers (gint32 image_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Layer mask */
|
/* Layer mask */
|
||||||
if (user_mask && lyr_a[lidx]->group_type == 0)
|
if (user_mask && lyr_a[lidx]->group_type != 3)
|
||||||
{
|
{
|
||||||
if (empty_mask)
|
if (empty_mask)
|
||||||
{
|
{
|
||||||
|
|
|
@ -191,7 +191,8 @@ static void write_datablock_luni (FILE *fd,
|
||||||
static void write_pixel_data (FILE *fd,
|
static void write_pixel_data (FILE *fd,
|
||||||
gint32 drawableID,
|
gint32 drawableID,
|
||||||
glong *ChanLenPosition,
|
glong *ChanLenPosition,
|
||||||
gint32 rowlenOffset);
|
gint32 rowlenOffset,
|
||||||
|
gboolean write_mask);
|
||||||
|
|
||||||
static gint32 create_merged_image (gint32 imageID);
|
static gint32 create_merged_image (gint32 imageID);
|
||||||
|
|
||||||
|
@ -959,7 +960,8 @@ save_layer_and_mask (FILE *fd,
|
||||||
write_gint32 (fd, offset_y + layerHeight, "Layer bottom");
|
write_gint32 (fd, offset_y + layerHeight, "Layer bottom");
|
||||||
write_gint32 (fd, offset_x + layerWidth, "Layer right");
|
write_gint32 (fd, offset_x + layerWidth, "Layer right");
|
||||||
|
|
||||||
hasMask = (gimp_layer_get_mask(PSDImageData.lLayers[i].id) == -1 ) ? 0 : 1;
|
hasMask = (PSDImageData.lLayers[i].type != PSD_LAYER_TYPE_GROUP_END &&
|
||||||
|
gimp_layer_get_mask (PSDImageData.lLayers[i].id) != -1);
|
||||||
nChannelsLayer = nChansLayer (PSDImageData.baseType,
|
nChannelsLayer = nChansLayer (PSDImageData.baseType,
|
||||||
gimp_drawable_has_alpha (PSDImageData.lLayers[i].id),
|
gimp_drawable_has_alpha (PSDImageData.lLayers[i].id),
|
||||||
hasMask);
|
hasMask);
|
||||||
|
@ -1022,19 +1024,28 @@ save_layer_and_mask (FILE *fd,
|
||||||
ExtraDataPos = ftell (fd); /* Position of Extra Data size */
|
ExtraDataPos = ftell (fd); /* Position of Extra Data size */
|
||||||
write_gint32 (fd, 0, "Extra data size");
|
write_gint32 (fd, 0, "Extra data size");
|
||||||
|
|
||||||
mask = gimp_layer_get_mask (PSDImageData.lLayers[i].id);
|
if (hasMask)
|
||||||
if (mask >= 0)
|
|
||||||
{
|
{
|
||||||
gint maskWidth = gimp_drawable_width (mask);
|
gint maskOffset_x;
|
||||||
gint maskHeight = gimp_drawable_height (mask);
|
gint maskOffset_y;
|
||||||
gboolean apply = gimp_layer_get_apply_mask (PSDImageData.lLayers[i].id);
|
gint maskWidth;
|
||||||
|
gint maskHeight;
|
||||||
|
gboolean apply;
|
||||||
|
|
||||||
|
mask = gimp_layer_get_mask (PSDImageData.lLayers[i].id);
|
||||||
|
|
||||||
|
gimp_drawable_offsets (mask, &maskOffset_x, &maskOffset_y);
|
||||||
|
|
||||||
|
maskWidth = gimp_drawable_width (mask);
|
||||||
|
maskHeight = gimp_drawable_height (mask);
|
||||||
|
apply = gimp_layer_get_apply_mask (PSDImageData.lLayers[i].id);
|
||||||
|
|
||||||
IFDBG printf ("\t\tLayer mask size: %d\n", 20);
|
IFDBG printf ("\t\tLayer mask size: %d\n", 20);
|
||||||
write_gint32 (fd, 20, "Layer mask size");
|
write_gint32 (fd, 20, "Layer mask size");
|
||||||
write_gint32 (fd, offset_y, "Layer mask top");
|
write_gint32 (fd, maskOffset_y, "Layer mask top");
|
||||||
write_gint32 (fd, offset_x, "Layer mask left");
|
write_gint32 (fd, maskOffset_x, "Layer mask left");
|
||||||
write_gint32 (fd, offset_y + maskHeight, "Layer mask bottom");
|
write_gint32 (fd, maskOffset_y + maskHeight, "Layer mask bottom");
|
||||||
write_gint32 (fd, offset_x + maskWidth, "Layer mask right");
|
write_gint32 (fd, maskOffset_x + maskWidth, "Layer mask right");
|
||||||
write_gchar (fd, 0, "Layer mask default color");
|
write_gchar (fd, 0, "Layer mask default color");
|
||||||
flags = (0 | /* position relative to layer */
|
flags = (0 | /* position relative to layer */
|
||||||
(apply ? 0 : 1) << 1 | /* layer mask disabled */
|
(apply ? 0 : 1) << 1 | /* layer mask disabled */
|
||||||
|
@ -1140,7 +1151,8 @@ save_layer_and_mask (FILE *fd,
|
||||||
gimp_progress_update ((PSDImageData.nLayers - i - 1.0) / (PSDImageData.nLayers + 1.0));
|
gimp_progress_update ((PSDImageData.nLayers - i - 1.0) / (PSDImageData.nLayers + 1.0));
|
||||||
|
|
||||||
IFDBG printf ("\t\tWriting pixel data for layer slot %d\n", i);
|
IFDBG printf ("\t\tWriting pixel data for layer slot %d\n", i);
|
||||||
write_pixel_data(fd, PSDImageData.lLayers[i].id, ChannelLengthPos[i], 0);
|
write_pixel_data (fd, PSDImageData.lLayers[i].id, ChannelLengthPos[i], 0,
|
||||||
|
PSDImageData.lLayers[i].type != PSD_LAYER_TYPE_GROUP_END);
|
||||||
g_free (ChannelLengthPos[i]);
|
g_free (ChannelLengthPos[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1170,10 +1182,12 @@ static void
|
||||||
write_pixel_data (FILE *fd,
|
write_pixel_data (FILE *fd,
|
||||||
gint32 drawableID,
|
gint32 drawableID,
|
||||||
glong *ChanLenPosition,
|
glong *ChanLenPosition,
|
||||||
gint32 ltable_offset)
|
gint32 ltable_offset,
|
||||||
|
gboolean write_mask)
|
||||||
{
|
{
|
||||||
GeglBuffer *buffer = gimp_drawable_get_buffer (drawableID);
|
GeglBuffer *buffer = gimp_drawable_get_buffer (drawableID);
|
||||||
const Babl *format;
|
const Babl *format;
|
||||||
|
gint32 maskID;
|
||||||
gint32 tile_height = gimp_tile_height ();
|
gint32 tile_height = gimp_tile_height ();
|
||||||
gint32 height = gegl_buffer_get_height (buffer);
|
gint32 height = gegl_buffer_get_height (buffer);
|
||||||
gint32 width = gegl_buffer_get_width (buffer);
|
gint32 width = gegl_buffer_get_width (buffer);
|
||||||
|
@ -1190,8 +1204,13 @@ write_pixel_data (FILE *fd,
|
||||||
IFDBG printf (" Function: write_pixel_data, drw %d, lto %d\n",
|
IFDBG printf (" Function: write_pixel_data, drw %d, lto %d\n",
|
||||||
drawableID, ltable_offset);
|
drawableID, ltable_offset);
|
||||||
|
|
||||||
/* groups have empty channel data */
|
if (write_mask)
|
||||||
if (gimp_item_is_group (drawableID))
|
maskID = gimp_layer_get_mask (drawableID);
|
||||||
|
else
|
||||||
|
maskID = -1;
|
||||||
|
|
||||||
|
/* groups have empty channel data, but may have a mask */
|
||||||
|
if (gimp_item_is_group (drawableID) && maskID == -1)
|
||||||
{
|
{
|
||||||
width = 0;
|
width = 0;
|
||||||
height = 0;
|
height = 0;
|
||||||
|
@ -1216,6 +1235,13 @@ write_pixel_data (FILE *fd,
|
||||||
|
|
||||||
data = g_new (guchar, MIN (height, tile_height) * width * bytes);
|
data = g_new (guchar, MIN (height, tile_height) * width * bytes);
|
||||||
|
|
||||||
|
/* groups have empty channel data */
|
||||||
|
if (gimp_item_is_group (drawableID))
|
||||||
|
{
|
||||||
|
width = 0;
|
||||||
|
height = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < bytes; i++)
|
for (i = 0; i < bytes; i++)
|
||||||
{
|
{
|
||||||
gint chan;
|
gint chan;
|
||||||
|
@ -1294,15 +1320,14 @@ write_pixel_data (FILE *fd,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write layer mask, as last channel, id -2 */
|
/* Write layer mask, as last channel, id -2 */
|
||||||
if (gimp_item_is_layer (drawableID))
|
|
||||||
{
|
|
||||||
gint32 maskID = gimp_layer_get_mask (drawableID);
|
|
||||||
|
|
||||||
if (maskID != -1)
|
if (maskID != -1)
|
||||||
{
|
{
|
||||||
GeglBuffer *mbuffer = gimp_drawable_get_buffer (maskID);
|
GeglBuffer *mbuffer = gimp_drawable_get_buffer (maskID);
|
||||||
const Babl *mformat = get_mask_format(maskID);
|
const Babl *mformat = get_mask_format(maskID);
|
||||||
|
|
||||||
|
width = gegl_buffer_get_width (buffer);
|
||||||
|
height = gegl_buffer_get_height (buffer);
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
|
|
||||||
if (ChanLenPosition)
|
if (ChanLenPosition)
|
||||||
|
@ -1369,7 +1394,6 @@ write_pixel_data (FILE *fd,
|
||||||
|
|
||||||
g_object_unref (mbuffer);
|
g_object_unref (mbuffer);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref (buffer);
|
g_object_unref (buffer);
|
||||||
|
|
||||||
|
@ -1409,7 +1433,7 @@ save_data (FILE *fd,
|
||||||
|
|
||||||
IFDBG printf ("\t\tWriting compressed image data\n");
|
IFDBG printf ("\t\tWriting compressed image data\n");
|
||||||
write_pixel_data (fd, PSDImageData.merged_layer,
|
write_pixel_data (fd, PSDImageData.merged_layer,
|
||||||
NULL, offset);
|
NULL, offset, FALSE);
|
||||||
|
|
||||||
chan = nChansLayer (PSDImageData.baseType,
|
chan = nChansLayer (PSDImageData.baseType,
|
||||||
gimp_drawable_has_alpha(PSDImageData.merged_layer), 0);
|
gimp_drawable_has_alpha(PSDImageData.merged_layer), 0);
|
||||||
|
@ -1419,7 +1443,7 @@ save_data (FILE *fd,
|
||||||
IFDBG printf ("\t\tWriting compressed channel data for channel %d\n",
|
IFDBG printf ("\t\tWriting compressed channel data for channel %d\n",
|
||||||
i);
|
i);
|
||||||
write_pixel_data (fd, PSDImageData.lChannels[i], NULL,
|
write_pixel_data (fd, PSDImageData.lChannels[i], NULL,
|
||||||
offset + 2*imageHeight*chan); //check how imgs are channels here
|
offset + 2*imageHeight*chan, FALSE); //check how imgs are channels here
|
||||||
chan++;
|
chan++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue