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.
22 #include "art_point.h"
23 #include "art_affine.h"
24 #include "art_rgb_affine_private.h"
25 #include "art_rgb_bitmap_affine.h"
27 /* This module handles compositing of affine-transformed bitmap images
28 over rgb pixel buffers. */
30 /* Composite the source image over the destination image, applying the
31 affine transform. Foreground color is given and assumed to be
32 opaque, background color is assumed to be fully transparent. */
35 art_rgb_bitmap_affine_opaque (art_u8 *dst,
36 int x0, int y0, int x1, int y1,
39 int src_width, int src_height, int src_rowstride,
41 const double affine[6],
43 ArtAlphaGamma *alphagamma)
45 /* Note: this is a slow implementation, and is missing all filter
46 levels other than NEAREST. It is here for clarity of presentation
47 and to establish the interface. */
50 art_u8 *dst_p, *dst_linestart;
58 g = (rgb >> 8) & 0xff;
61 art_affine_invert (inv, affine);
62 for (y = y0; y < y1; y++)
67 art_rgb_affine_run (&run_x0, &run_x1, y, src_width, src_height,
69 dst_p = dst_linestart + (run_x0 - x0) * 3;
70 for (x = run_x0; x < run_x1; x++)
73 art_affine_point (&src_pt, &pt, inv);
74 src_x = floor (src_pt.x);
75 src_y = floor (src_pt.y);
76 src_p = src + (src_y * src_rowstride) + (src_x >> 3);
77 if (*src_p & (128 >> (src_x & 7)))
85 dst_linestart += dst_rowstride;
88 /* Composite the source image over the destination image, applying the
89 affine transform. Foreground color is given, background color is
90 assumed to be fully transparent. */
93 * art_rgb_bitmap_affine: Affine transform source bitmap image and composite.
94 * @dst: Destination image RGB buffer.
95 * @x0: Left coordinate of destination rectangle.
96 * @y0: Top coordinate of destination rectangle.
97 * @x1: Right coordinate of destination rectangle.
98 * @y1: Bottom coordinate of destination rectangle.
99 * @dst_rowstride: Rowstride of @dst buffer.
100 * @src: Source image bitmap buffer.
101 * @src_width: Width of source image.
102 * @src_height: Height of source image.
103 * @src_rowstride: Rowstride of @src buffer.
104 * @rgba: RGBA foreground color, in 0xRRGGBBAA.
105 * @affine: Affine transform.
106 * @level: Filter level.
107 * @alphagamma: #ArtAlphaGamma for gamma-correcting the compositing.
109 * Affine transform the source image stored in @src, compositing over
110 * the area of destination image @dst specified by the rectangle
111 * (@x0, @y0) - (@x1, @y1).
113 * The source bitmap stored with MSB as the leftmost pixel. Source 1
114 * bits correspond to the semitransparent color @rgba, while source 0
115 * bits are transparent.
117 * See art_rgb_affine() for a description of additional parameters.
120 art_rgb_bitmap_affine (art_u8 *dst,
121 int x0, int y0, int x1, int y1, int dst_rowstride,
123 int src_width, int src_height, int src_rowstride,
125 const double affine[6],
126 ArtFilterLevel level,
127 ArtAlphaGamma *alphagamma)
129 /* Note: this is a slow implementation, and is missing all filter
130 levels other than NEAREST. It is here for clarity of presentation
131 and to establish the interface. */
134 art_u8 *dst_p, *dst_linestart;
139 art_u8 bg_r, bg_g, bg_b;
140 art_u8 fg_r, fg_g, fg_b;
147 art_rgb_bitmap_affine_opaque (dst, x0, y0, x1, y1, dst_rowstride,
149 src_width, src_height, src_rowstride,
156 /* alpha = (65536 * alpha) / 255; */
157 alpha = (alpha << 8) + alpha + (alpha >> 7);
159 g = (rgba >> 16) & 0xff;
160 b = (rgba >> 8) & 0xff;
162 art_affine_invert (inv, affine);
163 for (y = y0; y < y1; y++)
168 art_rgb_affine_run (&run_x0, &run_x1, y, src_width, src_height,
170 dst_p = dst_linestart + (run_x0 - x0) * 3;
171 for (x = run_x0; x < run_x1; x++)
174 art_affine_point (&src_pt, &pt, inv);
175 src_x = floor (src_pt.x);
176 src_y = floor (src_pt.y);
177 src_p = src + (src_y * src_rowstride) + (src_x >> 3);
178 if (*src_p & (128 >> (src_x & 7)))
184 fg_r = bg_r + (((r - bg_r) * alpha + 0x8000) >> 16);
185 fg_g = bg_g + (((g - bg_g) * alpha + 0x8000) >> 16);
186 fg_b = bg_b + (((b - bg_b) * alpha + 0x8000) >> 16);
194 dst_linestart += dst_rowstride;