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

Revision 18256, 6.0 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/* Libart_LGPL - library of basic graphic primitives
2 * Copyright (C) 1998 Raph Levien
3 *
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.
8 *
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.
13 *
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.
18 */
19
20#include "config.h"
21#include "art_rgb_bitmap_affine.h"
22
23#include <math.h>
24#include "art_misc.h"
25#include "art_point.h"
26#include "art_affine.h"
27#include "art_rgb_affine_private.h"
28
29/* This module handles compositing of affine-transformed bitmap images
30   over rgb pixel buffers. */
31
32/* Composite the source image over the destination image, applying the
33   affine transform. Foreground color is given and assumed to be
34   opaque, background color is assumed to be fully transparent. */
35
36static void
37art_rgb_bitmap_affine_opaque (art_u8 *dst,
38                              int x0, int y0, int x1, int y1,
39                              int dst_rowstride,
40                              const art_u8 *src,
41                              int src_width, int src_height, int src_rowstride,
42                              art_u32 rgb,
43                              const double affine[6],
44                              ArtFilterLevel level,
45                              ArtAlphaGamma *alphagamma)
46{
47  /* Note: this is a slow implementation, and is missing all filter
48     levels other than NEAREST. It is here for clarity of presentation
49     and to establish the interface. */
50  int x, y;
51  double inv[6];
52  art_u8 *dst_p, *dst_linestart;
53  const art_u8 *src_p;
54  ArtPoint pt, src_pt;
55  int src_x, src_y;
56  art_u8 r, g, b;
57  int run_x0, run_x1;
58
59  r = rgb >> 16;
60  g = (rgb >> 8) & 0xff;
61  b = rgb & 0xff;
62  dst_linestart = dst;
63  art_affine_invert (inv, affine);
64  for (y = y0; y < y1; y++)
65    {
66      pt.y = y + 0.5;
67      run_x0 = x0;
68      run_x1 = x1;
69      art_rgb_affine_run (&run_x0, &run_x1, y, src_width, src_height,
70                          inv);
71      dst_p = dst_linestart + (run_x0 - x0) * 3;
72      for (x = run_x0; x < run_x1; x++)
73        {
74          pt.x = x + 0.5;
75          art_affine_point (&src_pt, &pt, inv);
76          src_x = floor (src_pt.x);
77          src_y = floor (src_pt.y);
78          src_p = src + (src_y * src_rowstride) + (src_x >> 3);
79          if (*src_p & (128 >> (src_x & 7)))
80            {
81              dst_p[0] = r;
82              dst_p[1] = g;
83              dst_p[2] = b;
84            }
85          dst_p += 3;
86        }
87      dst_linestart += dst_rowstride;
88    }
89}
90/* Composite the source image over the destination image, applying the
91   affine transform. Foreground color is given, background color is
92   assumed to be fully transparent. */
93
94/**
95 * art_rgb_bitmap_affine: Affine transform source bitmap image and composite.
96 * @dst: Destination image RGB buffer.
97 * @x0: Left coordinate of destination rectangle.
98 * @y0: Top coordinate of destination rectangle.
99 * @x1: Right coordinate of destination rectangle.
100 * @y1: Bottom coordinate of destination rectangle.
101 * @dst_rowstride: Rowstride of @dst buffer.
102 * @src: Source image bitmap buffer.
103 * @src_width: Width of source image.
104 * @src_height: Height of source image.
105 * @src_rowstride: Rowstride of @src buffer.
106 * @rgba: RGBA foreground color, in 0xRRGGBBAA.
107 * @affine: Affine transform.
108 * @level: Filter level.
109 * @alphagamma: #ArtAlphaGamma for gamma-correcting the compositing.
110 *
111 * Affine transform the source image stored in @src, compositing over
112 * the area of destination image @dst specified by the rectangle
113 * (@x0, @y0) - (@x1, @y1).
114 *
115 * The source bitmap stored with MSB as the leftmost pixel. Source 1
116 * bits correspond to the semitransparent color @rgba, while source 0
117 * bits are transparent.
118 *
119 * See art_rgb_affine() for a description of additional parameters.
120 **/
121void
122art_rgb_bitmap_affine (art_u8 *dst,
123                       int x0, int y0, int x1, int y1, int dst_rowstride,
124                       const art_u8 *src,
125                       int src_width, int src_height, int src_rowstride,
126                       art_u32 rgba,
127                       const double affine[6],
128                       ArtFilterLevel level,
129                       ArtAlphaGamma *alphagamma)
130{
131  /* Note: this is a slow implementation, and is missing all filter
132     levels other than NEAREST. It is here for clarity of presentation
133     and to establish the interface. */
134  int x, y;
135  double inv[6];
136  art_u8 *dst_p, *dst_linestart;
137  const art_u8 *src_p;
138  ArtPoint pt, src_pt;
139  int src_x, src_y;
140  int alpha;
141  art_u8 bg_r, bg_g, bg_b;
142  art_u8 fg_r, fg_g, fg_b;
143  art_u8 r, g, b;
144  int run_x0, run_x1;
145
146  alpha = rgba & 0xff;
147  if (alpha == 0xff)
148    {
149      art_rgb_bitmap_affine_opaque (dst, x0, y0, x1, y1, dst_rowstride,
150                                    src,
151                                    src_width, src_height, src_rowstride,
152                                    rgba >> 8,
153                                    affine,
154                                    level,
155                                    alphagamma);
156      return;
157    }
158  /* alpha = (65536 * alpha) / 255; */
159  alpha = (alpha << 8) + alpha + (alpha >> 7);
160  r = rgba >> 24;
161  g = (rgba >> 16) & 0xff;
162  b = (rgba >> 8) & 0xff;
163  dst_linestart = dst;
164  art_affine_invert (inv, affine);
165  for (y = y0; y < y1; y++)
166    {
167      pt.y = y + 0.5;
168      run_x0 = x0;
169      run_x1 = x1;
170      art_rgb_affine_run (&run_x0, &run_x1, y, src_width, src_height,
171                          inv);
172      dst_p = dst_linestart + (run_x0 - x0) * 3;
173      for (x = run_x0; x < run_x1; x++)
174        {
175          pt.x = x + 0.5;
176          art_affine_point (&src_pt, &pt, inv);
177          src_x = floor (src_pt.x);
178          src_y = floor (src_pt.y);
179          src_p = src + (src_y * src_rowstride) + (src_x >> 3);
180          if (*src_p & (128 >> (src_x & 7)))
181            {
182              bg_r = dst_p[0];
183              bg_g = dst_p[1];
184              bg_b = dst_p[2];
185
186              fg_r = bg_r + (((r - bg_r) * alpha + 0x8000) >> 16);
187              fg_g = bg_g + (((g - bg_g) * alpha + 0x8000) >> 16);
188              fg_b = bg_b + (((b - bg_b) * alpha + 0x8000) >> 16);
189
190              dst_p[0] = fg_r;
191              dst_p[1] = fg_g;
192              dst_p[2] = fg_b;
193            }
194          dst_p += 3;
195        }
196      dst_linestart += dst_rowstride;
197    }
198}
Note: See TracBrowser for help on using the repository browser.