7 #define AVERAGE(a, b) ( ((((a) ^ (b)) & 0xfefefefeL) >> 1) + ((a) & (b)) )
9 static void scale_line(RrPixel32 *dest, RrPixel32 *source, gint w, gint dw)
12 gint int_part = w / dw;
13 gint fract_part = w % dw;
16 while (num_pixels-- > 0) {
27 static RrPixel32* scale_half(RrPixel32 *source, gint w, gint h)
29 RrPixel32 *out, *dest, *sourceline, *sourceline2;
33 sourceline2 = source + w;
38 out = dest = g_new(RrPixel32, dw * dh);
40 for (y = 0; y < dh; ++y) {
46 for (x = 0; x < dw; ++x) {
47 *dest++ = AVERAGE(AVERAGE(*s, *(s+1)),
48 AVERAGE(*s2, *(s2+1)));
53 sourceline2 += w << 1;
58 static RrPixel32* scale_rect(RrPixel32 *fullsource,
59 gint w, gint h, gint dw, gint dh)
61 RrPixel32 *out, *dest;
62 RrPixel32 *source = fullsource;
63 RrPixel32 *oldsource = NULL;
64 RrPixel32 *prev_source = NULL;
70 while (dw <= (w >> 1) && dh <= (h >> 1)) {
71 source = scale_half(source, w, h);
78 int_part = (h / dh) * w;
81 out = dest = g_new(RrPixel32, dw * dh);
83 while (num_pixels-- > 0) {
84 if (source == prev_source) {
85 memcpy(dest, dest - dw, dw * sizeof(RrPixel32));
87 scale_line(dest, source, w, dw);
104 void RrImageDraw(RrPixel32 *target, RrTextureRGBA *rgba,
105 gint target_w, gint target_h,
111 gint col, num_pixels;
118 dh = (int)(dw * ((double)sh / sw));
119 if (dh > area->height) {
121 dw = (int)(dh * ((double)sw / sh));
124 if (sw != dw || sh != dh) {
125 /*if (!(rgba->cache && dw == rgba->cwidth && dh == rgba->cheight))*/ {
127 rgba->cache = scale_rect(rgba->data, sw, sh, dw, dh);
131 source = rgba->cache;
136 /* copy source -> dest, and apply the alpha channel */
138 num_pixels = dw * dh;
139 dest = target + area->x + target_w * area->y;
140 while (num_pixels-- > 0) {
141 guchar alpha, r, g, b, bgr, bgg, bgb;
143 alpha = *source >> RrDefaultAlphaOffset;
144 r = *source >> RrDefaultRedOffset;
145 g = *source >> RrDefaultGreenOffset;
146 b = *source >> RrDefaultBlueOffset;
148 /* background color */
149 bgr = *dest >> RrDefaultRedOffset;
150 bgg = *dest >> RrDefaultGreenOffset;
151 bgb = *dest >> RrDefaultBlueOffset;
153 r = bgr + (((r - bgr) * alpha) >> 8);
154 g = bgg + (((g - bgg) * alpha) >> 8);
155 b = bgb + (((b - bgb) * alpha) >> 8);
157 *dest = ((r << RrDefaultRedOffset) |
158 (g << RrDefaultGreenOffset) |
159 (b << RrDefaultBlueOffset));
166 dest += target_w - dw;