Initialize Tizen 2.3
[adaptation/xorg/driver/xserver-xorg-video-emulfb.git] / src / util / fbdev_pixman.c
1 /**************************************************************************
2
3 xserver-xorg-video-emulfb
4
5 Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
6
7 Contact: Boram Park <boram1288.park@samsung.com>
8
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
19 of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29 **************************************************************************/
30
31 #include "fbdev_util.h"
32 #include "fbdev_pixman.h"
33
34 int
35 fbdev_pixman_convert_image (pixman_op_t op,
36                             unsigned char      *srcbuf,
37                             unsigned char      *dstbuf,
38                             pixman_format_code_t src_format,
39                             pixman_format_code_t dst_format,
40                             xRectangle *img,
41                             xRectangle *pxm,
42                             xRectangle *src,
43                             xRectangle *dst,
44                             RegionPtr   clip_region,
45                             int         rotate,
46                             int         hflip,
47                             int         vflip)
48 {
49         pixman_image_t    *src_img;
50         pixman_image_t    *dst_img;
51         struct pixman_f_transform ft;
52         pixman_transform_t transform;
53         int                src_stride, dst_stride;
54         int                src_bpp;
55         int                dst_bpp;
56         double             scale_x, scale_y;
57         int                rotate_step;
58         int                ret = FALSE;
59
60         return_val_if_fail (srcbuf != NULL, FALSE);
61         return_val_if_fail (dstbuf != NULL, FALSE);
62         return_val_if_fail (img != NULL, FALSE);
63         return_val_if_fail (pxm != NULL, FALSE);
64         return_val_if_fail (src != NULL, FALSE);
65         return_val_if_fail (dst != NULL, FALSE);
66         return_val_if_fail (rotate <= 360 && rotate >= -360, FALSE);
67
68         DRVLOG ("[Convert] img(%d,%d %dx%d) src(%d,%d %dx%d) pxm(%d,%d %dx%d) dst(%d,%d %dx%d) sflip(%d,%d), r(%d)\n",
69                 img->x, img->y, img->width, img->height,
70                 src->x, src->y, src->width, src->height,
71                 pxm->x, pxm->y, pxm->width, pxm->height,
72                 dst->x, dst->y, dst->width, dst->height,
73                 hflip, vflip, rotate);
74
75         src_bpp = PIXMAN_FORMAT_BPP (src_format) / 8;
76         return_val_if_fail (src_bpp > 0, FALSE);
77
78         dst_bpp = PIXMAN_FORMAT_BPP (dst_format) / 8;
79         return_val_if_fail (dst_bpp > 0, FALSE);
80
81         rotate_step = (rotate + 360) / 90 % 4;
82
83         src_stride = img->width * src_bpp;
84         dst_stride = pxm->width * dst_bpp;
85
86         src_img = pixman_image_create_bits (src_format, img->width, img->height, (uint32_t*)srcbuf, src_stride);
87         dst_img = pixman_image_create_bits (dst_format, pxm->width, pxm->height, (uint32_t*)dstbuf, dst_stride);
88
89         goto_if_fail (src_img != NULL, CANT_CONVERT);
90         goto_if_fail (dst_img != NULL, CANT_CONVERT);
91
92         pixman_f_transform_init_identity (&ft);
93
94         if (hflip)
95         {
96                 pixman_f_transform_scale (&ft, NULL, -1, 1);
97                 pixman_f_transform_translate (&ft, NULL, dst->width, 0);
98         }
99
100         if (vflip)
101         {
102                 pixman_f_transform_scale (&ft, NULL, 1, -1);
103                 pixman_f_transform_translate (&ft, NULL, 0, dst->height);
104         }
105
106         if (rotate_step > 0)
107         {
108                 int c, s, tx = 0, ty = 0;
109                 switch (rotate_step)
110                 {
111                 case 1:
112                         /* 90 degrees */
113                         c = 0;
114                         s = -1;
115                         tx = -dst->width;
116                         break;
117                 case 2:
118                         /* 180 degrees */
119                         c = -1;
120                         s = 0;
121                         tx = -dst->width;
122                         ty = -dst->height;
123                         break;
124                 case 3:
125                         /* 270 degrees */
126                         c = 0;
127                         s = 1;
128                         ty = -dst->height;
129                         break;
130                 default:
131                         /* 0 degrees */
132                         c = 0;
133                         s = 0;
134                         break;
135                 }
136
137                 pixman_f_transform_translate (&ft, NULL, tx, ty);
138                 pixman_f_transform_rotate (&ft, NULL, c, s);
139         }
140
141         if (rotate_step % 2 == 0)
142         {
143                 scale_x = (double)src->width / dst->width;
144                 scale_y = (double)src->height / dst->height;
145         }
146         else
147         {
148                 scale_x = (double)src->width / dst->height;
149                 scale_y = (double)src->height / dst->width;
150         }
151
152         pixman_f_transform_scale (&ft, NULL, scale_x, scale_y);
153         pixman_f_transform_translate (&ft, NULL, src->x, src->y);
154
155         pixman_transform_from_pixman_f_transform (&transform, &ft);
156         pixman_image_set_transform (src_img, &transform);
157
158         pixman_image_composite (op, src_img, NULL, dst_img,
159                                 0, 0, 0, 0, dst->x, dst->y, dst->width, dst->height);
160
161         ret = TRUE;
162
163 CANT_CONVERT:
164         if (src_img)
165                 pixman_image_unref (src_img);
166         if (dst_img)
167                 pixman_image_unref (dst_img);
168
169         return ret;
170 }