fix crashes reported by Debian Cylab Mayhem Team
[swftools.git] / lib / art / art_render_mask.c
blobce82608dcdf610e580a76699ba1f4ef73abe7b56
1 /*
2 * art_render_mask.c: Alpha mask source for modular rendering.
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.
22 * Authors: Raph Levien <raph@acm.org>
25 #include "config.h"
26 #include "art_render_mask.h"
28 #include <string.h>
31 typedef struct _ArtMaskSourceMask ArtMaskSourceMask;
33 struct _ArtMaskSourceMask {
34 ArtMaskSource super;
35 ArtRender *render;
36 art_boolean first;
37 int x0;
38 int y0;
39 int x1;
40 int y1;
41 const art_u8 *mask_buf;
42 int rowstride;
45 static void
46 art_render_mask_done (ArtRenderCallback *self, ArtRender *render)
48 art_free (self);
51 static int
52 art_render_mask_can_drive (ArtMaskSource *self, ArtRender *render)
54 return 0;
57 static void
58 art_render_mask_render (ArtRenderCallback *self, ArtRender *render,
59 art_u8 *dest, int y)
61 ArtMaskSourceMask *z = (ArtMaskSourceMask *)self;
62 int x0 = render->x0, x1 = render->x1;
63 int z_x0 = z->x0, z_x1 = z->x1;
64 int width = x1 - x0;
65 int z_width = z_x1 - z_x0;
66 art_u8 *alpha_buf = render->alpha_buf;
68 if (y < z->y0 || y >= z->y1 || z_width <= 0)
69 memset (alpha_buf, 0, width);
70 else
72 const art_u8 *src_line = z->mask_buf + (y - z->y0) * z->rowstride;
73 art_u8 *dst_line = alpha_buf + z_x0 - x0;
75 if (z_x0 > x0)
76 memset (alpha_buf, 0, z_x0 - x0);
78 if (z->first)
79 memcpy (dst_line, src_line, z_width);
80 else
82 int x;
84 for (x = 0; x < z_width; x++)
86 int v;
87 v = src_line[x];
88 if (v)
90 v = v * dst_line[x] + 0x80;
91 v = (v + (v >> 8)) >> 8;
92 dst_line[x] = v;
94 else
96 dst_line[x] = 0;
101 if (z_x1 < x1)
102 memset (alpha_buf + z_x1 - x0, 0, x1 - z_x1);
106 static void
107 art_render_mask_prepare (ArtMaskSource *self, ArtRender *render,
108 art_boolean first)
110 ArtMaskSourceMask *z = (ArtMaskSourceMask *)self;
111 self->super.render = art_render_mask_render;
112 z->first = first;
116 * art_render_mask: Use an alpha buffer as a render mask source.
117 * @render: Render object.
118 * @x0: Left coordinate of mask rect.
119 * @y0: Top coordinate of mask rect.
120 * @x1: Right coordinate of mask rect.
121 * @y1: Bottom coordinate of mask rect.
122 * @mask_buf: Buffer containing 8bpp alpha mask data.
123 * @rowstride: Rowstride of @mask_buf.
125 * Adds @mask_buf to the render object as a mask. Note: @mask_buf must
126 * remain allocated until art_render_invoke() is called on @render.
128 void
129 art_render_mask (ArtRender *render,
130 int x0, int y0, int x1, int y1,
131 const art_u8 *mask_buf, int rowstride)
133 ArtMaskSourceMask *mask_source;
135 if (x0 < render->x0)
137 mask_buf += render->x0 - x0;
138 x0 = render->x0;
140 if (x1 > render->x1)
141 x1 = render->x1;
143 if (y0 < render->y0)
145 mask_buf += (render->y0 - y0) * rowstride;
146 y0 = render->y0;
148 if (y1 > render->y1)
149 y1 = render->y1;
151 mask_source = art_new (ArtMaskSourceMask, 1);
153 mask_source->super.super.render = NULL;
154 mask_source->super.super.done = art_render_mask_done;
155 mask_source->super.can_drive = art_render_mask_can_drive;
156 mask_source->super.invoke_driver = NULL;
157 mask_source->super.prepare = art_render_mask_prepare;
158 mask_source->render = render;
159 mask_source->x0 = x0;
160 mask_source->y0 = y0;
161 mask_source->x1 = x1;
162 mask_source->y1 = y1;
163 mask_source->mask_buf = mask_buf;
164 mask_source->rowstride = rowstride;
166 art_render_add_mask_source (render, &mask_source->super);