use gimp_preview_area_draw when the opacity is 0 or 255, instead of

*  libgimpwidgets/gimppreviewarea.c: (gimp_preview_area_blend)
  use gimp_preview_area_draw when the opacity is 0 or 255, instead of
  duplicating code.
This commit is contained in:
David Odin 2004-09-08 11:52:05 +00:00
parent 099458184b
commit c59a6de934
2 changed files with 245 additions and 398 deletions

View File

@ -1,3 +1,9 @@
2004-09-08 DindinX <david@dindinx.org>
* libgimpwidgets/gimppreviewarea.c: (gimp_preview_area_blend)
use gimp_preview_area_draw when the opacity is 0 or 255, instead of
duplicating code.
2004-09-07 Sven Neumann <sven@gimp.org>
* libgimpwidgets/gimpwidgets.def: added new entries.

View File

@ -595,176 +595,133 @@ gimp_preview_area_blend (GimpPreviewArea *area,
g_return_if_fail (rowstride1 > 0);
g_return_if_fail (rowstride2 > 0);
if (x + width < 0 || x >= area->width)
return;
if (y + height < 0 || y >= area->height)
return;
if (x < 0)
switch (opacity)
{
gint bpp;
case 0:
gimp_preview_area_draw (area, x, y, width, height,
type, buf1, rowstride1);
return;
switch (type)
case 255:
gimp_preview_area_draw (area, x, y, width, height,
type, buf2, rowstride2);
return;
default:
if (x + width < 0 || x >= area->width)
return;
if (y + height < 0 || y >= area->height)
return;
if (x < 0)
{
case GIMP_GRAY_IMAGE:
case GIMP_INDEXED_IMAGE:
bpp = 1;
break;
case GIMP_GRAYA_IMAGE:
case GIMP_INDEXEDA_IMAGE:
bpp = 2;
break;
case GIMP_RGB_IMAGE:
bpp = 3;
break;
case GIMP_RGBA_IMAGE:
bpp = 4;
break;
default:
g_return_if_reached ();
break;
gint bpp;
switch (type)
{
case GIMP_GRAY_IMAGE:
case GIMP_INDEXED_IMAGE:
bpp = 1;
break;
case GIMP_GRAYA_IMAGE:
case GIMP_INDEXEDA_IMAGE:
bpp = 2;
break;
case GIMP_RGB_IMAGE:
bpp = 3;
break;
case GIMP_RGBA_IMAGE:
bpp = 4;
break;
default:
g_return_if_reached ();
break;
}
buf1 += x * bpp;
buf2 += x * bpp;
width -= x;
x = 0;
}
buf1 += x * bpp;
buf2 += x * bpp;
width -= x;
x = 0;
}
if (x + width > area->width)
width = area->width - x;
if (x + width > area->width)
width = area->width - x;
if (y < 0)
{
buf1 += y * rowstride1;
buf2 += y * rowstride2;
height -= y;
y = 0;
}
if (y < 0)
{
buf1 += y * rowstride1;
buf2 += y * rowstride2;
height -= y;
y = 0;
}
if (y + height > area->height)
height = area->height - y;
if (y + height > area->height)
height = area->height - y;
if (! area->buf)
{
area->rowstride = ((area->width * 3) + 3) & ~3;
area->buf = g_new (guchar, area->rowstride * area->height);
}
if (! area->buf)
{
area->rowstride = ((area->width * 3) + 3) & ~3;
area->buf = g_new (guchar, area->rowstride * area->height);
}
size = 1 << (2 + area->check_size);
gimp_checks_get_shades (area->check_type, &light, &dark);
size = 1 << (2 + area->check_size);
gimp_checks_get_shades (area->check_type, &light, &dark);
#define CHECK_COLOR(area, row, col) \
(((((area)->offset_y + (row)) & size) ^ \
(((area)->offset_x + (col)) & size)) ? dark : light)
src1 = buf1;
src2 = buf2;
dest = area->buf + x * 3 + y * area->rowstride;
src1 = buf1;
src2 = buf2;
dest = area->buf + x * 3 + y * area->rowstride;
switch (type)
{
case GIMP_RGB_IMAGE:
for (row = 0; row < height; row++)
switch (type)
{
const guchar *s1 = src1;
const guchar *s2 = src2;
guchar *d = dest;
for (col = x; col < x + width; col++, s1 += 3, s2 += 3, d+= 3)
case GIMP_RGB_IMAGE:
for (row = 0; row < height; row++)
{
d[0] = ((s1[0] << 8) + (s2[0] - s1[0]) * opacity) >> 8;
d[1] = ((s1[1] << 8) + (s2[1] - s1[1]) * opacity) >> 8;
d[2] = ((s1[2] << 8) + (s2[2] - s1[2]) * opacity) >> 8;
}
src1 += rowstride1;
src2 += rowstride2;
dest += area->rowstride;
}
break;
const guchar *s1 = src1;
const guchar *s2 = src2;
guchar *d = dest;
case GIMP_RGBA_IMAGE:
for (row = y; row < y + height; row++)
{
const guchar *s1 = src1;
const guchar *s2 = src2;
guchar *d = dest;
for (col = x; col < x + width; col++, s1 += 4, s2 += 4, d+= 3)
{
switch (opacity)
for (col = x; col < x + width; col++, s1 += 3, s2 += 3, d+= 3)
{
case 0:
switch (s1[3])
d[0] = ((s1[0] << 8) + (s2[0] - s1[0]) * opacity) >> 8;
d[1] = ((s1[1] << 8) + (s2[1] - s1[1]) * opacity) >> 8;
d[2] = ((s1[2] << 8) + (s2[2] - s1[2]) * opacity) >> 8;
}
src1 += rowstride1;
src2 += rowstride2;
dest += area->rowstride;
}
break;
case GIMP_RGBA_IMAGE:
for (row = y; row < y + height; row++)
{
const guchar *s1 = src1;
const guchar *s2 = src2;
guchar *d = dest;
for (col = x; col < x + width; col++, s1 += 4, s2 += 4, d+= 3)
{
guchar inter[4];
inter[3] = ((s1[3] << 8) + (s2[3] - s1[3]) * opacity) >> 8;
if (inter[3])
{
case 0:
d[0] = d[1] = d[2] = CHECK_COLOR (area, row, col);
break;
for (i=0 ; i<3 ; i++)
{
gushort a = s1[i] * s1[3];
gushort b = s2[i] * s2[3];
case 255:
d[0] = s1[0];
d[1] = s1[1];
d[2] = s1[2];
break;
default:
{
register guint alpha = s1[3] + 1;
register guint check = CHECK_COLOR (area, row, col);
d[0] = ((check << 8) + (s1[0] - check) * alpha) >> 8;
d[1] = ((check << 8) + (s1[1] - check) * alpha) >> 8;
d[2] = ((check << 8) + (s1[2] - check) * alpha) >> 8;
}
break;
inter[i] = (((a << 8) + (b - a) * opacity) >> 8) / inter[3];
}
}
break;
case 255:
switch (s2[3])
{
case 0:
d[0] = d[1] = d[2] = CHECK_COLOR (area, row, col);
break;
case 255:
d[0] = s2[0];
d[1] = s2[1];
d[2] = s2[2];
break;
default:
{
register guint alpha = s2[3] + 1;
register guint check = CHECK_COLOR (area, row, col);
d[0] = ((check << 8) + (s2[0] - check) * alpha) >> 8;
d[1] = ((check << 8) + (s2[1] - check) * alpha) >> 8;
d[2] = ((check << 8) + (s2[2] - check) * alpha) >> 8;
}
break;
}
break;
default:
{
guchar inter[4];
inter[3] = ((s1[3] << 8) + (s2[3] - s1[3]) * opacity) >> 8;
if (inter[3])
{
for (i=0 ; i<3 ; i++)
{
gushort a = s1[i] * s1[3];
gushort b = s2[i] * s2[3];
inter[i] = (((a << 8) + (b - a) * opacity) >> 8) / inter[3];
}
}
else
inter[0] = inter[1] = inter[2] = 0;
else
inter[0] = inter[1] = inter[2] = 0;
switch (inter[3])
{
@ -789,279 +746,165 @@ gimp_preview_area_blend (GimpPreviewArea *area,
}
break;
}
}
break;
}
src1 += rowstride1;
src2 += rowstride2;
dest += area->rowstride;
}
break;
src1 += rowstride1;
src2 += rowstride2;
dest += area->rowstride;
}
break;
case GIMP_GRAY_IMAGE:
for (row = 0; row < height; row++)
{
const guchar *s1 = src1;
const guchar *s2 = src2;
guchar *d = dest;
for (col = 0; col < width; col++, s1++, s2++, d += 3)
case GIMP_GRAY_IMAGE:
for (row = 0; row < height; row++)
{
d[0] = d[1] = d[2] = ((s1[0] << 8) + (s2[0] - s1[0]) * opacity) >> 8;
}
const guchar *s1 = src1;
const guchar *s2 = src2;
guchar *d = dest;
src1 += rowstride1;
src2 += rowstride2;
dest += area->rowstride;
}
break;
case GIMP_GRAYA_IMAGE:
for (row = y; row < y + height; row++)
{
const guchar *s1 = src1;
const guchar *s2 = src2;
guchar *d = dest;
for (col = x; col < x + width; col++, s1 += 2, s2 += 2, d+= 3)
{
switch (opacity)
for (col = 0; col < width; col++, s1++, s2++, d += 3)
{
case 0:
switch (s1[1])
{
case 0:
d[0] = d[1] = d[2] = CHECK_COLOR (area, row, col);
break;
case 255:
d[0] = d[1] = d[2] = s1[0];
break;
default:
{
register guint alpha = s1[1] + 1;
register guint check = CHECK_COLOR (area, row, col);
d[0] = d[1] = d[2] =
((check << 8) + (s1[0] - check) * alpha) >> 8;
}
break;
}
break;
case 255:
switch (s2[1])
{
case 0:
d[0] = d[1] = d[2] = CHECK_COLOR (area, row, col);
break;
case 255:
d[0] = d[1] = d[2] = s2[0];
break;
default:
{
register guint alpha = s2[1] + 1;
register guint check = CHECK_COLOR (area, row, col);
d[0] = d[1] = d[2] =
((check << 8) + (s2[0] - check) * alpha) >> 8;
}
break;
}
break;
default:
{
guchar inter[1];
inter[1] = ((s1[1] << 8) + (s2[1] - s1[1]) * opacity) >> 8;
if (inter[1])
{
gushort a = s1[0] * s1[1];
gushort b = s2[0] * s2[1];
inter[0] = (((a << 8) + (b - a) * opacity) >> 8) / inter[1];
}
else
inter[0] = 0;
switch (inter[1])
{
case 0:
d[0] = d[1] = d[2] = CHECK_COLOR (area, row, col);
break;
case 255:
d[0] = d[1] = d[2] = inter[0];
break;
default:
{
register guint alpha = inter[1] + 1;
register guint check = CHECK_COLOR (area, row, col);
d[0] = d[1] = d[2] = ((check << 8) + (inter[0] - check) * alpha) >> 8;
}
break;
}
}
break;
d[0] = d[1] = d[2] = ((s1[0] << 8) + (s2[0] - s1[0]) * opacity) >> 8;
}
src1 += rowstride1;
src2 += rowstride2;
dest += area->rowstride;
}
break;
src1 += rowstride1;
src2 += rowstride2;
dest += area->rowstride;
}
break;
case GIMP_INDEXED_IMAGE:
g_return_if_fail (area->cmap != NULL);
for (row = 0; row < height; row++)
{
const guchar *s1 = src1;
const guchar *s2 = src2;
guchar *d = dest;
for (col = 0; col < width; col++, s1++, s2++, d += 3)
case GIMP_GRAYA_IMAGE:
for (row = y; row < y + height; row++)
{
const guchar *cmap1 = area->cmap + 3 * s1[0];
const guchar *cmap2 = area->cmap + 3 * s2[0];
const guchar *s1 = src1;
const guchar *s2 = src2;
guchar *d = dest;
d[0] = ((cmap1[0] << 8) + (cmap2[0] - cmap1[0]) * opacity) >> 8;
d[1] = ((cmap1[1] << 8) + (cmap2[1] - cmap1[1]) * opacity) >> 8;
d[2] = ((cmap1[2] << 8) + (cmap2[2] - cmap1[2]) * opacity) >> 8;
}
src1 += rowstride1;
src2 += rowstride2;
dest += area->rowstride;
}
break;
case GIMP_INDEXEDA_IMAGE:
g_return_if_fail (area->cmap != NULL);
for (row = y; row < y + height; row++)
{
const guchar *s1 = src1;
const guchar *s2 = src2;
guchar *d = dest;
for (col = x; col < x + width; col++, s1 += 2, s2 += 2, d += 3)
{
const guchar *cmap1 = area->cmap + 3 * s1[0];
const guchar *cmap2 = area->cmap + 3 * s2[0];
switch (opacity)
for (col = x; col < x + width; col++, s1 += 2, s2 += 2, d+= 3)
{
case 0:
switch (s1[1])
guchar inter[1];
inter[1] = ((s1[1] << 8) + (s2[1] - s1[1]) * opacity) >> 8;
if (inter[1])
{
case 0:
d[0] = d[1] = d[2] = CHECK_COLOR (area, row, col);
break;
gushort a = s1[0] * s1[1];
gushort b = s2[0] * s2[1];
case 255:
d[0] = cmap1[0];
d[1] = cmap1[1];
d[2] = cmap1[2];
break;
default:
{
register guint alpha = s1[1] + 1;
register guint check = CHECK_COLOR (area, row, col);
d[0] = ((check << 8) + (cmap1[0] - check) * alpha) >> 8;
d[1] = ((check << 8) + (cmap1[1] - check) * alpha) >> 8;
d[2] = ((check << 8) + (cmap1[2] - check) * alpha) >> 8;
}
break;
inter[0] = (((a << 8) + (b - a) * opacity) >> 8) / inter[1];
}
break;
else
inter[0] = 0;
case 255:
switch (s2[1])
{
case 0:
d[0] = d[1] = d[2] = CHECK_COLOR (area, row, col);
break;
case 255:
d[0] = cmap2[0];
d[1] = cmap2[1];
d[2] = cmap2[2];
break;
default:
{
register guint alpha = s2[1] + 1;
register guint check = CHECK_COLOR (area, row, col);
d[0] = ((check << 8) + (cmap2[0] - check) * alpha) >> 8;
d[1] = ((check << 8) + (cmap2[1] - check) * alpha) >> 8;
d[2] = ((check << 8) + (cmap2[2] - check) * alpha) >> 8;
}
break;
}
break;
default:
switch (inter[1])
{
guchar inter[4];
case 0:
d[0] = d[1] = d[2] = CHECK_COLOR (area, row, col);
break;
inter[3] = ((s1[1] << 8) + (s2[1] - s1[1]) * opacity) >> 8;
case 255:
d[0] = d[1] = d[2] = inter[0];
break;
if (inter[3])
{
for (i = 0 ; i < 3 ; i++)
{
gushort a = cmap1[i] * s1[1];
gushort b = cmap2[i] * s2[1];
inter[i] = (((a << 8) + (b - a) * opacity) >> 8) / inter[3];
}
}
else
inter[0] = inter[1] = inter[2] = 0;
switch (inter[3])
default:
{
case 0:
d[0] = d[1] = d[2] = CHECK_COLOR (area, row, col);
break;
register guint alpha = inter[1] + 1;
register guint check = CHECK_COLOR (area, row, col);
case 255:
d[0] = inter[0];
d[1] = inter[1];
d[2] = inter[2];
break;
default:
{
register guint alpha = inter[3] + 1;
register guint check = CHECK_COLOR (area, row, col);
d[0] = ((check << 8) + (inter[0] - check) * alpha) >> 8;
d[1] = ((check << 8) + (inter[1] - check) * alpha) >> 8;
d[2] = ((check << 8) + (inter[2] - check) * alpha) >> 8;
}
break;
d[0] = d[1] = d[2] = ((check << 8) + (inter[0] - check) * alpha) >> 8;
}
break;
}
break;
}
}
src1 += rowstride1;
src2 += rowstride2;
dest += area->rowstride;
src1 += rowstride1;
src2 += rowstride2;
dest += area->rowstride;
}
break;
case GIMP_INDEXED_IMAGE:
g_return_if_fail (area->cmap != NULL);
for (row = 0; row < height; row++)
{
const guchar *s1 = src1;
const guchar *s2 = src2;
guchar *d = dest;
for (col = 0; col < width; col++, s1++, s2++, d += 3)
{
const guchar *cmap1 = area->cmap + 3 * s1[0];
const guchar *cmap2 = area->cmap + 3 * s2[0];
d[0] = ((cmap1[0] << 8) + (cmap2[0] - cmap1[0]) * opacity) >> 8;
d[1] = ((cmap1[1] << 8) + (cmap2[1] - cmap1[1]) * opacity) >> 8;
d[2] = ((cmap1[2] << 8) + (cmap2[2] - cmap1[2]) * opacity) >> 8;
}
src1 += rowstride1;
src2 += rowstride2;
dest += area->rowstride;
}
break;
case GIMP_INDEXEDA_IMAGE:
g_return_if_fail (area->cmap != NULL);
for (row = y; row < y + height; row++)
{
const guchar *s1 = src1;
const guchar *s2 = src2;
guchar *d = dest;
for (col = x; col < x + width; col++, s1 += 2, s2 += 2, d += 3)
{
const guchar *cmap1 = area->cmap + 3 * s1[0];
const guchar *cmap2 = area->cmap + 3 * s2[0];
guchar inter[4];
inter[3] = ((s1[1] << 8) + (s2[1] - s1[1]) * opacity) >> 8;
if (inter[3])
{
for (i = 0 ; i < 3 ; i++)
{
gushort a = cmap1[i] * s1[1];
gushort b = cmap2[i] * s2[1];
inter[i] = (((a << 8) + (b - a) * opacity) >> 8) / inter[3];
}
}
else
inter[0] = inter[1] = inter[2] = 0;
switch (inter[3])
{
case 0:
d[0] = d[1] = d[2] = CHECK_COLOR (area, row, col);
break;
case 255:
d[0] = inter[0];
d[1] = inter[1];
d[2] = inter[2];
break;
default:
{
register guint alpha = inter[3] + 1;
register guint check = CHECK_COLOR (area, row, col);
d[0] = ((check << 8) + (inter[0] - check) * alpha) >> 8;
d[1] = ((check << 8) + (inter[1] - check) * alpha) >> 8;
d[2] = ((check << 8) + (inter[2] - check) * alpha) >> 8;
}
break;
}
}
src1 += rowstride1;
src2 += rowstride2;
dest += area->rowstride;
}
break;
}
break;
}
@ -1300,8 +1143,6 @@ gimp_preview_area_mask (GimpPreviewArea *area,
inter[i] = (((a << 8) + (b - a) * m[0]) >> 8) / inter[3];
}
}
else
inter[0] = inter[1] = inter[2] = 0;
switch (inter[3])
{