3 * Routines for simple 2D->2D transformations for rotated, flipped screens.
5 * XXX This code is not intel-specific. Move it into a common/utility
9 #include "intel_rotate.h"
11 #define MIN2(A, B) ( ((A) < (B)) ? (A) : (B) )
13 #define ABS(A) ( ((A) < 0) ? -(A) : (A) )
17 matrix23Set(struct matrix23
*m
,
18 int m00
, int m01
, int m02
, int m10
, int m11
, int m12
)
30 * Transform (x,y) coordinate by the given matrix.
33 matrix23TransformCoordf(const struct matrix23
*m
, float *x
, float *y
)
38 *x
= m
->m00
* x0
+ m
->m01
* y0
+ m
->m02
;
39 *y
= m
->m10
* x0
+ m
->m11
* y0
+ m
->m12
;
44 matrix23TransformCoordi(const struct matrix23
*m
, int *x
, int *y
)
49 *x
= m
->m00
* x0
+ m
->m01
* y0
+ m
->m02
;
50 *y
= m
->m10
* x0
+ m
->m11
* y0
+ m
->m12
;
55 * Transform a width and height by the given matrix.
56 * XXX this could be optimized quite a bit.
59 matrix23TransformDistance(const struct matrix23
*m
, int *xDist
, int *yDist
)
62 int x1
= *xDist
, y1
= 0;
63 int x2
= 0, y2
= *yDist
;
64 matrix23TransformCoordi(m
, &x0
, &y0
);
65 matrix23TransformCoordi(m
, &x1
, &y1
);
66 matrix23TransformCoordi(m
, &x2
, &y2
);
68 *xDist
= (x1
- x0
) + (x2
- x0
);
69 *yDist
= (y1
- y0
) + (y2
- y0
);
79 * Transform the rect defined by (x, y, w, h) by m.
82 matrix23TransformRect(const struct matrix23
*m
, int *x
, int *y
, int *w
,
86 int x1
= *x
+ *w
, y1
= *y
;
87 int x2
= *x
+ *w
, y2
= *y
+ *h
;
88 int x3
= *x
, y3
= *y
+ *h
;
89 matrix23TransformCoordi(m
, &x0
, &y0
);
90 matrix23TransformCoordi(m
, &x1
, &y1
);
91 matrix23TransformCoordi(m
, &x2
, &y2
);
92 matrix23TransformCoordi(m
, &x3
, &y3
);
93 *w
= ABS(x1
- x0
) + ABS(x2
- x1
);
95 *h
= ABS(y1
- y0
) + ABS(y2
- y1
);
105 * Make rotation matrix for width X height screen.
108 matrix23Rotate(struct matrix23
*m
, int width
, int height
, int angle
)
112 matrix23Set(m
, 1, 0, 0, 0, 1, 0);
115 matrix23Set(m
, 0, 1, 0, -1, 0, width
);
118 matrix23Set(m
, -1, 0, width
, 0, -1, height
);
121 matrix23Set(m
, 0, -1, height
, 1, 0, 0);
130 * Make flip/reflection matrix for width X height screen.
133 matrix23Flip(struct matrix23
*m
, int width
, int height
, int xflip
, int yflip
)
162 matrix23Multiply(struct matrix23
*result
,
163 const struct matrix23
*a
, const struct matrix23
*b
)
165 result
->m00
= a
->m00
* b
->m00
+ a
->m01
* b
->m10
;
166 result
->m01
= a
->m00
* b
->m01
+ a
->m01
* b
->m11
;
167 result
->m02
= a
->m00
* b
->m02
+ a
->m01
* b
->m12
+ a
->m02
;
169 result
->m10
= a
->m10
* b
->m00
+ a
->m11
* b
->m10
;
170 result
->m11
= a
->m10
* b
->m01
+ a
->m11
* b
->m11
;
171 result
->m12
= a
->m10
* b
->m02
+ a
->m11
* b
->m12
+ a
->m12
;
180 main(int argc
, char *argv
[])
182 int width
= 500, height
= 400;
184 int fx
= 0, fy
= 0; /* flip x and/or y ? */
187 /* four corner coords to test with */
190 coords
[1][0] = width
- 1;
192 coords
[2][0] = width
- 1;
193 coords
[2][1] = height
- 1;
195 coords
[3][1] = height
- 1;
198 for (rot
= 0; rot
< 360; rot
+= 90) {
199 struct matrix23 rotate
, flip
, m
;
202 printf("Rot %d, xFlip %d, yFlip %d:\n", rot
, fx
, fy
);
204 /* make transformation matrix 'm' */
205 matrix23Rotate(&rotate
, width
, height
, rot
);
206 matrix23Flip(&flip
, width
, height
, fx
, fy
);
207 matrix23Multiply(&m
, &rotate
, &flip
);
209 /* xform four coords */
210 for (i
= 0; i
< 4; i
++) {
211 int x
= coords
[i
][0];
212 int y
= coords
[i
][1];
213 matrix23TransformCoordi(&m
, &x
, &y
);
214 printf(" %d, %d -> %d %d\n", coords
[i
][0], coords
[i
][1], x
, y
);
217 /* xform width, height */
221 matrix23TransformDistance(&m
, &x
, &y
);
222 printf(" %d x %d -> %d x %d\n", width
, height
, x
, y
);
227 int x
= 50, y
= 10, w
= 200, h
= 100;
228 matrix23TransformRect(&m
, &x
, &y
, &w
, &h
);
229 printf(" %d,%d %d x %d -> %d, %d %d x %d\n", 50, 10, 200, 100,