2 * art_rgba.c: Functions for manipulating RGBA pixel data.
4 * Libart_LGPL - library of basic graphic primitives
5 * Copyright (C) 2000 Raph Levien
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
26 #define ART_OPTIMIZE_SPACE
28 #ifndef ART_OPTIMIZE_SPACE
29 #include "art_rgba_table.c"
33 * art_rgba_rgba_composite: Composite RGBA image over RGBA buffer.
34 * @dst: Destination RGBA buffer.
35 * @src: Source RGBA buffer.
36 * @n: Number of RGBA pixels to composite.
38 * Composites the RGBA pixels in @dst over the @src buffer.
41 art_rgba_rgba_composite (art_u8
*dst
, const art_u8
*src
, int n
)
44 #ifdef WORDS_BIGENDIAN
45 art_u32 src_rgba
, dst_rgba
;
47 art_u32 src_abgr
, dst_abgr
;
49 art_u8 src_alpha
, dst_alpha
;
51 for (i
= 0; i
< n
; i
++)
53 #ifdef WORDS_BIGENDIAN
54 src_rgba
= ((art_u32
*)src
)[i
];
55 src_alpha
= src_rgba
& 0xff;
57 src_abgr
= ((art_u32
*)src
)[i
];
58 src_alpha
= (src_abgr
>> 24) & 0xff;
62 if (src_alpha
== 0xff ||
64 #ifdef WORDS_BIGENDIAN
65 dst_rgba
= ((art_u32
*)dst
)[i
],
66 dst_alpha
= dst_rgba
& 0xff,
68 dst_abgr
= ((art_u32
*)dst
)[i
],
69 dst_alpha
= (dst_abgr
>> 24),
72 #ifdef WORDS_BIGENDIAN
73 ((art_u32
*)dst
)[i
] = src_rgba
;
75 ((art_u32
*)dst
)[i
] = src_abgr
;
80 int src_r
, src_g
, src_b
;
81 int dst_r
, dst_g
, dst_b
;
85 #ifdef ART_OPTIMIZE_SPACE
86 tmp
= (255 - src_alpha
) * (255 - dst_alpha
) + 0x80;
87 a
= 255 - ((tmp
+ (tmp
>> 8)) >> 8);
88 c
= ((src_alpha
<< 16) + (a
>> 1)) / a
;
90 tmp
= art_rgba_composite_table
[(src_alpha
<< 8) + dst_alpha
];
94 #ifdef WORDS_BIGENDIAN
95 src_r
= (src_rgba
>> 24) & 0xff;
96 src_g
= (src_rgba
>> 16) & 0xff;
97 src_b
= (src_rgba
>> 8) & 0xff;
98 dst_r
= (dst_rgba
>> 24) & 0xff;
99 dst_g
= (dst_rgba
>> 16) & 0xff;
100 dst_b
= (dst_rgba
>> 8) & 0xff;
102 src_r
= src_abgr
& 0xff;
103 src_g
= (src_abgr
>> 8) & 0xff;
104 src_b
= (src_abgr
>> 16) & 0xff;
105 dst_r
= dst_abgr
& 0xff;
106 dst_g
= (dst_abgr
>> 8) & 0xff;
107 dst_b
= (dst_abgr
>> 16) & 0xff;
109 r
= dst_r
+ (((src_r
- dst_r
) * c
+ 0x8000) >> 16);
110 g
= dst_g
+ (((src_g
- dst_g
) * c
+ 0x8000) >> 16);
111 b
= dst_b
+ (((src_b
- dst_b
) * c
+ 0x8000) >> 16);
112 #ifdef WORDS_BIGENDIAN
113 ((art_u32
*)dst
)[i
] = (r
<< 24) | (g
<< 16) | (b
<< 8) | a
;
115 ((art_u32
*)dst
)[i
] = (a
<< 24) | (b
<< 16) | (g
<< 8) | r
;
120 /* it's not clear to me this optimization really wins */
123 /* skip over run of transparent pixels */
124 for (; i
< n
- 1; i
++)
126 #ifdef WORDS_BIGENDIAN
127 src_rgba
= ((art_u32
*)src
)[i
+ 1];
131 src_abgr
= ((art_u32
*)src
)[i
+ 1];
132 if (src_abgr
& 0xff000000)
142 * art_rgba_fill_run: fill an RGBA buffer a solid RGB color.
143 * @buf: Buffer to fill.
144 * @r: Red, range 0..255.
145 * @g: Green, range 0..255.
146 * @b: Blue, range 0..255.
147 * @n: Number of RGB triples to fill.
149 * Fills a buffer with @n copies of the (@r, @g, @b) triple, solid
150 * alpha. Thus, locations @buf (inclusive) through @buf + 4 * @n
151 * (exclusive) are written.
154 art_rgba_fill_run (art_u8
*buf
, art_u8 r
, art_u8 g
, art_u8 b
, int n
)
157 #ifdef WORDS_BIGENDIAN
163 #ifdef WORDS_BIGENDIAN
164 src_rgba
= (r
<< 24) | (g
<< 16) | (b
<< 8) | 255;
166 src_abgr
= (255 << 24) | (b
<< 16) | (g
<< 8) | r
;
168 for (i
= 0; i
< n
; i
++)
170 #ifdef WORDS_BIGENDIAN
171 ((art_u32
*)buf
)[i
] = src_rgba
;
173 ((art_u32
*)buf
)[i
] = src_abgr
;
179 * art_rgba_run_alpha: Render semitransparent color over RGBA buffer.
180 * @buf: Buffer for rendering.
181 * @r: Red, range 0..255.
182 * @g: Green, range 0..255.
183 * @b: Blue, range 0..255.
184 * @alpha: Alpha, range 0..255.
185 * @n: Number of RGB triples to render.
187 * Renders a sequential run of solid (@r, @g, @b) color over @buf with
188 * opacity @alpha. Note that the range of @alpha is 0..255, in contrast
189 * to art_rgb_run_alpha, which has a range of 0..256.
192 art_rgba_run_alpha (art_u8
*buf
, art_u8 r
, art_u8 g
, art_u8 b
, int alpha
, int n
)
195 #ifdef WORDS_BIGENDIAN
196 art_u32 src_rgba
, dst_rgba
;
198 art_u32 src_abgr
, dst_abgr
;
202 int dst_r
, dst_g
, dst_b
;
206 #ifdef WORDS_BIGENDIAN
207 src_rgba
= (r
<< 24) | (g
<< 16) | (b
<< 8) | alpha
;
209 src_abgr
= (alpha
<< 24) | (b
<< 16) | (g
<< 8) | r
;
211 for (i
= 0; i
< n
; i
++)
213 #ifdef WORDS_BIGENDIAN
214 dst_rgba
= ((art_u32
*)buf
)[i
];
215 dst_alpha
= dst_rgba
& 0xff;
217 dst_abgr
= ((art_u32
*)buf
)[i
];
218 dst_alpha
= (dst_abgr
>> 24) & 0xff;
222 #ifdef ART_OPTIMIZE_SPACE
223 tmp
= (255 - alpha
) * (255 - dst_alpha
) + 0x80;
224 a
= 255 - ((tmp
+ (tmp
>> 8)) >> 8);
225 c
= ((alpha
<< 16) + (a
>> 1)) / a
;
227 tmp
= art_rgba_composite_table
[(alpha
<< 8) + dst_alpha
];
231 #ifdef WORDS_BIGENDIAN
232 dst_r
= (dst_rgba
>> 24) & 0xff;
233 dst_g
= (dst_rgba
>> 16) & 0xff;
234 dst_b
= (dst_rgba
>> 8) & 0xff;
236 dst_r
= dst_abgr
& 0xff;
237 dst_g
= (dst_abgr
>> 8) & 0xff;
238 dst_b
= (dst_abgr
>> 16) & 0xff;
240 dst_r
+= (((r
- dst_r
) * c
+ 0x8000) >> 16);
241 dst_g
+= (((g
- dst_g
) * c
+ 0x8000) >> 16);
242 dst_b
+= (((b
- dst_b
) * c
+ 0x8000) >> 16);
243 #ifdef WORDS_BIGENDIAN
244 ((art_u32
*)buf
)[i
] = (dst_r
<< 24) | (dst_g
<< 16) | (dst_b
<< 8) | a
;
246 ((art_u32
*)buf
)[i
] = (a
<< 24) | (dst_b
<< 16) | (dst_g
<< 8) | dst_r
;
251 #ifdef WORDS_BIGENDIAN
252 ((art_u32
*)buf
)[i
] = src_rgba
;
254 ((art_u32
*)buf
)[i
] = src_abgr
;