vfs: check userland buffers before reading them.
[haiku.git] / headers / libs / agg / agg_trans_perspective.h
blob0937494a19937ff73c58d30fd1969dcaf78f1be1
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 //----------------------------------------------------------------------------
16 // Perspective 2D transformations
18 //----------------------------------------------------------------------------
19 #ifndef AGG_TRANS_PERSPECTIVE_INCLUDED
20 #define AGG_TRANS_PERSPECTIVE_INCLUDED
22 #include "agg_basics.h"
23 #include "agg_simul_eq.h"
25 namespace agg
27 //=======================================================trans_perspective
28 class trans_perspective
30 public:
31 //--------------------------------------------------------------------
32 trans_perspective() : m_valid(false) {}
35 //--------------------------------------------------------------------
36 // Arbitrary quadrangle transformations
37 trans_perspective(const double* src, const double* dst)
39 quad_to_quad(src, dst);
43 //--------------------------------------------------------------------
44 // Direct transformations
45 trans_perspective(double x1, double y1, double x2, double y2,
46 const double* quad)
48 rect_to_quad(x1, y1, x2, y2, quad);
52 //--------------------------------------------------------------------
53 // Reverse transformations
54 trans_perspective(const double* quad,
55 double x1, double y1, double x2, double y2)
57 quad_to_rect(quad, x1, y1, x2, y2);
61 //--------------------------------------------------------------------
62 // Set the transformations using two arbitrary quadrangles.
63 void quad_to_quad(const double* src, const double* dst)
66 double left[8][8];
67 double right[8][1];
69 unsigned i;
70 for (i = 0; i < 4; i++)
72 unsigned ix = i * 2;
73 unsigned iy = ix + 1;
75 left[ix][0] = 1.0;
76 left[ix][1] = src[ix];
77 left[ix][2] = src[iy];
78 left[ix][3] = 0.0;
79 left[ix][4] = 0.0;
80 left[ix][5] = 0.0;
81 left[ix][6] = -src[ix] * dst[ix];
82 left[ix][7] = -src[iy] * dst[ix];
83 right[ix][0] = dst[ix];
85 left[iy][0] = 0.0;
86 left[iy][1] = 0.0;
87 left[iy][2] = 0.0;
88 left[iy][3] = 1.0;
89 left[iy][4] = src[ix];
90 left[iy][5] = src[iy];
91 left[iy][6] = -src[ix] * dst[iy];
92 left[iy][7] = -src[iy] * dst[iy];
93 right[iy][0] = dst[iy];
95 m_valid = simul_eq<8, 1>::solve(left, right, m_mtx);
99 //--------------------------------------------------------------------
100 // Set the direct transformations, i.e., rectangle -> quadrangle
101 void rect_to_quad(double x1, double y1, double x2, double y2,
102 const double* quad)
104 double src[8];
105 src[0] = src[6] = x1;
106 src[2] = src[4] = x2;
107 src[1] = src[3] = y1;
108 src[5] = src[7] = y2;
109 quad_to_quad(src, quad);
113 //--------------------------------------------------------------------
114 // Set the reverse transformations, i.e., quadrangle -> rectangle
115 void quad_to_rect(const double* quad,
116 double x1, double y1, double x2, double y2)
118 double dst[8];
119 dst[0] = dst[6] = x1;
120 dst[2] = dst[4] = x2;
121 dst[1] = dst[3] = y1;
122 dst[5] = dst[7] = y2;
123 quad_to_quad(quad, dst);
126 //--------------------------------------------------------------------
127 // Check if the equations were solved successfully
128 bool is_valid() const { return m_valid; }
130 //--------------------------------------------------------------------
131 // Transform a point (x, y)
132 void transform(double* x, double* y) const
134 double tx = *x;
135 double ty = *y;
136 double d = 1.0 / (m_mtx[6][0] * tx + m_mtx[7][0] * ty + 1.0);
137 *x = (m_mtx[0][0] + m_mtx[1][0] * tx + m_mtx[2][0] * ty) * d;
138 *y = (m_mtx[3][0] + m_mtx[4][0] * tx + m_mtx[5][0] * ty) * d;
141 //--------------------------------------------------------------------
142 class iterator_x
144 double den;
145 double den_step;
146 double nom_x;
147 double nom_x_step;
148 double nom_y;
149 double nom_y_step;
151 public:
152 double x;
153 double y;
155 iterator_x() {}
156 iterator_x(double tx, double ty, double step, const double m[8][1]) :
157 den(m[6][0] * tx + m[7][0] * ty + 1.0),
158 den_step(m[6][0] * step),
159 nom_x(m[0][0] + m[1][0] * tx + m[2][0] * ty),
160 nom_x_step(m[1][0] * step),
161 nom_y(m[3][0] + m[4][0] * tx + m[5][0] * ty),
162 nom_y_step(m[4][0] * step),
163 x(nom_x / den),
164 y(nom_y / den)
168 void operator ++ ()
170 den += den_step;
171 nom_x += nom_x_step;
172 nom_y += nom_y_step;
173 double d = 1.0 / den;
174 x = nom_x * d;
175 y = nom_y * d;
179 //--------------------------------------------------------------------
180 iterator_x begin(double x, double y, double step) const
182 return iterator_x(x, y, step, m_mtx);
185 private:
186 double m_mtx[8][1];
187 bool m_valid;
192 #endif