source: trunk/third/libart_lgpl/art_rgba.c @ 18256

Revision 18256, 6.6 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18255, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * art_rgba.c: Functions for manipulating RGBA pixel data.
3 *
4 * Libart_LGPL - library of basic graphic primitives
5 * Copyright (C) 2000 Raph Levien
6 *
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.
11 *
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.
16 *
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.
21 */
22
23#include "config.h"
24#include "art_rgba.h"
25
26#define ART_OPTIMIZE_SPACE
27
28#ifndef ART_OPTIMIZE_SPACE
29#include "art_rgba_table.c"
30#endif
31
32/**
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.
37 *
38 * Composites the RGBA pixels in @dst over the @src buffer.
39 **/
40void
41art_rgba_rgba_composite (art_u8 *dst, const art_u8 *src, int n)
42{
43  int i;
44#ifdef WORDS_BIGENDIAN
45  art_u32 src_rgba, dst_rgba;
46#else
47  art_u32 src_abgr, dst_abgr;
48#endif
49  art_u8 src_alpha, dst_alpha;
50
51  for (i = 0; i < n; i++)
52    {
53#ifdef WORDS_BIGENDIAN
54      src_rgba = ((art_u32 *)src)[i];
55      src_alpha = src_rgba & 0xff;
56#else
57      src_abgr = ((art_u32 *)src)[i];
58      src_alpha = (src_abgr >> 24) & 0xff;
59#endif
60      if (src_alpha)
61        {
62          if (src_alpha == 0xff ||
63              (
64#ifdef WORDS_BIGENDIAN
65               dst_rgba = ((art_u32 *)dst)[i],
66               dst_alpha = dst_rgba & 0xff,
67#else
68               dst_abgr = ((art_u32 *)dst)[i],
69               dst_alpha = (dst_abgr >> 24),
70#endif
71               dst_alpha == 0))
72#ifdef WORDS_BIGENDIAN
73            ((art_u32 *)dst)[i] = src_rgba;
74#else
75            ((art_u32 *)dst)[i] = src_abgr;
76#endif
77          else
78            {
79              int r, g, b, a;
80              int src_r, src_g, src_b;
81              int dst_r, dst_g, dst_b;
82              int tmp;
83              int c;
84
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;
89#else
90              tmp = art_rgba_composite_table[(src_alpha << 8) + dst_alpha];
91              c = tmp & 0x1ffff;
92              a = tmp >> 24;
93#endif
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;
101#else
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;
108#endif
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;
114#else
115            ((art_u32 *)dst)[i] = (a << 24) | (b << 16) | (g << 8) | r;
116#endif       
117            }
118        }
119#if 0
120      /* it's not clear to me this optimization really wins */
121      else
122        {
123          /* skip over run of transparent pixels */
124          for (; i < n - 1; i++)
125            {
126#ifdef WORDS_BIGENDIAN
127              src_rgba = ((art_u32 *)src)[i + 1];
128              if (src_rgba & 0xff)
129                break;
130#else
131              src_abgr = ((art_u32 *)src)[i + 1];
132              if (src_abgr & 0xff000000)
133                break;
134#endif
135            }
136        }
137#endif
138    }
139}
140
141/**
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.
148 *
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.
152 **/
153void
154art_rgba_fill_run (art_u8 *buf, art_u8 r, art_u8 g, art_u8 b, int n)
155{
156  int i;
157#ifdef WORDS_BIGENDIAN
158  art_u32 src_rgba;
159#else
160  art_u32 src_abgr;
161#endif
162
163#ifdef WORDS_BIGENDIAN
164  src_rgba = (r << 24) | (g << 16) | (b << 8) | 255;
165#else
166  src_abgr = (255 << 24) | (b << 16) | (g << 8) | r;
167#endif
168  for (i = 0; i < n; i++)
169    {
170#ifdef WORDS_BIGENDIAN
171      ((art_u32 *)buf)[i] = src_rgba;
172#else
173      ((art_u32 *)buf)[i] = src_abgr;
174#endif
175    }   
176}
177
178/**
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.
186 *
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.
190 **/
191void
192art_rgba_run_alpha (art_u8 *buf, art_u8 r, art_u8 g, art_u8 b, int alpha, int n)
193{
194  int i;
195#ifdef WORDS_BIGENDIAN
196  art_u32 src_rgba, dst_rgba;
197#else
198  art_u32 src_abgr, dst_abgr;
199#endif
200  art_u8 dst_alpha;
201  int a;
202  int dst_r, dst_g, dst_b;
203  int tmp;
204  int c;
205
206#ifdef WORDS_BIGENDIAN
207  src_rgba = (r << 24) | (g << 16) | (b << 8) | alpha;
208#else
209  src_abgr = (alpha << 24) | (b << 16) | (g << 8) | r;
210#endif
211  for (i = 0; i < n; i++)
212    {
213#ifdef WORDS_BIGENDIAN
214      dst_rgba = ((art_u32 *)buf)[i];
215      dst_alpha = dst_rgba & 0xff;
216#else
217      dst_abgr = ((art_u32 *)buf)[i];
218      dst_alpha = (dst_abgr >> 24) & 0xff;
219#endif
220      if (dst_alpha)
221        {
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;
226#else
227          tmp = art_rgba_composite_table[(alpha << 8) + dst_alpha];
228          c = tmp & 0x1ffff;
229          a = tmp >> 24;
230#endif
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;
235#else
236          dst_r = dst_abgr & 0xff;
237          dst_g = (dst_abgr >> 8) & 0xff;
238          dst_b = (dst_abgr >> 16) & 0xff;
239#endif
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;
245#else
246          ((art_u32 *)buf)[i] = (a << 24) | (dst_b << 16) | (dst_g << 8) | dst_r;
247#endif
248        }
249      else
250        {
251#ifdef WORDS_BIGENDIAN
252          ((art_u32 *)buf)[i] = src_rgba;
253#else
254          ((art_u32 *)buf)[i] = src_abgr;
255#endif
256        }
257    }
258}
Note: See TracBrowser for help on using the repository browser.