vfs: check userland buffers before reading them.
[haiku.git] / headers / libs / agg / agg_span_interpolator_persp.h
blobcad437e04f50c9a8d8a14db4e7a47f860173bcde
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
15 #ifndef AGG_SPAN_INTERPOLATOR_PERSP_INCLUDED
16 #define AGG_SPAN_INTERPOLATOR_PERSP_INCLUDED
18 #include "agg_trans_perspective.h"
19 #include "agg_dda_line.h"
21 namespace agg
26 //===========================================span_interpolator_persp_exact
27 template<unsigned SubpixelShift = 8>
28 class span_interpolator_persp_exact
30 public:
31 typedef trans_perspective trans_type;
32 typedef trans_perspective::iterator_x iterator_type;
33 enum subpixel_scale_e
35 subpixel_shift = SubpixelShift,
36 subpixel_scale = 1 << subpixel_shift
39 //--------------------------------------------------------------------
40 span_interpolator_persp_exact() {}
42 //--------------------------------------------------------------------
43 // Arbitrary quadrangle transformations
44 span_interpolator_persp_exact(const double* src, const double* dst)
46 quad_to_quad(src, dst);
49 //--------------------------------------------------------------------
50 // Direct transformations
51 span_interpolator_persp_exact(double x1, double y1,
52 double x2, double y2,
53 const double* quad)
55 rect_to_quad(x1, y1, x2, y2, quad);
58 //--------------------------------------------------------------------
59 // Reverse transformations
60 span_interpolator_persp_exact(const double* quad,
61 double x1, double y1,
62 double x2, double y2)
64 quad_to_rect(quad, x1, y1, x2, y2);
67 //--------------------------------------------------------------------
68 // Set the transformations using two arbitrary quadrangles.
69 void quad_to_quad(const double* src, const double* dst)
71 m_trans_dir.quad_to_quad(src, dst);
72 m_trans_inv.quad_to_quad(dst, src);
75 //--------------------------------------------------------------------
76 // Set the direct transformations, i.e., rectangle -> quadrangle
77 void rect_to_quad(double x1, double y1, double x2, double y2,
78 const double* quad)
80 double src[8];
81 src[0] = src[6] = x1;
82 src[2] = src[4] = x2;
83 src[1] = src[3] = y1;
84 src[5] = src[7] = y2;
85 quad_to_quad(src, quad);
89 //--------------------------------------------------------------------
90 // Set the reverse transformations, i.e., quadrangle -> rectangle
91 void quad_to_rect(const double* quad,
92 double x1, double y1, double x2, double y2)
94 double dst[8];
95 dst[0] = dst[6] = x1;
96 dst[2] = dst[4] = x2;
97 dst[1] = dst[3] = y1;
98 dst[5] = dst[7] = y2;
99 quad_to_quad(quad, dst);
102 //--------------------------------------------------------------------
103 // Check if the equations were solved successfully
104 bool is_valid() const { return m_trans_dir.is_valid(); }
106 //----------------------------------------------------------------
107 void begin(double x, double y, unsigned len)
109 m_iterator = m_trans_dir.begin(x, y, 1.0);
110 double xt = m_iterator.x;
111 double yt = m_iterator.y;
113 double dx;
114 double dy;
115 const double delta = 1/double(subpixel_scale);
116 dx = xt + delta;
117 dy = yt;
118 m_trans_inv.transform(&dx, &dy);
119 dx -= x;
120 dy -= y;
121 int sx1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
122 dx = xt;
123 dy = yt + delta;
124 m_trans_inv.transform(&dx, &dy);
125 dx -= x;
126 dy -= y;
127 int sy1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
129 x += len;
130 xt = x;
131 yt = y;
132 m_trans_dir.transform(&xt, &yt);
134 dx = xt + delta;
135 dy = yt;
136 m_trans_inv.transform(&dx, &dy);
137 dx -= x;
138 dy -= y;
139 int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
140 dx = xt;
141 dy = yt + delta;
142 m_trans_inv.transform(&dx, &dy);
143 dx -= x;
144 dy -= y;
145 int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
147 m_scale_x = dda2_line_interpolator(sx1, sx2, len);
148 m_scale_y = dda2_line_interpolator(sy1, sy2, len);
152 //----------------------------------------------------------------
153 void resynchronize(double xe, double ye, unsigned len)
155 // Assume x1,y1 are equal to the ones at the previous end point
156 int sx1 = m_scale_x.y();
157 int sy1 = m_scale_y.y();
159 // Calculate transformed coordinates at x2,y2
160 double xt = xe;
161 double yt = ye;
162 m_trans_dir.transform(&xt, &yt);
164 const double delta = 1/double(subpixel_scale);
165 double dx;
166 double dy;
168 // Calculate scale by X at x2,y2
169 dx = xt + delta;
170 dy = yt;
171 m_trans_inv.transform(&dx, &dy);
172 dx -= xe;
173 dy -= ye;
174 int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
176 // Calculate scale by Y at x2,y2
177 dx = xt;
178 dy = yt + delta;
179 m_trans_inv.transform(&dx, &dy);
180 dx -= xe;
181 dy -= ye;
182 int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
184 // Initialize the interpolators
185 m_scale_x = dda2_line_interpolator(sx1, sx2, len);
186 m_scale_y = dda2_line_interpolator(sy1, sy2, len);
191 //----------------------------------------------------------------
192 void operator++()
194 ++m_iterator;
195 ++m_scale_x;
196 ++m_scale_y;
199 //----------------------------------------------------------------
200 void coordinates(int* x, int* y) const
202 *x = iround(m_iterator.x * subpixel_scale);
203 *y = iround(m_iterator.y * subpixel_scale);
206 //----------------------------------------------------------------
207 void local_scale(int* x, int* y)
209 *x = m_scale_x.y();
210 *y = m_scale_y.y();
213 //----------------------------------------------------------------
214 void transform(double* x, double* y) const
216 m_trans_dir.transform(x, y);
219 private:
220 trans_type m_trans_dir;
221 trans_type m_trans_inv;
222 iterator_type m_iterator;
223 dda2_line_interpolator m_scale_x;
224 dda2_line_interpolator m_scale_y;
237 //============================================span_interpolator_persp_lerp
238 template<unsigned SubpixelShift = 8>
239 class span_interpolator_persp_lerp
241 public:
242 typedef trans_perspective trans_type;
243 enum subpixel_scale_e
245 subpixel_shift = SubpixelShift,
246 subpixel_scale = 1 << subpixel_shift
249 //--------------------------------------------------------------------
250 span_interpolator_persp_lerp() {}
252 //--------------------------------------------------------------------
253 // Arbitrary quadrangle transformations
254 span_interpolator_persp_lerp(const double* src, const double* dst)
256 quad_to_quad(src, dst);
259 //--------------------------------------------------------------------
260 // Direct transformations
261 span_interpolator_persp_lerp(double x1, double y1,
262 double x2, double y2,
263 const double* quad)
265 rect_to_quad(x1, y1, x2, y2, quad);
268 //--------------------------------------------------------------------
269 // Reverse transformations
270 span_interpolator_persp_lerp(const double* quad,
271 double x1, double y1,
272 double x2, double y2)
274 quad_to_rect(quad, x1, y1, x2, y2);
277 //--------------------------------------------------------------------
278 // Set the transformations using two arbitrary quadrangles.
279 void quad_to_quad(const double* src, const double* dst)
281 m_trans_dir.quad_to_quad(src, dst);
282 m_trans_inv.quad_to_quad(dst, src);
285 //--------------------------------------------------------------------
286 // Set the direct transformations, i.e., rectangle -> quadrangle
287 void rect_to_quad(double x1, double y1, double x2, double y2,
288 const double* quad)
290 double src[8];
291 src[0] = src[6] = x1;
292 src[2] = src[4] = x2;
293 src[1] = src[3] = y1;
294 src[5] = src[7] = y2;
295 quad_to_quad(src, quad);
299 //--------------------------------------------------------------------
300 // Set the reverse transformations, i.e., quadrangle -> rectangle
301 void quad_to_rect(const double* quad,
302 double x1, double y1, double x2, double y2)
304 double dst[8];
305 dst[0] = dst[6] = x1;
306 dst[2] = dst[4] = x2;
307 dst[1] = dst[3] = y1;
308 dst[5] = dst[7] = y2;
309 quad_to_quad(quad, dst);
312 //--------------------------------------------------------------------
313 // Check if the equations were solved successfully
314 bool is_valid() const { return m_trans_dir.is_valid(); }
316 //----------------------------------------------------------------
317 void begin(double x, double y, unsigned len)
319 // Calculate transformed coordinates at x1,y1
320 double xt = x;
321 double yt = y;
322 m_trans_dir.transform(&xt, &yt);
323 int x1 = iround(xt * subpixel_scale);
324 int y1 = iround(yt * subpixel_scale);
326 double dx;
327 double dy;
328 const double delta = 1/double(subpixel_scale);
330 // Calculate scale by X at x1,y1
331 dx = xt + delta;
332 dy = yt;
333 m_trans_inv.transform(&dx, &dy);
334 dx -= x;
335 dy -= y;
336 int sx1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
338 // Calculate scale by Y at x1,y1
339 dx = xt;
340 dy = yt + delta;
341 m_trans_inv.transform(&dx, &dy);
342 dx -= x;
343 dy -= y;
344 int sy1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
346 // Calculate transformed coordinates at x2,y2
347 x += len;
348 xt = x;
349 yt = y;
350 m_trans_dir.transform(&xt, &yt);
351 int x2 = iround(xt * subpixel_scale);
352 int y2 = iround(yt * subpixel_scale);
354 // Calculate scale by X at x2,y2
355 dx = xt + delta;
356 dy = yt;
357 m_trans_inv.transform(&dx, &dy);
358 dx -= x;
359 dy -= y;
360 int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
362 // Calculate scale by Y at x2,y2
363 dx = xt;
364 dy = yt + delta;
365 m_trans_inv.transform(&dx, &dy);
366 dx -= x;
367 dy -= y;
368 int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
370 // Initialize the interpolators
371 m_coord_x = dda2_line_interpolator(x1, x2, len);
372 m_coord_y = dda2_line_interpolator(y1, y2, len);
373 m_scale_x = dda2_line_interpolator(sx1, sx2, len);
374 m_scale_y = dda2_line_interpolator(sy1, sy2, len);
378 //----------------------------------------------------------------
379 void resynchronize(double xe, double ye, unsigned len)
381 // Assume x1,y1 are equal to the ones at the previous end point
382 int x1 = m_coord_x.y();
383 int y1 = m_coord_y.y();
384 int sx1 = m_scale_x.y();
385 int sy1 = m_scale_y.y();
387 // Calculate transformed coordinates at x2,y2
388 double xt = xe;
389 double yt = ye;
390 m_trans_dir.transform(&xt, &yt);
391 int x2 = iround(xt * subpixel_scale);
392 int y2 = iround(yt * subpixel_scale);
394 const double delta = 1/double(subpixel_scale);
395 double dx;
396 double dy;
398 // Calculate scale by X at x2,y2
399 dx = xt + delta;
400 dy = yt;
401 m_trans_inv.transform(&dx, &dy);
402 dx -= xe;
403 dy -= ye;
404 int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
406 // Calculate scale by Y at x2,y2
407 dx = xt;
408 dy = yt + delta;
409 m_trans_inv.transform(&dx, &dy);
410 dx -= xe;
411 dy -= ye;
412 int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
414 // Initialize the interpolators
415 m_coord_x = dda2_line_interpolator(x1, x2, len);
416 m_coord_y = dda2_line_interpolator(y1, y2, len);
417 m_scale_x = dda2_line_interpolator(sx1, sx2, len);
418 m_scale_y = dda2_line_interpolator(sy1, sy2, len);
422 //----------------------------------------------------------------
423 void operator++()
425 ++m_coord_x;
426 ++m_coord_y;
427 ++m_scale_x;
428 ++m_scale_y;
431 //----------------------------------------------------------------
432 void coordinates(int* x, int* y) const
434 *x = m_coord_x.y();
435 *y = m_coord_y.y();
438 //----------------------------------------------------------------
439 void local_scale(int* x, int* y)
441 *x = m_scale_x.y();
442 *y = m_scale_y.y();
445 //----------------------------------------------------------------
446 void transform(double* x, double* y) const
448 m_trans_dir.transform(x, y);
451 private:
452 trans_type m_trans_dir;
453 trans_type m_trans_inv;
454 dda2_line_interpolator m_coord_x;
455 dda2_line_interpolator m_coord_y;
456 dda2_line_interpolator m_scale_x;
457 dda2_line_interpolator m_scale_y;
462 #endif