]>
Dogcows Code - chaz/openbox/blob - render/image.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 image.c for the Openbox window manager
4 Copyright (c) 2003 Ben Jansens
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 See the COPYING file for a copy of the GNU General Public License.
26 #define FLOOR(i) ((i) & (~0UL << FRACTION))
27 #define AVERAGE(a, b) (((((a) ^ (b)) & 0xfefefefeL) >> 1) + ((a) & (b)))
29 static RrPixel32
* scale_half(RrPixel32
*source
, gint w
, gint h
)
31 RrPixel32
*out
, *dest
, *sourceline
, *sourceline2
;
35 sourceline2
= source
+ w
;
40 out
= dest
= g_new(RrPixel32
, dw
* dh
);
42 for (y
= 0; y
< dh
; ++y
) {
48 for (x
= 0; x
< dw
; ++x
) {
49 *dest
++ = AVERAGE(AVERAGE(*s
, *(s
+1)),
50 AVERAGE(*s2
, *(s2
+1)));
55 sourceline2
+= w
<< 1;
60 static void ImageCopyResampled(RrPixel32
*dst
, RrPixel32
*src
,
61 gulong dstW
, gulong dstH
,
62 gulong srcW
, gulong srcH
)
64 gulong dstX
, dstY
, srcX
, srcY
;
65 gulong srcX1
, srcX2
, srcY1
, srcY2
;
66 gulong ratioX
, ratioY
;
68 ratioX
= (srcW
<< FRACTION
) / dstW
;
69 ratioY
= (srcH
<< FRACTION
) / dstH
;
72 for (dstY
= 0; dstY
< dstH
; dstY
++) {
77 for (dstX
= 0; dstX
< dstW
; dstX
++) {
78 gulong red
= 0, green
= 0, blue
= 0, alpha
= 0;
79 gulong portionX
, portionY
, portionXY
, sumXY
= 0;
85 for (srcY
= srcY1
; srcY
< srcY2
; srcY
+= (1UL << FRACTION
)) {
88 portionY
= (1UL << FRACTION
) - (srcY1
- srcY
);
89 if (portionY
> srcY2
- srcY1
)
90 portionY
= srcY2
- srcY1
;
92 else if (srcY
== FLOOR(srcY2
))
93 portionY
= srcY2
- srcY
;
95 portionY
= (1UL << FRACTION
);
97 for (srcX
= srcX1
; srcX
< srcX2
; srcX
+= (1UL << FRACTION
)) {
100 portionX
= (1UL << FRACTION
) - (srcX1
- srcX
);
101 if (portionX
> srcX2
- srcX1
)
102 portionX
= srcX2
- srcX1
;
104 else if (srcX
== FLOOR(srcX2
))
105 portionX
= srcX2
- srcX
;
107 portionX
= (1UL << FRACTION
);
109 portionXY
= (portionX
* portionY
) >> FRACTION
;
112 pixel
= *(src
+ (srcY
>> FRACTION
) * srcW
+ (srcX
>> FRACTION
));
113 red
+= ((pixel
>> RrDefaultRedOffset
) & 0xFF) * portionXY
;
114 green
+= ((pixel
>> RrDefaultGreenOffset
) & 0xFF) * portionXY
;
115 blue
+= ((pixel
>> RrDefaultBlueOffset
) & 0xFF) * portionXY
;
116 alpha
+= ((pixel
>> RrDefaultAlphaOffset
) & 0xFF) * portionXY
;
120 g_assert(sumXY
!= 0);
126 *dst
++ = (red
<< RrDefaultRedOffset
) |
127 (green
<< RrDefaultGreenOffset
) |
128 (blue
<< RrDefaultBlueOffset
) |
129 (alpha
<< RrDefaultAlphaOffset
);
134 void RrImageDraw(RrPixel32
*target
, RrTextureRGBA
*rgba
,
135 gint target_w
, gint target_h
,
141 gint col
, num_pixels
;
148 dh
= (gint
)(dw
* ((gdouble
)sh
/ sw
));
149 if (dh
> area
->height
) {
151 dw
= (gint
)(dh
* ((gdouble
)sw
/ sh
));
155 return; /* XXX sanity check */
157 if (sw
!= dw
|| sh
!= dh
) {
158 /*if (!(rgba->cache && dw == rgba->cwidth && dh == rgba->cheight))*/ {
160 rgba
->cache
= g_new(RrPixel32
, dw
* dh
);
161 ImageCopyResampled(rgba
->cache
, rgba
->data
, dw
, dh
, sw
, sh
);
165 source
= rgba
->cache
;
170 /* copy source -> dest, and apply the alpha channel */
172 num_pixels
= dw
* dh
;
173 dest
= target
+ area
->x
+ target_w
* area
->y
;
174 while (num_pixels
-- > 0) {
175 guchar alpha
, r
, g
, b
, bgr
, bgg
, bgb
;
177 alpha
= *source
>> RrDefaultAlphaOffset
;
178 r
= *source
>> RrDefaultRedOffset
;
179 g
= *source
>> RrDefaultGreenOffset
;
180 b
= *source
>> RrDefaultBlueOffset
;
182 /* background color */
183 bgr
= *dest
>> RrDefaultRedOffset
;
184 bgg
= *dest
>> RrDefaultGreenOffset
;
185 bgb
= *dest
>> RrDefaultBlueOffset
;
187 r
= bgr
+ (((r
- bgr
) * alpha
) >> 8);
188 g
= bgg
+ (((g
- bgg
) * alpha
) >> 8);
189 b
= bgb
+ (((b
- bgb
) * alpha
) >> 8);
191 *dest
= ((r
<< RrDefaultRedOffset
) |
192 (g
<< RrDefaultGreenOffset
) |
193 (b
<< RrDefaultBlueOffset
));
200 dest
+= target_w
- dw
;
This page took 0.042611 seconds and 4 git commands to generate.