2006-12-10 05:33:38 +08:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
1997-11-25 06:05:25 +08:00
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
1998-04-13 13:44:11 +08:00
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
1997-11-25 06:05:25 +08:00
|
|
|
*/
|
2000-12-17 05:37:03 +08:00
|
|
|
|
1999-02-21 07:20:54 +08:00
|
|
|
#include "config.h"
|
|
|
|
|
2003-07-03 02:01:19 +08:00
|
|
|
#include <string.h>
|
1999-02-21 07:20:54 +08:00
|
|
|
|
2001-12-08 00:10:53 +08:00
|
|
|
#include <glib-object.h>
|
2001-05-15 19:25:25 +08:00
|
|
|
|
2004-01-19 09:54:11 +08:00
|
|
|
#include "libgimpbase/gimpbase.h"
|
2001-01-24 07:56:18 +08:00
|
|
|
#include "libgimpcolor/gimpcolor.h"
|
|
|
|
|
2001-05-15 19:25:25 +08:00
|
|
|
#include "base-types.h"
|
2000-12-17 05:37:03 +08:00
|
|
|
|
2001-05-15 19:25:25 +08:00
|
|
|
#include "paint-funcs/paint-funcs.h"
|
2000-04-28 01:27:28 +08:00
|
|
|
|
2006-07-06 18:50:39 +08:00
|
|
|
#include "pixel-region.h"
|
|
|
|
#include "temp-buf.h"
|
2001-04-07 23:58:26 +08:00
|
|
|
|
2001-10-29 20:51:21 +08:00
|
|
|
|
2006-07-06 18:50:39 +08:00
|
|
|
static void temp_buf_to_color (TempBuf *src_buf,
|
|
|
|
TempBuf *dest_buf);
|
|
|
|
static void temp_buf_to_gray (TempBuf *src_buf,
|
|
|
|
TempBuf *dest_buf);
|
2003-05-15 21:33:30 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
TempBuf *
|
2006-07-06 18:50:39 +08:00
|
|
|
temp_buf_new (gint width,
|
|
|
|
gint height,
|
|
|
|
gint bytes,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
2006-07-06 20:27:32 +08:00
|
|
|
const guchar *color)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-12-03 21:44:59 +08:00
|
|
|
TempBuf *temp;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-12-03 21:44:59 +08:00
|
|
|
g_return_val_if_fail (width > 0 && height > 0, NULL);
|
2004-02-10 23:45:10 +08:00
|
|
|
g_return_val_if_fail (bytes > 0, NULL);
|
2001-11-13 11:31:47 +08:00
|
|
|
|
2007-05-22 18:43:48 +08:00
|
|
|
temp = g_slice_new (TempBuf);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-12-14 01:27:07 +08:00
|
|
|
temp->bytes = bytes;
|
|
|
|
temp->width = width;
|
|
|
|
temp->height = height;
|
|
|
|
temp->x = x;
|
|
|
|
temp->y = y;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2006-07-06 18:50:39 +08:00
|
|
|
temp->data = g_new (guchar, width * height * bytes);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* initialize the data */
|
2006-07-06 20:27:32 +08:00
|
|
|
if (color)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2006-07-06 18:50:39 +08:00
|
|
|
glong i;
|
|
|
|
|
1998-04-28 11:50:21 +08:00
|
|
|
/* First check if we can save a lot of work */
|
2004-02-10 23:45:10 +08:00
|
|
|
for (i = 1; i < bytes; i++)
|
1998-04-28 11:50:21 +08:00
|
|
|
{
|
2006-07-06 20:27:32 +08:00
|
|
|
if (color[0] != color[i])
|
2004-02-10 23:45:10 +08:00
|
|
|
break;
|
1998-04-28 11:50:21 +08:00
|
|
|
}
|
2004-02-10 23:45:10 +08:00
|
|
|
|
|
|
|
if (i == bytes)
|
1998-04-28 11:50:21 +08:00
|
|
|
{
|
2006-07-06 20:27:32 +08:00
|
|
|
memset (temp->data, *color, width * height * bytes);
|
1998-04-28 11:50:21 +08:00
|
|
|
}
|
2004-02-10 23:45:10 +08:00
|
|
|
else /* No, we cannot */
|
1998-04-28 11:50:21 +08:00
|
|
|
{
|
2006-07-06 18:50:39 +08:00
|
|
|
guchar *dptr = temp->data;
|
2001-01-03 02:17:16 +08:00
|
|
|
|
1998-04-28 11:50:21 +08:00
|
|
|
/* Fill the first row */
|
|
|
|
for (i = width - 1; i >= 0; --i)
|
|
|
|
{
|
2006-07-06 20:27:32 +08:00
|
|
|
const guchar *c = color;
|
2006-07-06 18:50:39 +08:00
|
|
|
gint j = bytes;
|
2001-01-03 02:17:16 +08:00
|
|
|
|
1998-04-28 11:50:21 +08:00
|
|
|
while (j--)
|
2006-07-06 18:50:39 +08:00
|
|
|
*dptr++ = *c++;
|
1998-04-28 11:50:21 +08:00
|
|
|
}
|
2001-01-03 02:17:16 +08:00
|
|
|
|
2004-02-10 23:45:10 +08:00
|
|
|
/* Now copy from it (we set bytes to bytes-per-row now) */
|
1998-04-28 11:50:21 +08:00
|
|
|
bytes *= width;
|
2001-01-03 02:17:16 +08:00
|
|
|
|
1998-04-28 11:50:21 +08:00
|
|
|
while (--height)
|
|
|
|
{
|
2006-07-06 18:50:39 +08:00
|
|
|
memcpy (dptr, temp->data, bytes);
|
1998-04-28 11:50:21 +08:00
|
|
|
dptr += bytes;
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return temp;
|
|
|
|
}
|
2001-02-21 08:07:21 +08:00
|
|
|
|
|
|
|
/* This function simply renders a checkerboard with the given
|
2003-08-25 19:35:16 +08:00
|
|
|
parameters into a newly allocated RGB tempbuf */
|
2001-02-21 08:07:21 +08:00
|
|
|
|
|
|
|
TempBuf *
|
2003-05-16 05:01:02 +08:00
|
|
|
temp_buf_new_check (gint width,
|
2006-04-12 20:49:29 +08:00
|
|
|
gint height,
|
|
|
|
GimpCheckType check_type,
|
|
|
|
GimpCheckSize check_size)
|
2001-02-21 08:07:21 +08:00
|
|
|
{
|
2006-07-06 18:50:39 +08:00
|
|
|
TempBuf *new;
|
2001-11-13 11:31:47 +08:00
|
|
|
guchar *data;
|
|
|
|
guchar check_shift = 0;
|
2003-08-25 19:35:16 +08:00
|
|
|
guchar check_mod = 0;
|
2004-09-03 08:06:21 +08:00
|
|
|
guchar check_light = 0;
|
|
|
|
guchar check_dark = 0;
|
2003-08-25 19:35:16 +08:00
|
|
|
gint x, y;
|
2001-11-13 11:31:47 +08:00
|
|
|
|
|
|
|
g_return_val_if_fail (width > 0 && height > 0, NULL);
|
2001-02-21 08:07:21 +08:00
|
|
|
|
|
|
|
switch (check_size)
|
|
|
|
{
|
2004-09-02 22:28:37 +08:00
|
|
|
case GIMP_CHECK_SIZE_SMALL_CHECKS:
|
2003-08-25 19:35:16 +08:00
|
|
|
check_mod = 0x3;
|
2001-02-21 08:07:21 +08:00
|
|
|
check_shift = 2;
|
|
|
|
break;
|
2004-09-02 22:28:37 +08:00
|
|
|
case GIMP_CHECK_SIZE_MEDIUM_CHECKS:
|
2003-08-25 19:35:16 +08:00
|
|
|
check_mod = 0x7;
|
|
|
|
check_shift = 3;
|
2001-02-21 08:07:21 +08:00
|
|
|
break;
|
2004-09-02 22:28:37 +08:00
|
|
|
case GIMP_CHECK_SIZE_LARGE_CHECKS:
|
2003-08-25 19:35:16 +08:00
|
|
|
check_mod = 0xf;
|
|
|
|
check_shift = 4;
|
2001-11-13 11:31:47 +08:00
|
|
|
break;
|
2001-02-21 08:07:21 +08:00
|
|
|
}
|
2003-08-25 19:35:16 +08:00
|
|
|
|
2004-09-03 08:06:21 +08:00
|
|
|
gimp_checks_get_shades (check_type, &check_light, &check_dark);
|
2003-08-25 19:35:16 +08:00
|
|
|
|
2006-07-06 18:50:39 +08:00
|
|
|
new = temp_buf_new (width, height, 3, 0, 0, NULL);
|
2008-12-13 18:35:53 +08:00
|
|
|
data = temp_buf_get_data (new);
|
2001-12-04 01:59:48 +08:00
|
|
|
|
2003-09-05 18:26:59 +08:00
|
|
|
for (y = 0; y < height; y++)
|
2001-02-21 08:07:21 +08:00
|
|
|
{
|
2006-07-06 18:50:39 +08:00
|
|
|
guchar check_dark = y >> check_shift;
|
|
|
|
guchar color = (check_dark & 0x1) ? check_light : check_dark;
|
2003-08-25 19:35:16 +08:00
|
|
|
|
2003-09-05 18:26:59 +08:00
|
|
|
for (x = 0; x < width; x++)
|
2006-04-12 20:49:29 +08:00
|
|
|
{
|
2003-08-25 19:35:16 +08:00
|
|
|
*data++ = color;
|
|
|
|
*data++ = color;
|
|
|
|
*data++ = color;
|
|
|
|
|
|
|
|
if (((x + 1) & check_mod) == 0)
|
|
|
|
{
|
2004-09-03 08:06:21 +08:00
|
|
|
check_dark += 1;
|
|
|
|
color = (check_dark & 0x1) ? check_light : check_dark;
|
2003-08-25 19:35:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-12-04 01:59:48 +08:00
|
|
|
|
2006-07-06 18:50:39 +08:00
|
|
|
return new;
|
2001-02-21 08:07:21 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
TempBuf *
|
2001-02-05 06:10:54 +08:00
|
|
|
temp_buf_copy (TempBuf *src,
|
2006-04-12 20:49:29 +08:00
|
|
|
TempBuf *dest)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-11-13 11:31:47 +08:00
|
|
|
g_return_val_if_fail (src != NULL, NULL);
|
2002-04-17 04:25:27 +08:00
|
|
|
g_return_val_if_fail (! dest || (dest->width == src->width &&
|
|
|
|
dest->height == src->height), NULL);
|
|
|
|
|
|
|
|
if (! dest)
|
2006-07-06 18:50:39 +08:00
|
|
|
dest = temp_buf_new (src->width, src->height, src->bytes, 0, 0, NULL);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-04-17 04:25:27 +08:00
|
|
|
if (src->bytes != dest->bytes)
|
2001-01-03 02:17:16 +08:00
|
|
|
{
|
2003-05-15 21:33:30 +08:00
|
|
|
if (src->bytes == 4 && dest->bytes == 2) /* RGBA -> GRAYA */
|
2002-04-17 04:25:27 +08:00
|
|
|
temp_buf_to_gray (src, dest);
|
2003-05-15 21:33:30 +08:00
|
|
|
else if (src->bytes == 3 && dest->bytes == 1) /* RGB -> GRAY */
|
2002-04-17 04:25:27 +08:00
|
|
|
temp_buf_to_gray (src, dest);
|
2003-05-15 21:33:30 +08:00
|
|
|
else if (src->bytes == 2 && dest->bytes == 4) /* GRAYA -> RGBA */
|
2002-04-17 04:25:27 +08:00
|
|
|
temp_buf_to_color (src, dest);
|
2003-05-15 21:33:30 +08:00
|
|
|
else if (src->bytes == 1 && dest->bytes == 3) /* GRAY -> RGB */
|
2002-04-17 04:25:27 +08:00
|
|
|
temp_buf_to_color (src, dest);
|
|
|
|
else
|
|
|
|
g_warning ("temp_buf_copy(): unimplemented color conversion");
|
2001-01-03 02:17:16 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
|
|
|
{
|
2008-12-13 18:35:53 +08:00
|
|
|
memcpy (temp_buf_get_data (dest),
|
|
|
|
temp_buf_get_data (src),
|
2006-07-06 18:50:39 +08:00
|
|
|
src->width * src->height * src->bytes);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
2002-04-17 04:25:27 +08:00
|
|
|
return dest;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TempBuf *
|
2001-01-03 02:17:16 +08:00
|
|
|
temp_buf_resize (TempBuf *buf,
|
2006-04-12 20:49:29 +08:00
|
|
|
gint bytes,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
gint width,
|
|
|
|
gint height)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-12-03 21:44:59 +08:00
|
|
|
g_return_val_if_fail (width > 0 && height > 0, NULL);
|
|
|
|
|
2005-09-04 05:56:07 +08:00
|
|
|
if (! buf)
|
2001-01-03 02:17:16 +08:00
|
|
|
{
|
|
|
|
buf = temp_buf_new (width, height, bytes, x, y, NULL);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
|
|
|
{
|
2006-07-06 18:50:39 +08:00
|
|
|
gsize size = width * height * bytes;
|
2005-09-04 05:56:07 +08:00
|
|
|
|
2006-07-06 18:50:39 +08:00
|
|
|
if (size != (buf->width * buf->height * buf->bytes))
|
2001-12-04 01:59:48 +08:00
|
|
|
{
|
2006-07-06 18:50:39 +08:00
|
|
|
buf->data = g_renew (guchar, buf->data, size);
|
2001-12-04 01:59:48 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-01-03 02:17:16 +08:00
|
|
|
buf->x = x;
|
|
|
|
buf->y = y;
|
|
|
|
buf->width = width;
|
|
|
|
buf->height = height;
|
|
|
|
buf->bytes = bytes;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
2001-02-05 06:10:54 +08:00
|
|
|
TempBuf *
|
|
|
|
temp_buf_scale (TempBuf *src,
|
2006-04-12 20:49:29 +08:00
|
|
|
gint new_width,
|
|
|
|
gint new_height)
|
2001-02-05 06:10:54 +08:00
|
|
|
{
|
2007-12-14 01:27:07 +08:00
|
|
|
TempBuf *dest;
|
|
|
|
const guchar *src_data;
|
|
|
|
guchar *dest_data;
|
|
|
|
gdouble x_ratio;
|
|
|
|
gdouble y_ratio;
|
|
|
|
gint loop1;
|
|
|
|
gint loop2;
|
2001-02-05 06:10:54 +08:00
|
|
|
|
2001-11-13 11:31:47 +08:00
|
|
|
g_return_val_if_fail (src != NULL, NULL);
|
|
|
|
g_return_val_if_fail (new_width > 0 && new_height > 0, NULL);
|
|
|
|
|
2001-02-05 06:10:54 +08:00
|
|
|
dest = temp_buf_new (new_width,
|
2006-04-12 20:49:29 +08:00
|
|
|
new_height,
|
|
|
|
src->bytes,
|
|
|
|
0, 0, NULL);
|
2001-02-05 06:10:54 +08:00
|
|
|
|
2008-12-13 18:35:53 +08:00
|
|
|
src_data = temp_buf_get_data (src);
|
|
|
|
dest_data = temp_buf_get_data (dest);
|
2001-02-05 06:10:54 +08:00
|
|
|
|
|
|
|
x_ratio = (gdouble) src->width / (gdouble) new_width;
|
|
|
|
y_ratio = (gdouble) src->height / (gdouble) new_height;
|
2003-08-25 19:35:16 +08:00
|
|
|
|
2001-02-05 06:10:54 +08:00
|
|
|
for (loop1 = 0 ; loop1 < new_height ; loop1++)
|
|
|
|
{
|
|
|
|
for (loop2 = 0 ; loop2 < new_width ; loop2++)
|
2006-04-12 20:49:29 +08:00
|
|
|
{
|
2007-12-14 01:27:07 +08:00
|
|
|
const guchar *src_pixel;
|
|
|
|
guchar *dest_pixel;
|
|
|
|
gint i;
|
2001-02-05 06:10:54 +08:00
|
|
|
|
2006-04-12 20:49:29 +08:00
|
|
|
src_pixel = src_data +
|
|
|
|
(gint) (loop2 * x_ratio) * src->bytes +
|
|
|
|
(gint) (loop1 * y_ratio) * src->bytes * src->width;
|
2001-02-05 06:10:54 +08:00
|
|
|
|
2006-04-12 20:49:29 +08:00
|
|
|
dest_pixel = dest_data +
|
|
|
|
(loop2 + loop1 * new_width) * src->bytes;
|
2001-02-05 06:10:54 +08:00
|
|
|
|
2006-04-12 20:49:29 +08:00
|
|
|
for (i = 0 ; i < src->bytes; i++)
|
|
|
|
*dest_pixel++ = *src_pixel++;
|
|
|
|
}
|
2001-02-05 06:10:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
TempBuf *
|
2001-01-03 02:17:16 +08:00
|
|
|
temp_buf_copy_area (TempBuf *src,
|
2006-04-12 20:49:29 +08:00
|
|
|
TempBuf *dest,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
gint width,
|
|
|
|
gint height,
|
|
|
|
gint dest_x,
|
|
|
|
gint dest_y)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-01-03 02:17:16 +08:00
|
|
|
TempBuf *new;
|
2004-11-14 10:50:33 +08:00
|
|
|
PixelRegion srcPR = { 0, };
|
|
|
|
PixelRegion destPR = { 0, };
|
2001-01-03 02:17:16 +08:00
|
|
|
guchar empty[MAX_CHANNELS] = { 0, 0, 0, 0 };
|
|
|
|
gint x1, y1, x2, y2;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2004-11-14 10:50:33 +08:00
|
|
|
g_return_val_if_fail (src != NULL, dest);
|
2001-02-06 05:52:57 +08:00
|
|
|
g_return_val_if_fail (!dest || dest->bytes == src->bytes, dest);
|
|
|
|
|
|
|
|
g_return_val_if_fail (width + dest_x > 0, dest);
|
|
|
|
g_return_val_if_fail (height + dest_y > 0, dest);
|
|
|
|
|
|
|
|
g_return_val_if_fail (!dest || dest->width >= width + dest_x, dest);
|
|
|
|
g_return_val_if_fail (!dest || dest->height >= height + dest_y, dest);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* some bounds checking */
|
2001-02-06 05:52:57 +08:00
|
|
|
x1 = CLAMP (x, 0, src->width - 1);
|
|
|
|
y1 = CLAMP (y, 0, src->height - 1);
|
|
|
|
x2 = CLAMP (x + width - 1, 0, src->width - 1);
|
|
|
|
y2 = CLAMP (y + height - 1, 0, src->height - 1);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
if (!(x2 - x1) || !(y2 - y1))
|
|
|
|
return dest;
|
|
|
|
|
2001-02-06 05:52:57 +08:00
|
|
|
width = x2 - x1 + 1;
|
|
|
|
height = y2 - y1 + 1;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-02-06 05:52:57 +08:00
|
|
|
if (! dest)
|
2001-01-03 02:17:16 +08:00
|
|
|
{
|
2001-02-06 05:52:57 +08:00
|
|
|
new = temp_buf_new (width + dest_x,
|
2006-04-12 20:49:29 +08:00
|
|
|
height + dest_y,
|
|
|
|
src->bytes,
|
|
|
|
0, 0,
|
|
|
|
empty);
|
2001-01-03 02:17:16 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
new = dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy the region */
|
2005-09-04 01:16:58 +08:00
|
|
|
pixel_region_init_temp_buf (&srcPR, src, x1, y1, width, height);
|
|
|
|
pixel_region_init_temp_buf (&destPR, new, dest_x, dest_y, width, height);
|
2002-08-22 17:48:56 +08:00
|
|
|
|
|
|
|
copy_region (&srcPR, &destPR);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2007-12-14 01:27:07 +08:00
|
|
|
/**
|
|
|
|
* temp_buf_demultiply:
|
|
|
|
* @buf:
|
|
|
|
*
|
|
|
|
* Converts a TempBuf with pre-multiplied alpha to a 'normal' TempBuf.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
temp_buf_demultiply (TempBuf *buf)
|
|
|
|
{
|
|
|
|
guchar *data;
|
|
|
|
gint pixels;
|
|
|
|
|
|
|
|
g_return_if_fail (buf != NULL);
|
|
|
|
|
|
|
|
switch (buf->bytes)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
2008-12-13 18:35:53 +08:00
|
|
|
data = temp_buf_get_data (buf);
|
2007-12-14 01:27:07 +08:00
|
|
|
pixels = buf->width * buf->height;
|
|
|
|
while (pixels--)
|
|
|
|
{
|
2007-12-14 04:30:29 +08:00
|
|
|
data[0] = (data[0] << 8) / (data[1] + 1);
|
2007-12-14 01:27:07 +08:00
|
|
|
|
|
|
|
data += 2;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
2008-12-13 18:35:53 +08:00
|
|
|
data = temp_buf_get_data (buf);
|
2007-12-14 01:27:07 +08:00
|
|
|
pixels = buf->width * buf->height;
|
|
|
|
while (pixels--)
|
|
|
|
{
|
2007-12-14 04:30:29 +08:00
|
|
|
data[0] = (data[0] << 8) / (data[3] + 1);
|
|
|
|
data[1] = (data[1] << 8) / (data[3] + 1);
|
|
|
|
data[2] = (data[2] << 8) / (data[3] + 1);
|
2007-12-14 01:27:07 +08:00
|
|
|
|
|
|
|
data += 4;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_return_if_reached ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
void
|
2007-12-14 01:27:07 +08:00
|
|
|
temp_buf_free (TempBuf *buf)
|
2003-08-25 19:35:16 +08:00
|
|
|
{
|
2007-12-14 01:27:07 +08:00
|
|
|
g_return_if_fail (buf != NULL);
|
2001-11-13 11:31:47 +08:00
|
|
|
|
2007-12-14 01:27:07 +08:00
|
|
|
if (buf->data)
|
|
|
|
g_free (buf->data);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-12-14 01:27:07 +08:00
|
|
|
g_slice_free (TempBuf, buf);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
2000-04-28 01:27:28 +08:00
|
|
|
guchar *
|
2008-12-13 18:35:53 +08:00
|
|
|
temp_buf_get_data (TempBuf *buf)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2007-12-14 01:27:07 +08:00
|
|
|
return buf->data;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
2001-01-03 01:01:30 +08:00
|
|
|
guchar *
|
2007-12-14 01:27:07 +08:00
|
|
|
temp_buf_data_clear (TempBuf *buf)
|
2001-01-03 01:01:30 +08:00
|
|
|
{
|
2007-12-14 01:27:07 +08:00
|
|
|
memset (buf->data, 0, buf->height * buf->width * buf->bytes);
|
2001-01-03 02:17:16 +08:00
|
|
|
|
2007-12-14 01:27:07 +08:00
|
|
|
return buf->data;
|
2001-01-03 01:01:30 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-01-31 00:14:26 +08:00
|
|
|
gsize
|
2007-12-14 01:27:07 +08:00
|
|
|
temp_buf_get_memsize (TempBuf *buf)
|
2002-01-31 00:14:26 +08:00
|
|
|
{
|
2007-12-14 01:27:07 +08:00
|
|
|
if (buf)
|
|
|
|
return (sizeof (TempBuf) + buf->bytes * buf->width * buf->height);
|
2002-01-31 00:14:26 +08:00
|
|
|
|
2007-11-17 02:19:30 +08:00
|
|
|
return 0;
|
2002-01-31 00:14:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-07-06 18:50:39 +08:00
|
|
|
/* The conversion routines */
|
|
|
|
|
|
|
|
static void
|
|
|
|
temp_buf_to_color (TempBuf *src_buf,
|
|
|
|
TempBuf *dest_buf)
|
|
|
|
{
|
|
|
|
guchar *src;
|
|
|
|
guchar *dest;
|
|
|
|
glong num_pixels;
|
|
|
|
|
2008-12-13 18:35:53 +08:00
|
|
|
src = temp_buf_get_data (src_buf);
|
|
|
|
dest = temp_buf_get_data (dest_buf);
|
2006-07-06 18:50:39 +08:00
|
|
|
|
|
|
|
num_pixels = src_buf->width * src_buf->height;
|
|
|
|
|
|
|
|
switch (dest_buf->bytes)
|
|
|
|
{
|
|
|
|
case 3:
|
|
|
|
g_return_if_fail (src_buf->bytes == 1);
|
|
|
|
while (num_pixels--)
|
|
|
|
{
|
|
|
|
guchar tmp;
|
|
|
|
|
|
|
|
*dest++ = tmp = *src++;
|
|
|
|
*dest++ = tmp;
|
|
|
|
*dest++ = tmp;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
g_return_if_fail (src_buf->bytes == 2);
|
|
|
|
while (num_pixels--)
|
|
|
|
{
|
|
|
|
guchar tmp;
|
|
|
|
|
|
|
|
*dest++ = tmp = *src++;
|
|
|
|
*dest++ = tmp;
|
|
|
|
*dest++ = tmp;
|
|
|
|
|
|
|
|
*dest++ = *src++; /* alpha channel */
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_return_if_reached ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
temp_buf_to_gray (TempBuf *src_buf,
|
|
|
|
TempBuf *dest_buf)
|
|
|
|
{
|
|
|
|
const guchar *src;
|
|
|
|
guchar *dest;
|
|
|
|
glong num_pixels;
|
|
|
|
|
2008-12-13 18:35:53 +08:00
|
|
|
src = temp_buf_get_data (src_buf);
|
|
|
|
dest = temp_buf_get_data (dest_buf);
|
2006-07-06 18:50:39 +08:00
|
|
|
|
|
|
|
num_pixels = src_buf->width * src_buf->height;
|
|
|
|
|
|
|
|
switch (dest_buf->bytes)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
g_return_if_fail (src_buf->bytes == 3);
|
|
|
|
while (num_pixels--)
|
|
|
|
{
|
|
|
|
gint lum = GIMP_RGB_LUMINANCE (src[0], src[1], src[2]) + 0.5;
|
|
|
|
|
|
|
|
*dest++ = (guchar) lum;
|
|
|
|
|
|
|
|
src += 3;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
g_return_if_fail (src_buf->bytes == 4);
|
|
|
|
while (num_pixels--)
|
|
|
|
{
|
|
|
|
gint lum = GIMP_RGB_LUMINANCE (src[0], src[1], src[2]) + 0.5;
|
|
|
|
|
|
|
|
*dest++ = (guchar) lum;
|
|
|
|
*dest++ = src[3]; /* alpha channel */
|
|
|
|
|
|
|
|
src += 4;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_return_if_reached ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|