fix crashes reported by Debian Cylab Mayhem Team
[swftools.git] / lib / art / art_rgb_bitmap_affine.c
blob825f8b56380120aaf01559892c39e47702f7a1bd
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.
20 #include "config.h"
21 #include "art_rgb_bitmap_affine.h"
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"
29 /* This module handles compositing of affine-transformed bitmap images
30 over rgb pixel buffers. */
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. */
36 static void
37 art_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)
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;
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++)
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++)
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)))
81 dst_p[0] = r;
82 dst_p[1] = g;
83 dst_p[2] = b;
85 dst_p += 3;
87 dst_linestart += dst_rowstride;
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. */
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.
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).
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.
119 * See art_rgb_affine() for a description of additional parameters.
121 void
122 art_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)
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;
146 alpha = rgba & 0xff;
147 if (alpha == 0xff)
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;
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++)
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++)
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)))
182 bg_r = dst_p[0];
183 bg_g = dst_p[1];
184 bg_b = dst_p[2];
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);
190 dst_p[0] = fg_r;
191 dst_p[1] = fg_g;
192 dst_p[2] = fg_b;
194 dst_p += 3;
196 dst_linestart += dst_rowstride;