Save patterns with alpha channels, and remove warning while loading

2003-06-28  Dave Neary  <bolsh@gimp.org>

        * plug-ins/common/pat.c: Save patterns with alpha
        channels, and remove warning while loading patterns
        with an alpha channel.

        * app/core/gimppattern.c
        * app/core/gimpdrawable-bucket-fill.c
        * app/paint/gimpclone.c: Make cloning from a pattern
        source, and bucket filling with a pattern, work when
        there's an alpha channel present in the pattern.

        I'm not particularly happy with this, because the only
        way to tell whether there's an alpha channel or not is
        by the number of bytes in the TempBuf the clone and
        bucketfill routines get passed, which is rather
        restrictive. It would be nice if a TempBuf had a
        _has_alpha () method.
This commit is contained in:
Dave Neary
2003-06-28 12:36:52 +00:00
committed by David Neary
parent e14e158e70
commit 46ca5a780b
7 changed files with 85 additions and 22 deletions

View File

@ -1,3 +1,22 @@
2003-06-28 Dave Neary <bolsh@gimp.org>
* plug-ins/common/pat.c: Save patterns with alpha
channels, and remove warning while loading patterns
with an alpha channel.
* app/core/gimppattern.c
* app/core/gimpdrawable-bucket-fill.c
* app/paint/gimpclone.c: Make cloning from a pattern
source, and bucket filling with a pattern, work when
there's an alpha channel present in the pattern.
I'm not particularly happy with this, because the only
way to tell whether there's an alpha channel or not is
by the number of bytes in the TempBuf the clone and
bucketfill routines get passed, which is rather
restrictive. It would be nice if a TempBuf had a
_has_alpha () method.
2003-06-28 Michael Natterer <mitch@gimp.org>
* app/core/gimpcontext.h: removed enum GimpContextPropType and

View File

