Commit 82140a7a authored by Arturo Espinosa's avatar Arturo Espinosa

Merge the changes from GNOME_STABLE into HEAD.



Merge the changes from GNOME_STABLE into HEAD.

Miguel.
parent 84eb132b
Wed Dec 16 14:18:46 1998 Raph Levien <raph@gimp.org>
* art_alphagamma.h:
* art_alphagamma.c: Added. At present, it only contains a dummy
stub. When the real code is added, it supports doing alpha
compositing in a gamma-corrected color space (suppressing
jaggies).
* art_pixbuf.h:
* art_pixbuf.c: Added. This is a virtualization layer over
a few different kinds of image formats.
* art_rgb_pixbuf_affine.h:
* art_rgb_pixbuf_affine.c: Added. Supports compositing of
generic images over an rgb buffer.
* art_affine.h:
* art_affine.c (art_affine_expansion): Added this function,
which reports the exact scale factor in the case of rotation,
scaling, and transformation (an approximate number in the
case of shearing or anamorphic distortion).
* art_misc.h:
* art_misc.c (art_warn): Added.
* art_rgb_affine.h:
* art_rgb_affine.c: Added alphagamma argument (not yet implemented).
* art_rgb_affine_private.c: Fixed typo bug that was causing
repaint problems for nonsquare images.
* art_rgb_bitmap_affine.h:
* art_rgb_bitmap_affine.c: Major speed improvement, probably fixed
correctness while I was at it. Added alphagamma argument (not yet
implemented).
* art_rgb_svp.h:
* art_rgb_svp.c: Added alphagamma argument (only implemented
in aa case, not yet alpha case).
* art_vpath.c: increased perturbation to 2e-3, because the old
value (1e-6) was too small.
* testart.c: added alphagamma.
* Makefile.am: added new files
Mon Dec 14 00:16:53 1998 Raph Levien <raph@gimp.org>
* art_affine.c (art_affine_to_string): re-added the "scale" method
......
......@@ -11,9 +11,11 @@ lib_LTLIBRARIES = libart_lgpl.la
libart_lgpl_la_SOURCES = \
art_affine.c \
art_alphagamma.c \
art_bpath.c \
art_gray_svp.c \
art_misc.c \
art_pixbuf.c \
art_rect.c \
art_rect_uta.c \
art_rgb.c \
......@@ -21,6 +23,7 @@ libart_lgpl_la_SOURCES = \
art_rgb_affine_private.c \
art_rgb_affine_private.h \
art_rgb_bitmap_affine.c \
art_rgb_pixbuf_affine.c \
art_rgb_rgba_affine.c \
art_rgb_svp.c \
art_svp.c \
......@@ -44,17 +47,20 @@ libart_lgpl_la_LDFLAGS = -version-info @LIBART_VERSION_INFO@
libart_lgplincdir = $(includedir)/libart_lgpl
libart_lgplinc_HEADERS = \
art_affine.h \
art_alphagamma.h \
art_bpath.h \
art_filterlevel.h \
art_gray_svp.h \
art_misc.h \
art_pathcode.h \
art_pixbuf.h \
art_point.h \
art_rect.h \
art_rect_uta.h \
art_rgb.h \
art_rgb_affine.h \
art_rgb_bitmap_affine.h \
art_rgb_pixbuf_affine.h \
art_rgb_rgba_affine.h \
art_rgb_svp.h \
art_svp.h \
......
......@@ -284,3 +284,12 @@ art_affine_translate (double dst[6], double tx, double ty)
dst[4] = tx;
dst[5] = ty;
}
/* find the affine's "expansion factor", i.e. the scale amount */
double
art_affine_expansion (const double src[6])
{
double r_det;
return sqrt (src[0] * src[3] - src[1] * src[2]);
}
......@@ -56,6 +56,10 @@ art_affine_rotate (double dst[6], double theta);
void
art_affine_translate (double dst[6], double tx, double ty);
/* find the affine's "expansion factor", i.e. the scale amount */
double
art_affine_expansion (const double src[6]);
#ifdef __cplusplus
}
#endif /* __cplusplus */
......
/* This is a stub and will get replaced with the real code. */
#include <stdlib.h>
#include "art_misc.h"
#include "art_alphagamma.h"
ArtAlphaGamma *
art_alphagamma_new (double gamma)
{
return NULL;
}
void
art_alphagamma_free (ArtAlphaGamma *alphagamma)
{
}
/* This is a stub and will get replaced with the real code. */
#ifndef __ART_ALPHAGAMMA_H__
#define __ART_ALPHAGAMMA_H__
typedef struct _ArtAlphaGamma ArtAlphaGamma;
struct _ArtAlphaGamma {
int table[256];
art_u8 invtable[1];
};
ArtAlphaGamma *
art_alphagamma_new (double gamma);
void
art_alphagamma_free (ArtAlphaGamma *alphagamma);
#endif
......@@ -24,7 +24,7 @@
#include <stdarg.h>
#include "art_misc.h"
/* Print the error message to stdout and exit with a return code of 1 */
/* Print the error message to stderr and exit with a return code of 1 */
void
art_die (const char *fmt, ...)
{
......@@ -35,3 +35,14 @@ art_die (const char *fmt, ...)
va_end (ap);
exit (1);
}
/* Print the error message to stderr */
void
art_warn (const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
vfprintf (stderr, fmt, ap);
va_end (ap);
}
......@@ -56,4 +56,7 @@ typedef unsigned int art_u32;
void
art_die (const char *fmt, ...);
void
art_warn (const char *fmt, ...);
#endif /* __ART_MISC_H__ */
/* Libart_LGPL - library of basic graphic primitives
* Copyright (C) 1998 Raph Levien
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "art_misc.h"
#include "art_pixbuf.h"
/* A generic data structure for holding a buffer of pixels. One way
to think about this module is as a virtualization over specific
pixel buffer formats. */
ArtPixBuf *
art_pixbuf_new_rgb (art_u8 *pixels, int width, int height, int rowstride)
{
ArtPixBuf *pixbuf;
pixbuf = art_new (ArtPixBuf, 1);
pixbuf->format = ART_PIX_RGB;
pixbuf->n_channels = 3;
pixbuf->has_alpha = 0;
pixbuf->bits_per_sample = 8;
pixbuf->pixels = pixels;
pixbuf->width = width;
pixbuf->height = height;
pixbuf->rowstride = rowstride;
return pixbuf;
}
ArtPixBuf *
art_pixbuf_new_rgba (art_u8 *pixels, int width, int height, int rowstride)
{
ArtPixBuf *pixbuf;
pixbuf = art_new (ArtPixBuf, 1);
pixbuf->format = ART_PIX_RGB;
pixbuf->n_channels = 4;
pixbuf->has_alpha = 1;
pixbuf->bits_per_sample = 8;
pixbuf->pixels = pixels;
pixbuf->width = width;
pixbuf->height = height;
pixbuf->rowstride = rowstride;
return pixbuf;
}
/* Warning: if you call this function, make sure the pixels were
allocated with art_alloc. */
void
art_pixbuf_free (ArtPixBuf *pixbuf)
{
art_free (pixbuf->pixels);
art_free (pixbuf);
}
void
art_pixbuf_free_shallow (ArtPixBuf *pixbuf)
{
art_free (pixbuf);
}
/* Libart_LGPL - library of basic graphic primitives
* Copyright (C) 1998 Raph Levien
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __ART_PIXBUF_H__
#define __ART_PIXBUF_H__
/* A generic data structure for holding a buffer of pixels. One way
to think about this module is as a virtualization over specific
pixel buffer formats. */
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _ArtPixBuf ArtPixBuf;
typedef enum {
ART_PIX_RGB
/* gray, cmyk, lab, ... ? */
} ArtPixFormat;
/* The pixel buffer consists of width * height pixels, each of which
has n_channels samples. It is stored in simple packed format. */
struct _ArtPixBuf {
ArtPixFormat format;
int n_channels;
int has_alpha;
int bits_per_sample;
art_u8 *pixels;
int width;
int height;
int rowstride;
};
ArtPixBuf *
art_pixbuf_new_rgb (art_u8 *pixels, int width, int height, int rowstride);
ArtPixBuf *
art_pixbuf_new_rgba (art_u8 *pixels, int width, int height, int rowstride);
void
art_pixbuf_free (ArtPixBuf *pixbuf);
void
art_pixbuf_free_shallow (ArtPixBuf *pixbuf);
#ifdef __cplusplus
}
#endif
#endif
......@@ -35,7 +35,8 @@ art_rgb_affine (art_u8 *dst, int x0, int y0, int x1, int y1, int dst_rowstride,
const art_u8 *src,
int src_width, int src_height, int src_rowstride,
const double affine[6],
ArtFilterLevel level)
ArtFilterLevel level,
ArtAlphaGamma *alphagamma)
{
/* Note: this is a slow implementation, and is missing all filter
levels other than NEAREST. It is here for clarity of presentation
......
......@@ -24,6 +24,7 @@
over rgb pixel buffers. */
#include <libart_lgpl/art_filterlevel.h>
#include <libart_lgpl/art_alphagamma.h>
#ifdef __cplusplus
extern "C" {
......@@ -34,7 +35,8 @@ art_rgb_affine (art_u8 *dst, int x0, int y0, int x1, int y1, int dst_rowstride,
const art_u8 *src,
int src_width, int src_height, int src_rowstride,
const double affine[6],
ArtFilterLevel level);
ArtFilterLevel level,
ArtAlphaGamma *alphagamma);
#ifdef __cplusplus
}
......
......@@ -113,7 +113,7 @@ art_rgb_affine_run (int *p_x0, int *p_x1, int y,
else
{
z = affine[3] * (y + 0.5) + affine[5];
if (z < 0 || z >= src_width)
if (z < 0 || z >= src_height)
{
*p_x1 = *p_x0;
return;
......
......@@ -39,7 +39,8 @@ art_rgb_bitmap_affine_opaque (art_u8 *dst,
int src_width, int src_height, int src_rowstride,
art_u32 rgb,
const double affine[6],
ArtFilterLevel level)
ArtFilterLevel level,
ArtAlphaGamma *alphagamma)
{
/* Note: this is a slow implementation, and is missing all filter
levels other than NEAREST. It is here for clarity of presentation
......@@ -51,6 +52,7 @@ art_rgb_bitmap_affine_opaque (art_u8 *dst,
ArtPoint pt, src_pt;
int src_x, src_y;
art_u8 r, g, b;
int run_x0, run_x1;
r = rgb >> 16;
g = (rgb >> 8) & 0xff;
......@@ -59,24 +61,24 @@ art_rgb_bitmap_affine_opaque (art_u8 *dst,
art_affine_invert (inv, affine);
for (y = y0; y < y1; y++)
{
pt.y = y;
dst_p = dst_linestart;
for (x = x0; x < x1; x++)
pt.y = y + 0.5;
run_x0 = x0;
run_x1 = x1;
art_rgb_affine_run (&run_x0, &run_x1, y, src_width, src_height,
inv);
dst_p = dst_linestart + (run_x0 - x0) * 3;
for (x = run_x0; x < run_x1; x++)
{
pt.x = x;
pt.x = x + 0.5;
art_affine_point (&src_pt, &pt, inv);
src_x = floor (src_pt.x + 0.5);
src_y = floor (src_pt.y + 0.5);
if (src_x >= 0 && src_x < src_width &&
src_y >= 0 && src_y < src_height)
src_x = floor (src_pt.x);
src_y = floor (src_pt.y);
src_p = src + (src_y * src_rowstride) + (src_x >> 3);
if (*src_p & (128 >> (src_x & 7)))
{
src_p = src + (src_y * src_rowstride) + (src_x >> 3);
if (*src_p & (128 >> (src_x & 7)))
{
dst_p[0] = r;
dst_p[1] = g;
dst_p[2] = b;
}
dst_p[0] = r;
dst_p[1] = g;
dst_p[2] = b;
}
dst_p += 3;
}
......@@ -94,7 +96,8 @@ art_rgb_bitmap_affine (art_u8 *dst,
int src_width, int src_height, int src_rowstride,
art_u32 rgba,
const double affine[6],
ArtFilterLevel level)
ArtFilterLevel level,
ArtAlphaGamma *alphagamma)
{
/* Note: this is a slow implementation, and is missing all filter
levels other than NEAREST. It is here for clarity of presentation
......@@ -119,7 +122,8 @@ art_rgb_bitmap_affine (art_u8 *dst,
src_width, src_height, src_rowstride,
rgba >> 8,
affine,
level);
level,
alphagamma);
return;
}
/* alpha = (65536 * alpha) / 255; */
......
......@@ -24,6 +24,7 @@
over rgb pixel buffers. */
#include <libart_lgpl/art_filterlevel.h>
#include <libart_lgpl/art_alphagamma.h>
#ifdef __cplusplus
extern "C" {
......@@ -36,7 +37,8 @@ art_rgb_bitmap_affine (art_u8 *dst,
int src_width, int src_height, int src_rowstride,
art_u32 rgba,
const double affine[6],
ArtFilterLevel level);
ArtFilterLevel level,
ArtAlphaGamma *alphagamma);
#ifdef __cplusplus
}
......
/* Libart_LGPL - library of basic graphic primitives
* Copyright (C) 1998 Raph Levien
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <math.h>
#include "art_misc.h"
#include "art_point.h"
#include "art_affine.h"
#include "art_pixbuf.h"
#include "art_rgb_affine.h"
#include "art_rgb_affine.h"
#include "art_rgb_rgba_affine.h"
/* This module handles compositing of affine-transformed generic
pixbuf images over rgb pixel buffers. */
/* Composite the source image over the destination image, applying the
affine transform. */
void
art_rgb_pixbuf_affine (art_u8 *dst,
int x0, int y0, int x1, int y1, int dst_rowstride,
const ArtPixBuf *pixbuf,
const double affine[6],
ArtFilterLevel level,
ArtAlphaGamma *alphagamma)
{
if (pixbuf->format != ART_PIX_RGB)
{
art_warn ("art_rgb_pixbuf_affine: need RGB format image\n");
return;
}
if (pixbuf->bits_per_sample != 8)
{
art_warn ("art_rgb_pixbuf_affine: need 8-bit sample data\n");
return;
}
if (pixbuf->n_channels != 3 + (pixbuf->has_alpha != 0))
{
art_warn ("art_rgb_pixbuf_affine: need 8-bit sample data\n");
return;
}
if (pixbuf->has_alpha)
art_rgb_rgba_affine (dst, x0, y0, x1, y1, dst_rowstride,
pixbuf->pixels,
pixbuf->width, pixbuf->height, pixbuf->rowstride,
affine,
level,
alphagamma);
else
art_rgb_affine (dst, x0, y0, x1, y1, dst_rowstride,
pixbuf->pixels,
pixbuf->width, pixbuf->height, pixbuf->rowstride,
affine,
level,
alphagamma);
}
/* Libart_LGPL - library of basic graphic primitives
* Copyright (C) 1998 Raph Levien
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __ART_RGB_AFFINE_H__
#define __ART_RGB_AFFINE_H__
/* This module handles compositing of affine-transformed generic
pixbuf images over rgb pixel buffers. */
#include <libart_lgpl/art_filterlevel.h>
#include <libart_lgpl/art_alphagamma.h>
#ifdef __cplusplus
extern "C" {
#endif
void
art_rgb_pixbuf_affine (art_u8 *dst,
int x0, int y0, int x1, int y1, int dst_rowstride,
const ArtPixBuf *pixbuf,
const double affine[6],
ArtFilterLevel level,
ArtAlphaGamma *alphagamma);
#ifdef __cplusplus
}
#endif
#endif
......@@ -36,7 +36,8 @@ art_rgb_rgba_affine (art_u8 *dst,
const art_u8 *src,
int src_width, int src_height, int src_rowstride,
const double affine[6],
ArtFilterLevel level)
ArtFilterLevel level,
ArtAlphaGamma *alphagamma)
{
/* Note: this is a slow implementation, and is missing all filter
levels other than NEAREST. It is here for clarity of presentation
......
......@@ -24,6 +24,7 @@
over rgb pixel buffers. */
#include <libart_lgpl/art_filterlevel.h>
#include <libart_lgpl/art_alphagamma.h>
#ifdef __cplusplus
extern "C" {
......@@ -35,7 +36,8 @@ art_rgb_rgba_affine (art_u8 *dst,
const art_u8 *src,
int src_width, int src_height, int src_rowstride,
const double affine[6],
ArtFilterLevel level);
ArtFilterLevel level,
ArtAlphaGamma *alphagamma);
#ifdef __cplusplus
}
......
......@@ -111,7 +111,8 @@ void
art_rgb_svp_aa (const ArtSVP *svp,
int x0, int y0, int x1, int y1,
art_u32 fg_color, art_u32 bg_color,
art_u8 *buf, int rowstride)
art_u8 *buf, int rowstride,
ArtAlphaGamma *alphagamma)
{
ArtRgbSVPData data;
......@@ -121,27 +122,63 @@ art_rgb_svp_aa (const ArtSVP *svp,
int dr, dg, db;
int i;
r_fg = fg_color >> 16;
g_fg = (fg_color >> 8) & 0xff;
b_fg = fg_color & 0xff;
if (alphagamma == NULL)
{
r_fg = fg_color >> 16;
g_fg = (fg_color >> 8) & 0xff;
b_fg = fg_color & 0xff;
r_bg = bg_color >> 16;
g_bg = (bg_color >> 8) & 0xff;
b_bg = bg_color & 0xff;
r = (r_bg << 16) + 0x8000;
g = (g_bg << 16) + 0x8000;
b = (b_bg << 16) + 0x8000;
dr = ((r_fg - r_bg) << 16) / 255;
dg = ((g_fg - g_bg) << 16) / 255;
db = ((b_fg - b_bg) << 16) / 255;
for (i = 0; i < 256; i++)
{
data.rgbtab[i] = (r & 0xff0000) | ((g & 0xff0000) >> 8) | (b >> 16);
r += dr;
g += dg;
b += db;
}
}
else
{
int *table;
art_u8 *invtab;
r_bg = bg_color >> 16;
g_bg = (bg_color >> 8) & 0xff;
b_bg = bg_color & 0xff;
table = alphagamma->table;
r = (r_bg << 16) + 0x8000;
g = (g_bg << 16) + 0x8000;
b = (b_bg << 16) + 0x8000;
dr = ((r_fg - r_bg) << 16) / 255;
dg = ((g_fg - g_bg) << 16) / 255;
db = ((b_fg - b_bg) << 16) / 255;
r_fg = table[fg_color >> 16];
g_fg = table[(fg_color >> 8) & 0xff];
b_fg = table[fg_color & 0xff];
for (i = 0; i < 256; i++)
{
data.rgbtab[i] = (r & 0xff0000) | ((g & 0xff0000) >> 8) | (b >> 16);
r += dr;
g += dg;
b += db;
r_bg = table[bg_color >> 16];
g_bg = table[(bg_color >> 8) & 0xff];
b_bg = table[bg_color & 0xff];
r = (r_bg << 16) + 0x8000;
g = (g_bg << 16) + 0x8000;
b = (b_bg << 16) + 0x8000;
dr = ((r_fg - r_bg) << 16) / 255;
dg = ((g_fg - g_bg) << 16) / 255;
db = ((b_fg - b_bg) << 16) / 255;
invtab = alphagamma->invtable;
for (i = 0; i < 256; i++)
{
data.rgbtab[i] = (invtab[r >> 16] << 16) |
(invtab[g >> 16] << 8) |
invtab[b >> 16];
r += dr;
g += dg;
b += db;
}
}
data.buf = buf;
data.rowstride = rowstride;
......@@ -327,7 +364,8 @@ void
art_rgb_svp_alpha (const ArtSVP *svp,
int x0, int y0, int x1, int y1,
art_u32 rgba,
art_u8 *buf, int rowstride)
art_u8 *buf, int rowstride,
ArtAlphaGamma *alphagamma)
{
ArtRgbSVPAlphaData data;
int r, g, b, alpha;
......
......@@ -17,11 +17,13 @@
* Boston, MA 02111-1307, USA.
*/
/* Render a sorted vector path into an RGB buffer. */
#ifndef __ART_RGB_SVP_H__
#define __ART_RGB_SVP_H__
/* Render a sorted vector path into an RGB buffer. */
#include <libart_lgpl/art_alphagamma.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
......@@ -30,13 +32,15 @@ void
art_rgb_svp_aa (const ArtSVP *svp,
int x0, int y0, int x1, int y1,
art_u32 fg_color, art_u32 bg_color,
art_u8 *buf, int rowstride);
art_u8 *buf, int rowstride,
ArtAlphaGamma *alphagamma);
void
art_rgb_svp_alpha (const ArtSVP *svp,
int x0, int y0, int x1, int y1,
art_u32 rgba,
art_u8 *buf, int rowstride);
art_u8 *buf, int rowstride,
ArtAlphaGamma *alphagamma);
#ifdef __cplusplus