1 /* Libart_LGPL - library of basic graphic primitives
2 * Copyright (C) 1998 Raph Levien
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
23 #include <string.h> /* for memset */
25 /* Basic operators for manipulating 24-bit packed RGB buffers. */
27 #define COLOR_RUN_COMPLEX
29 #ifdef COLOR_RUN_SIMPLE
30 /* This is really slow. Is there any way we might speed it up?
33 First, maybe we should be working at 32-bit alignment. Then,
34 this can be a simple loop over word stores.
36 Second, we can keep working at 24-bit alignment, but have some
37 intelligence about storing. For example, we can iterate over
38 4-pixel chunks (aligned at 4 pixels), with an inner loop
45 One source of extra complexity is the need to make sure linebuf is
46 aligned to a 32-bit boundary.
48 This second alternative has some complexity to it, but is
49 appealing because it really minimizes the memory bandwidth. */
51 art_rgb_fill_run (art_u8
*buf
, art_u8 r
, art_u8 g
, art_u8 b
, gint n
)
57 memset (buf
, g
, n
+ n
+ n
);
61 for (i
= 0; i
< n
; i
++)
71 #ifdef COLOR_RUN_COMPLEX
72 /* This implements the second of the two ideas above. The test results
73 are _very_ encouraging - it seems the speed is within 10% of
74 memset, which is quite good! */
76 * art_rgb_fill_run: fill a buffer a solid RGB color.
77 * @buf: Buffer to fill.
78 * @r: Red, range 0..255.
79 * @g: Green, range 0..255.
80 * @b: Blue, range 0..255.
81 * @n: Number of RGB triples to fill.
83 * Fills a buffer with @n copies of the (@r, @g, @b) triple. Thus,
84 * locations @buf (inclusive) through @buf + 3 * @n (exclusive) are
87 * The implementation of this routine is very highly optimized.
90 art_rgb_fill_run (art_u8
*buf
, art_u8 r
, art_u8 g
, art_u8 b
, int n
)
93 unsigned int v1
, v2
, v3
;
97 memset (buf
, g
, n
+ n
+ n
);
103 for (i
= 0; i
< n
; i
++)
110 /* handle prefix up to byte alignment */
111 /* I'm worried about this cast on sizeof(long) != sizeof(uchar *)
112 architectures, but it _should_ work. */
113 for (i
= 0; ((unsigned long)buf
) & 3; i
++)
119 #ifndef WORDS_BIGENDIAN
120 v1
= r
| (g
<< 8) | (b
<< 16) | (r
<< 24);
124 v1
= (r
<< 24) | (g
<< 16) | (b
<< 8) | r
;
128 for (; i
< n
- 3; i
+= 4)
130 ((art_u32
*)buf
)[0] = v1
;
131 ((art_u32
*)buf
)[1] = v2
;
132 ((art_u32
*)buf
)[2] = v3
;
148 * art_rgb_run_alpha: Render semitransparent color over RGB buffer.
149 * @buf: Buffer for rendering.
150 * @r: Red, range 0..255.
151 * @g: Green, range 0..255.
152 * @b: Blue, range 0..255.
153 * @alpha: Alpha, range 0..256.
154 * @n: Number of RGB triples to render.
156 * Renders a sequential run of solid (@r, @g, @b) color over @buf with
160 art_rgb_run_alpha (art_u8
*buf
, art_u8 r
, art_u8 g
, art_u8 b
, int alpha
, int n
)
165 for (i
= 0; i
< n
; i
++)
168 *buf
++ = v
+ (((r
- v
) * alpha
+ 0x80) >> 8);
170 *buf
++ = v
+ (((g
- v
) * alpha
+ 0x80) >> 8);
172 *buf
++ = v
+ (((b
- v
) * alpha
+ 0x80) >> 8);