]>
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.
25 #define AVERAGE(a, b) ( ((((a) ^ (b)) & 0xfefefefeL) >> 1) + ((a) & (b)) )
27 static void scale_line(RrPixel32
*dest
, RrPixel32
*source
, gint w
, gint dw
)
30 gint int_part
= w
/ dw
;
31 gint fract_part
= w
% dw
;
34 while (num_pixels
-- > 0) {
45 static RrPixel32
* scale_half(RrPixel32
*source
, gint w
, gint h
)
47 RrPixel32
*out
, *dest
, *sourceline
, *sourceline2
;
51 sourceline2
= source
+ w
;
56 out
= dest
= g_new(RrPixel32
, dw
* dh
);
58 for (y
= 0; y
< dh
; ++y
) {
64 for (x
= 0; x
< dw
; ++x
) {
65 *dest
++ = AVERAGE(AVERAGE(*s
, *(s
+1)),
66 AVERAGE(*s2
, *(s2
+1)));
71 sourceline2
+= w
<< 1;
76 static RrPixel32
* scale_rect(RrPixel32
*fullsource
,
77 gint w
, gint h
, gint dw
, gint dh
)
79 RrPixel32
*out
, *dest
;
80 RrPixel32
*source
= fullsource
;
81 RrPixel32
*oldsource
= NULL
;
82 RrPixel32
*prev_source
= NULL
;
88 while (dw
<= (w
>> 1) && dh
<= (h
>> 1)) {
89 source
= scale_half(source
, w
, h
);
96 int_part
= (h
/ dh
) * w
;
99 out
= dest
= g_new(RrPixel32
, dw
* dh
);
101 while (num_pixels
-- > 0) {
102 if (source
== prev_source
) {
103 memcpy(dest
, dest
- dw
, dw
* sizeof(RrPixel32
));
105 scale_line(dest
, source
, w
, dw
);
106 prev_source
= source
;
122 void RrImageDraw(RrPixel32
*target
, RrTextureRGBA
*rgba
,
123 gint target_w
, gint target_h
,
129 gint col
, num_pixels
;
136 dh
= (gint
)(dw
* ((gdouble
)sh
/ sw
));
137 if (dh
> area
->height
) {
139 dw
= (gint
)(dh
* ((gdouble
)sw
/ sh
));
143 return; /* XXX sanity check */
145 if (sw
!= dw
|| sh
!= dh
) {
146 /*if (!(rgba->cache && dw == rgba->cwidth && dh == rgba->cheight))*/ {
148 rgba
->cache
= scale_rect(rgba
->data
, sw
, sh
, dw
, dh
);
152 source
= rgba
->cache
;
157 /* copy source -> dest, and apply the alpha channel */
159 num_pixels
= dw
* dh
;
160 dest
= target
+ area
->x
+ target_w
* area
->y
;
161 while (num_pixels
-- > 0) {
162 guchar alpha
, r
, g
, b
, bgr
, bgg
, bgb
;
164 alpha
= *source
>> RrDefaultAlphaOffset
;
165 r
= *source
>> RrDefaultRedOffset
;
166 g
= *source
>> RrDefaultGreenOffset
;
167 b
= *source
>> RrDefaultBlueOffset
;
169 /* background color */
170 bgr
= *dest
>> RrDefaultRedOffset
;
171 bgg
= *dest
>> RrDefaultGreenOffset
;
172 bgb
= *dest
>> RrDefaultBlueOffset
;
174 r
= bgr
+ (((r
- bgr
) * alpha
) >> 8);
175 g
= bgg
+ (((g
- bgg
) * alpha
) >> 8);
176 b
= bgb
+ (((b
- bgb
) * alpha
) >> 8);
178 *dest
= ((r
<< RrDefaultRedOffset
) |
179 (g
<< RrDefaultGreenOffset
) |
180 (b
<< RrDefaultBlueOffset
));
187 dest
+= target_w
- dw
;
This page took 0.040826 seconds and 4 git commands to generate.