+static void SCR_ScaleDown(unsigned char *in, int inw, int inh, unsigned char *out, int outw, int outh)
+{
+ // TODO optimize this function
+
+ int x, y;
+ float area;
+
+ // memcpy is faster than me
+ if(inw == outw && inh == outh)
+ {
+ memcpy(out, in, 3 * inw * inh);
+ return;
+ }
+
+ // otherwise: a box filter
+ area = (float)outw * (float)outh / (float)inw / (float)inh;
+ for(y = 0; y < outh; ++y)
+ {
+ float iny0 = y / (float)outh * inh; int iny0_i = floor(iny0);
+ float iny1 = (y+1) / (float)outh * inh; int iny1_i = ceil(iny1);
+ for(x = 0; x < outw; ++x)
+ {
+ float inx0 = x / (float)outw * inw; int inx0_i = floor(inx0);
+ float inx1 = (x+1) / (float)outw * inw; int inx1_i = ceil(inx1);
+ float r = 0, g = 0, b = 0;
+ int xx, yy;
+
+ for(yy = iny0_i; yy < iny1_i; ++yy)
+ {
+ float ya = min(yy+1, iny1) - max(iny0, yy);
+ for(xx = inx0_i; xx < inx1_i; ++xx)
+ {
+ float a = ya * (min(xx+1, inx1) - max(inx0, xx));
+ r += a * in[3*(xx + inw * yy)+0];
+ g += a * in[3*(xx + inw * yy)+1];
+ b += a * in[3*(xx + inw * yy)+2];
+ }
+ }
+
+ out[3*(x + outw * y)+0] = r * area;
+ out[3*(x + outw * y)+1] = g * area;
+ out[3*(x + outw * y)+2] = b * area;
+ }
+ }
+}
+