@ -180,17 +180,25 @@ gimp_drawable_bucket_fill_full (GimpDrawable *drawable,
/* If the pattern doesn't match the image in terms of color type,
* transform it. (ie pattern is RGB, image is indexed)
*/
if (((pattern->mask->bytes == 3) && ! gimp_drawable_is_rgb (drawable)) ||
((pattern->mask->bytes == 1) && ! gimp_drawable_is_gray (drawable)))
if (((pattern->mask->bytes == 3 || pattern->mask->bytes == 4 ) && ! gimp_drawable_is_rgb (drawable)) ||
((pattern->mask->bytes == 1 || pattern->mask->bytes == 2 ) && ! gimp_drawable_is_gray (drawable)))
{
guchar *d1, *d2;
gint size;
gint size, in_bytes, out_bytes;
if ((pattern->mask->bytes == 1) && gimp_drawable_is_rgb (drawable))
if ((pattern->mask->bytes == 2) && gimp_drawable_is_rgb (drawable))
pat_buf = temp_buf_new (pattern->mask->width,
pattern->mask->height,
4, 0, 0, NULL);
else if ((pattern->mask->bytes == 1) && gimp_drawable_is_rgb (drawable))
pat_buf = temp_buf_new (pattern->mask->width,
pattern->mask->height,
3, 0, 0, NULL);
else
else if ((pattern->mask->bytes == 4) && gimp_drawable_is_gray (drawable))
pat_buf = temp_buf_new (pattern->mask->width,
pattern->mask->height,
2, 0, 0, NULL);
else
pat_buf = temp_buf_new (pattern->mask->width,
pattern->mask->height,
1, 0, 0, NULL);
@ -199,13 +207,21 @@ gimp_drawable_bucket_fill_full (GimpDrawable *drawable,
d2 = temp_buf_data (pat_buf);
size = pattern->mask->width * pattern->mask->height;
in_bytes = pattern->mask->bytes;
out_bytes = pat_buf->bytes;
while (size--)
{
gimp_image_transform_color (gimage, drawable, d1, d2,
(pattern->mask->bytes == 3) ?
(in_bytes == 3 ||
in_bytes == 4) ?
GIMP_RGB : GIMP_GRAY);
d1 += pattern->mask->bytes;
d2 += pat_buf->bytes;
/* Handle alpha */
if (in_bytes == 4 ||
in_bytes == 2 )
d2[out_bytes - 1] = d1[in_bytes - 1];
d1 += in_bytes;
d2 += out_bytes;
}
new_buf = TRUE;
@ -438,6 +454,20 @@ gimp_drawable_bucket_fill_line_pattern (guchar *buf,
(y % pattern->height) * pattern->width * pattern->bytes;
alpha = (has_alpha) ? bytes - 1 : bytes;
/*
* image data = pattern data for all but alpha
*
* If (image has alpha)
* if (there's a mask)
* image data = mask for alpha;
* else
* image data = opaque for alpha.
*
* if (pattern has alpha)
* multiply existing alpha channel by pattern alpha
* (normalised to (0..1))
*/
for (i = 0; i < width; i++)
{
p = pat + ((i + x) % pattern->width) * pattern->bytes;
@ -447,10 +477,17 @@ gimp_drawable_bucket_fill_line_pattern (guchar *buf,
if (has_alpha)
{
if (mask)
if (mask)
buf[alpha] = *mask++;
else
else
buf[alpha] = OPAQUE_OPACITY;
if (pattern->bytes == 2 || pattern->bytes == 4)
{
buf[alpha] =
(guchar)(buf[alpha] *
(p[alpha]/(gdouble)OPAQUE_OPACITY));
}
}
buf += bytes;

View File

@ -374,6 +374,7 @@ gimp_pattern_load (const gchar *filename,
}
/* Check for supported bit depths */
/*
if (header.bytes != 1 && header.bytes != 3)
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
@ -383,6 +384,7 @@ gimp_pattern_load (const gchar *filename,
header.bytes, filename);
goto error;
}
*/
/* Read in the pattern name */
if ((bn_size = (header.header_size - sizeof (header))))

View File

@ -374,6 +374,7 @@ gimp_pattern_load (const gchar *filename,
}
/* Check for supported bit depths */
/*
if (header.bytes != 1 && header.bytes != 3)
{
g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ,
@ -383,6 +384,7 @@ gimp_pattern_load (const gchar *filename,
header.bytes, filename);
goto error;
}
*/
/* Read in the pattern name */
if ((bn_size = (header.header_size - sizeof (header))))

View File

@ -514,7 +514,8 @@ gimp_clone_line_pattern (GimpImage *dest,
pat = temp_buf_data (pattern->mask) +
(y % pattern->mask->height) * pattern->mask->width * pattern->mask->bytes;
color_type = (pattern->mask->bytes == 3) ? GIMP_RGB : GIMP_GRAY;
color_type = (pattern->mask->bytes == 3 ||
pattern->mask->bytes == 4) ? GIMP_RGB : GIMP_GRAY;
alpha = bytes - 1;
@ -524,7 +525,10 @@ gimp_clone_line_pattern (GimpImage *dest,
gimp_image_transform_color (dest, drawable, p, d, color_type);
d[alpha] = OPAQUE_OPACITY;
if (pattern->mask->bytes == 2 || pattern->mask->bytes == 4)
d[alpha] = p[alpha];
else
d[alpha] = OPAQUE_OPACITY;
d += bytes;
}

View File

@ -514,7 +514,8 @@ gimp_clone_line_pattern (GimpImage *dest,
pat = temp_buf_data (pattern->mask) +
(y % pattern->mask->height) * pattern->mask->width * pattern->mask->bytes;
color_type = (pattern->mask->bytes == 3) ? GIMP_RGB : GIMP_GRAY;
color_type = (pattern->mask->bytes == 3 ||
pattern->mask->bytes == 4) ? GIMP_RGB : GIMP_GRAY;
alpha = bytes - 1;
@ -524,7 +525,10 @@ gimp_clone_line_pattern (GimpImage *dest,
gimp_image_transform_color (dest, drawable, p, d, color_type);
d[alpha] = OPAQUE_OPACITY;
if (pattern->mask->bytes == 2 || pattern->mask->bytes == 4)
d[alpha] = p[alpha];
else
d[alpha] = OPAQUE_OPACITY;
d += bytes;
}

View File

@ -121,7 +121,7 @@ query (void)
"Tim Newsome",
"1997",
"<Save>/PAT",
"RGB, GRAY",
"RGB*, GRAY*",
GIMP_PLUGIN,
G_N_ELEMENTS (save_args), 0,
save_args, NULL);
@ -187,7 +187,8 @@ run (gchar *name,
gimp_ui_init ("pat", FALSE);
export = gimp_export_image (&image_ID, &drawable_ID, "PAT",
GIMP_EXPORT_CAN_HANDLE_GRAY |
GIMP_EXPORT_CAN_HANDLE_RGB);
GIMP_EXPORT_CAN_HANDLE_RGB |
GIMP_EXPORT_CAN_HANDLE_ALPHA);
if (export == GIMP_EXPORT_CANCEL)
{
values[0].data.d_status = GIMP_PDB_CANCEL;
@ -316,9 +317,6 @@ load_image (gchar *filename)
case 2:
base_type = GIMP_GRAY;
image_type = GIMP_GRAYA_IMAGE;
g_message ("Your pattern has an aplha channel,\n"
"please flatten and save it again to fix this.\n"
"Loading it anyway...");
break;
case 3:
base_type = GIMP_RGB;
@ -327,9 +325,6 @@ load_image (gchar *filename)
case 4:
base_type = GIMP_RGB;
image_type = GIMP_RGBA_IMAGE;
g_message ("Your pattern has an aplha channel,\n"
"please flatten and save it again to fix this.\n"
"Loading it anyway...");
break;
default:
g_message ("Unsupported pattern depth: %d\n"