RGB brush scaling

--Sven
This commit is contained in:
Sven Neumann 1999-08-21 20:33:13 +00:00
parent 6ac43482aa
commit d5cc2ac5da
7 changed files with 404 additions and 28 deletions

View File

@ -1,3 +1,9 @@
Sat Aug 21 22:32:25 MEST 1999 Sven Neumann <sven@gimp.org>
* app/brush_select.c
* app/brush_scale.[ch]: implemented brush_scaling for pixmap brushes.
This commit is done only to get some working code in before I start to
move all the brush_preview crap into one central place.
Sat Aug 21 20:30:48 BST 1999 Adam D. Moss <adam@gimp.org>

View File

@ -19,6 +19,7 @@
#include <glib.h>
#include "brush_scale.h"
MaskBuf *
brush_scale_mask (MaskBuf *brush_mask,
int dest_width,
@ -164,3 +165,180 @@ brush_scale_mask (MaskBuf *brush_mask,
return scale_brush;
}
#define ADD_RGB(dest, factor, src) \
dest[0] += factor * src[0]; \
dest[1] += factor * src[1]; \
dest[2] += factor * src[2];
MaskBuf *
brush_scale_pixmap (MaskBuf *pixmap,
int dest_width,
int dest_height)
{
MaskBuf *scale_brush;
int src_width;
int src_height;
int value[3];
int factor;
int area;
int i, j;
int x, x0, y, y0;
int dx, dx0, dy, dy0;
int fx, fx0, fy, fy0;
unsigned char *src, *src_ptr, *dest;
g_return_val_if_fail (pixmap != NULL && pixmap->bytes == 3 &&
dest_width != 0 && dest_height != 0, NULL);
src_width = pixmap->width;
src_height = pixmap->height;
scale_brush = temp_buf_new (dest_width, dest_height, 3, 0, 0, NULL);
g_return_val_if_fail (scale_brush != NULL, NULL);
/* get the data */
dest = mask_buf_data (scale_brush);
src = mask_buf_data (pixmap);
fx = fx0 = (256.0 * src_width) / dest_width;
fy = fy0 = (256.0 * src_height) / dest_height;
area = fx0 * fy0;
x = x0 = 0;
y = y0 = 0;
dx = dx0 = 0;
dy = dy0 = 0;
for (i=0; i<dest_height; i++)
{
for (j=0; j<dest_width; j++)
{
value[0] = 0;
value[1] = 0;
value[2] = 0;
fy = fy0;
y = y0;
dy = dy0;
if (dy)
{
fx = fx0;
x = x0;
dx = dx0;
if (dx)
{
factor = dx * dy;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= dx;
dx = 0;
}
while (fx >= 256)
{
factor = 256 * dy;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= 256;
}
if (fx)
{
factor = fx * dy;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
dx = 256 - fx;
}
y++;
fy -= dy;
dy = 0;
}
while (fy >= 256)
{
fx = fx0;
x = x0;
dx = dx0;
if (dx)
{
factor = dx * 256;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= dx;
dx = 0;
}
while (fx >= 256)
{
factor = 256 * 256;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= 256;
}
if (fx)
{
factor = fx * 256;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
dx = 256 - fx;
}
y++;
fy -= 256;
}
if (fy)
{
fx = fx0;
x = x0;
dx = dx0;
if (dx)
{
factor = dx * fy;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= dx;
dx = 0;
}
while (fx >= 256)
{
factor = 256 * fy;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= 256;
}
if (fx)
{
factor = fx * fy;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
dx = 256 - fx;
}
dy = 256 - fy;
}
*dest++ = MIN ((value[0] / area), 255);
*dest++ = MIN ((value[1] / area), 255);
*dest++ = MIN ((value[2] / area), 255);
x0 = x;
dx0 = dx;
}
x0 = 0;
dx0 = 0;
y0 = y;
dy0 = dy;
}
return scale_brush;
}
#undef ADD_RGB

View File

@ -43,7 +43,8 @@ static unsigned char brush_scale_indicator_bits[7][7][3] =
/* functions */
MaskBuf * brush_scale_mask (MaskBuf *, int, int);
MaskBuf * brush_scale_mask (MaskBuf *, int, int);
MaskBuf * brush_scale_pixmap (MaskBuf *, int, int);
#endif /* __BRUSH_SCALE_H__ */

View File

@ -19,6 +19,7 @@
#include <glib.h>
#include "brush_scale.h"
MaskBuf *
brush_scale_mask (MaskBuf *brush_mask,
int dest_width,
@ -164,3 +165,180 @@ brush_scale_mask (MaskBuf *brush_mask,
return scale_brush;
}
#define ADD_RGB(dest, factor, src) \
dest[0] += factor * src[0]; \
dest[1] += factor * src[1]; \
dest[2] += factor * src[2];
MaskBuf *
brush_scale_pixmap (MaskBuf *pixmap,
int dest_width,
int dest_height)
{
MaskBuf *scale_brush;
int src_width;
int src_height;
int value[3];
int factor;
int area;
int i, j;
int x, x0, y, y0;
int dx, dx0, dy, dy0;
int fx, fx0, fy, fy0;
unsigned char *src, *src_ptr, *dest;
g_return_val_if_fail (pixmap != NULL && pixmap->bytes == 3 &&
dest_width != 0 && dest_height != 0, NULL);
src_width = pixmap->width;
src_height = pixmap->height;
scale_brush = temp_buf_new (dest_width, dest_height, 3, 0, 0, NULL);
g_return_val_if_fail (scale_brush != NULL, NULL);
/* get the data */
dest = mask_buf_data (scale_brush);
src = mask_buf_data (pixmap);
fx = fx0 = (256.0 * src_width) / dest_width;
fy = fy0 = (256.0 * src_height) / dest_height;
area = fx0 * fy0;
x = x0 = 0;
y = y0 = 0;
dx = dx0 = 0;
dy = dy0 = 0;
for (i=0; i<dest_height; i++)
{
for (j=0; j<dest_width; j++)
{
value[0] = 0;
value[1] = 0;
value[2] = 0;
fy = fy0;
y = y0;
dy = dy0;
if (dy)
{
fx = fx0;
x = x0;
dx = dx0;
if (dx)
{
factor = dx * dy;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= dx;
dx = 0;
}
while (fx >= 256)
{
factor = 256 * dy;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= 256;
}
if (fx)
{
factor = fx * dy;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
dx = 256 - fx;
}
y++;
fy -= dy;
dy = 0;
}
while (fy >= 256)
{
fx = fx0;
x = x0;
dx = dx0;
if (dx)
{
factor = dx * 256;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= dx;
dx = 0;
}
while (fx >= 256)
{
factor = 256 * 256;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= 256;
}
if (fx)
{
factor = fx * 256;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
dx = 256 - fx;
}
y++;
fy -= 256;
}
if (fy)
{
fx = fx0;
x = x0;
dx = dx0;
if (dx)
{
factor = dx * fy;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= dx;
dx = 0;
}
while (fx >= 256)
{
factor = 256 * fy;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
x++;
fx -= 256;
}
if (fx)
{
factor = fx * fy;
src_ptr = src + 3 * (x + y * src_width);
ADD_RGB (value, factor, src_ptr);
dx = 256 - fx;
}
dy = 256 - fy;
}
*dest++ = MIN ((value[0] / area), 255);
*dest++ = MIN ((value[1] / area), 255);
*dest++ = MIN ((value[2] / area), 255);
x0 = x;
dx0 = dx;
}
x0 = 0;
dx0 = 0;
y0 = y;
dy0 = dy;
}
return scale_brush;
}
#undef ADD_RGB

View File

@ -43,7 +43,8 @@ static unsigned char brush_scale_indicator_bits[7][7][3] =
/* functions */
MaskBuf * brush_scale_mask (MaskBuf *, int, int);
MaskBuf * brush_scale_mask (MaskBuf *, int, int);
MaskBuf * brush_scale_pixmap (MaskBuf *, int, int);
#endif /* __BRUSH_SCALE_H__ */

View File

@ -817,23 +817,30 @@ display_brush (BrushSelectP bsp,
int ystart;
int i, j;
brush_buf = brush->mask;
brush_buf = GIMP_IS_BRUSH_PIXMAP (brush) ? GIMP_BRUSH_PIXMAP(brush)->pixmap_mask
: brush->mask;
if (!GIMP_IS_BRUSH_PIXMAP(brush) && /* can't scale color brushes yet */
(brush_buf->width > bsp->cell_width ||
brush_buf->height > bsp->cell_height))
if (brush_buf->width > bsp->cell_width || brush_buf->height > bsp->cell_height)
{
double ratio_x = (double)brush_buf->width / bsp->cell_width;
double ratio_y = (double)brush_buf->height / bsp->cell_height;
if (ratio_x >= ratio_y)
brush_buf = brush_scale_mask (brush_buf,
(double)(brush_buf->width) / ratio_x,
(double)(brush_buf->height) / ratio_x);
brush_buf = GIMP_IS_BRUSH_PIXMAP (brush) ?
brush_scale_pixmap (brush_buf,
(double)(brush_buf->width) / ratio_x,
(double)(brush_buf->height) / ratio_x) :
brush_scale_mask (brush_buf,
(double)(brush_buf->width) / ratio_x,
(double)(brush_buf->height) / ratio_x);
else
brush_buf = brush_scale_mask (brush_buf,
(double)(brush_buf->width) / ratio_y,
(double)(brush_buf->height) / ratio_y);
brush_buf = GIMP_IS_BRUSH_PIXMAP (brush) ?
brush_scale_pixmap (brush_buf,
(double)(brush_buf->width) / ratio_y,
(double)(brush_buf->height) / ratio_y) :
brush_scale_mask (brush_buf,
(double)(brush_buf->width) / ratio_y,
(double)(brush_buf->height) / ratio_y);
scale = TRUE;
}
@ -853,13 +860,12 @@ display_brush (BrushSelectP bsp,
/* Get the pointer into the brush mask data */
if (GIMP_IS_BRUSH_PIXMAP (brush))
{
GimpBrushPixmap *pixmapbrush = GIMP_BRUSH_PIXMAP(brush);
src = (gchar *) temp_buf_data (pixmapbrush->pixmap_mask) + (ystart - offset_y) * brush->mask->width * 3;
src = mask_buf_data (brush_buf) + (ystart - offset_y) * brush_buf->width * 3;
for (i = ystart; i < yend; i++)
{
gtk_preview_draw_row (GTK_PREVIEW (bsp->preview), src,
offset_x, i, width);
src += brush->mask->width * 3;
src += brush_buf->width * 3;
}
}
else

View File

@ -817,23 +817,30 @@ display_brush (BrushSelectP bsp,
int ystart;
int i, j;
brush_buf = brush->mask;
brush_buf = GIMP_IS_BRUSH_PIXMAP (brush) ? GIMP_BRUSH_PIXMAP(brush)->pixmap_mask
: brush->mask;
if (!GIMP_IS_BRUSH_PIXMAP(brush) && /* can't scale color brushes yet */
(brush_buf->width > bsp->cell_width ||
brush_buf->height > bsp->cell_height))
if (brush_buf->width > bsp->cell_width || brush_buf->height > bsp->cell_height)
{
double ratio_x = (double)brush_buf->width / bsp->cell_width;
double ratio_y = (double)brush_buf->height / bsp->cell_height;
if (ratio_x >= ratio_y)
brush_buf = brush_scale_mask (brush_buf,
(double)(brush_buf->width) / ratio_x,
(double)(brush_buf->height) / ratio_x);
brush_buf = GIMP_IS_BRUSH_PIXMAP (brush) ?
brush_scale_pixmap (brush_buf,
(double)(brush_buf->width) / ratio_x,
(double)(brush_buf->height) / ratio_x) :
brush_scale_mask (brush_buf,
(double)(brush_buf->width) / ratio_x,
(double)(brush_buf->height) / ratio_x);
else
brush_buf = brush_scale_mask (brush_buf,
(double)(brush_buf->width) / ratio_y,
(double)(brush_buf->height) / ratio_y);
brush_buf = GIMP_IS_BRUSH_PIXMAP (brush) ?
brush_scale_pixmap (brush_buf,
(double)(brush_buf->width) / ratio_y,
(double)(brush_buf->height) / ratio_y) :
brush_scale_mask (brush_buf,
(double)(brush_buf->width) / ratio_y,
(double)(brush_buf->height) / ratio_y);
scale = TRUE;
}
@ -853,13 +860,12 @@ display_brush (BrushSelectP bsp,
/* Get the pointer into the brush mask data */
if (GIMP_IS_BRUSH_PIXMAP (brush))
{
GimpBrushPixmap *pixmapbrush = GIMP_BRUSH_PIXMAP(brush);
src = (gchar *) temp_buf_data (pixmapbrush->pixmap_mask) + (ystart - offset_y) * brush->mask->width * 3;
src = mask_buf_data (brush_buf) + (ystart - offset_y) * brush_buf->width * 3;
for (i = ystart; i < yend; i++)
{
gtk_preview_draw_row (GTK_PREVIEW (bsp->preview), src,
offset_x, i, width);
src += brush->mask->width * 3;
src += brush_buf->width * 3;
}
}
else