]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/texmanip.cpp
more eol-style
[xonotic/netradiant.git] / radiant / texmanip.cpp
index 1e0c62ac833f87ae4dc1a0c924f35704ec3bf6e7..53c3b788f7d045522e58eae0e8cdc856c6ace5e7 100644 (file)
-/*\r
-Copyright (c) 2002 Forest "LordHavoc" Hale\r
-\r
-All rights reserved.\r
-\r
-Redistribution and use in source and binary forms, with or without modification,\r
-are permitted provided that the following conditions are met:\r
-\r
-Redistributions of source code must retain the above copyright notice, this list\r
-of conditions and the following disclaimer.\r
-\r
-Redistributions in binary form must reproduce the above copyright notice, this\r
-list of conditions and the following disclaimer in the documentation and/or\r
-other materials provided with the distribution.\r
-\r
-Neither the name of Forest Hale nor the names of other contributors may be used\r
-to endorse or promote products derived from this software without specific prior\r
-written permission. \r
-\r
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''\r
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
-DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY \r
-DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \r
-*/\r
-\r
-#include "stdafx.h"\r
-#include "str.h"\r
-\r
-static byte *row1 = NULL, *row2 = NULL;\r
-static int rowsize = 0;\r
-\r
-void R_ResampleTextureLerpLine (byte *in, byte *out, int inwidth, int outwidth, int bytesperpixel)\r
-{\r
-  int   j, xi, oldx = 0, f, fstep, endx, lerp;\r
-#define LERPBYTE(i) out[i] = (byte) ((((row2[i] - row1[i]) * lerp) >> 16) + row1[i])\r
-\r
-  fstep = (int) (inwidth * 65536.0f / outwidth);\r
-  endx = (inwidth - 1);\r
-  if (bytesperpixel == 4)\r
-  {\r
-    for (j = 0,f = 0;j < outwidth;j++, f += fstep)\r
-    {\r
-      xi = f >> 16;\r
-      if (xi != oldx)\r
-      {\r
-        in += (xi - oldx) * 4;\r
-        oldx = xi;\r
-      }\r
-\r
-      if (xi < endx)\r
-      {\r
-        lerp = f & 0xFFFF;\r
-        *out++ = (byte) ((((in[4] - in[0]) * lerp) >> 16) + in[0]);\r
-        *out++ = (byte) ((((in[5] - in[1]) * lerp) >> 16) + in[1]);\r
-        *out++ = (byte) ((((in[6] - in[2]) * lerp) >> 16) + in[2]);\r
-        *out++ = (byte) ((((in[7] - in[3]) * lerp) >> 16) + in[3]);\r
-      }\r
-      else // last pixel of the line has no pixel to lerp to\r
-      {\r
-        *out++ = in[0];\r
-        *out++ = in[1];\r
-        *out++ = in[2];\r
-        *out++ = in[3];\r
-      }\r
-    }\r
-  }\r
-  else if (bytesperpixel == 3)\r
-  {\r
-    for (j = 0, f = 0; j < outwidth; j++, f += fstep)\r
-    {\r
-      xi = f >> 16;\r
-      if (xi != oldx)\r
-      {\r
-        in += (xi - oldx) * 3;\r
-        oldx = xi;\r
-      }\r
-\r
-      if (xi < endx)\r
-      {\r
-        lerp = f & 0xFFFF;\r
-        *out++ = (byte) ((((in[3] - in[0]) * lerp) >> 16) + in[0]);\r
-        *out++ = (byte) ((((in[4] - in[1]) * lerp) >> 16) + in[1]);\r
-        *out++ = (byte) ((((in[5] - in[2]) * lerp) >> 16) + in[2]);\r
-      }\r
-      else // last pixel of the line has no pixel to lerp to\r
-      {\r
-        *out++ = in[0];\r
-        *out++ = in[1];\r
-        *out++ = in[2];\r
-      }\r
-    }\r
-  }\r
-  else\r
-    Sys_Printf("R_ResampleTextureLerpLine: unsupported bytesperpixel %i\n", bytesperpixel);\r
-}\r
-\r
-/*\r
-================\r
-R_ResampleTexture\r
-================\r
-*/\r
-void R_ResampleTexture (void *indata, int inwidth, int inheight, void *outdata,  int outwidth, int outheight, int bytesperpixel)\r
-{\r
-  if (rowsize < outwidth * bytesperpixel)\r
-  {\r
-    if (row1)\r
-      free(row1);\r
-    if (row2)\r
-      free(row2);\r
-\r
-    rowsize = outwidth * bytesperpixel;\r
-    row1 = (byte *)malloc(rowsize);\r
-    row2 = (byte *)malloc(rowsize);\r
-  }\r
-\r
-  if (bytesperpixel == 4)\r
-  {\r
-    int                i, j, yi, oldy, f, fstep, lerp, endy = (inheight-1), inwidth4 = inwidth*4, outwidth4 = outwidth*4;\r
-    byte       *inrow, *out;\r
-    out = (byte *)outdata;\r
-    fstep = (int) (inheight * 65536.0f / outheight);\r
-#define LERPBYTE(i) out[i] = (byte) ((((row2[i] - row1[i]) * lerp) >> 16) + row1[i])\r
-\r
-    inrow = (byte *)indata;\r
-    oldy = 0;\r
-    R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);\r
-    R_ResampleTextureLerpLine (inrow + inwidth4, row2, inwidth, outwidth, bytesperpixel);\r
-\r
-    for (i = 0, f = 0;i < outheight;i++,f += fstep)\r
-    {\r
-      yi = f >> 16;\r
-      if (yi < endy)\r
-      {\r
-        lerp = f & 0xFFFF;\r
-        if (yi != oldy)\r
-        {\r
-          inrow = (byte *)indata + inwidth4 * yi;\r
-          if (yi == oldy+1)\r
-            memcpy(row1, row2, outwidth4);\r
-          else\r
-            R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);\r
-\r
-          R_ResampleTextureLerpLine (inrow + inwidth4, row2, inwidth, outwidth, bytesperpixel);\r
-          oldy = yi;\r
-        }\r
-        j = outwidth - 4;\r
-        while(j >= 0)\r
-        {\r
-          LERPBYTE( 0);\r
-          LERPBYTE( 1);\r
-          LERPBYTE( 2);\r
-          LERPBYTE( 3);\r
-          LERPBYTE( 4);\r
-          LERPBYTE( 5);\r
-          LERPBYTE( 6);\r
-          LERPBYTE( 7);\r
-          LERPBYTE( 8);\r
-          LERPBYTE( 9);\r
-          LERPBYTE(10);\r
-          LERPBYTE(11);\r
-          LERPBYTE(12);\r
-          LERPBYTE(13);\r
-          LERPBYTE(14);\r
-          LERPBYTE(15);\r
-          out += 16;\r
-          row1 += 16;\r
-          row2 += 16;\r
-          j -= 4;\r
-        }\r
-        if (j & 2)\r
-        {\r
-          LERPBYTE( 0);\r
-          LERPBYTE( 1);\r
-          LERPBYTE( 2);\r
-          LERPBYTE( 3);\r
-          LERPBYTE( 4);\r
-          LERPBYTE( 5);\r
-          LERPBYTE( 6);\r
-          LERPBYTE( 7);\r
-          out += 8;\r
-          row1 += 8;\r
-          row2 += 8;\r
-        }\r
-        if (j & 1)\r
-        {\r
-          LERPBYTE( 0);\r
-          LERPBYTE( 1);\r
-          LERPBYTE( 2);\r
-          LERPBYTE( 3);\r
-          out += 4;\r
-          row1 += 4;\r
-          row2 += 4;\r
-        }\r
-        row1 -= outwidth4;\r
-        row2 -= outwidth4;\r
-      }\r
-      else\r
-      {\r
-        if (yi != oldy)\r
-        {\r
-          inrow = (byte *)indata + inwidth4*yi;\r
-          if (yi == oldy+1)\r
-            memcpy(row1, row2, outwidth4);\r
-          else\r
-            R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);\r
-\r
-          oldy = yi;\r
-        }\r
-        memcpy(out, row1, outwidth4);\r
-      }\r
-    }\r
-  }\r
-  else if (bytesperpixel == 3)\r
-  {\r
-    int                i, j, yi, oldy, f, fstep, lerp, endy = (inheight-1), inwidth3 = inwidth * 3, outwidth3 = outwidth * 3;\r
-    byte       *inrow, *out;\r
-    out = (byte *)outdata;\r
-    fstep = (int) (inheight*65536.0f/outheight);\r
-#define LERPBYTE(i) out[i] = (byte) ((((row2[i] - row1[i]) * lerp) >> 16) + row1[i])\r
-\r
-    inrow = (byte *)indata;\r
-    oldy = 0;\r
-    R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);\r
-    R_ResampleTextureLerpLine (inrow + inwidth3, row2, inwidth, outwidth, bytesperpixel);\r
-    for (i = 0, f = 0;i < outheight;i++,f += fstep)\r
-    {\r
-      yi = f >> 16;\r
-      if (yi < endy)\r
-      {\r
-        lerp = f & 0xFFFF;\r
-        if (yi != oldy)\r
-        {\r
-          inrow = (byte *)indata + inwidth3*yi;\r
-          if (yi == oldy+1)\r
-            memcpy(row1, row2, outwidth3);\r
-          else\r
-            R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);\r
-\r
-          R_ResampleTextureLerpLine (inrow + inwidth3, row2, inwidth, outwidth, bytesperpixel);\r
-          oldy = yi;\r
-        }\r
-        j = outwidth - 4;\r
-        while(j >= 0)\r
-        {\r
-          LERPBYTE( 0);\r
-          LERPBYTE( 1);\r
-          LERPBYTE( 2);\r
-          LERPBYTE( 3);\r
-          LERPBYTE( 4);\r
-          LERPBYTE( 5);\r
-          LERPBYTE( 6);\r
-          LERPBYTE( 7);\r
-          LERPBYTE( 8);\r
-          LERPBYTE( 9);\r
-          LERPBYTE(10);\r
-          LERPBYTE(11);\r
-          out += 12;\r
-          row1 += 12;\r
-          row2 += 12;\r
-          j -= 4;\r
-        }\r
-        if (j & 2)\r
-        {\r
-          LERPBYTE( 0);\r
-          LERPBYTE( 1);\r
-          LERPBYTE( 2);\r
-          LERPBYTE( 3);\r
-          LERPBYTE( 4);\r
-          LERPBYTE( 5);\r
-          out += 6;\r
-          row1 += 6;\r
-          row2 += 6;\r
-        }\r
-        if (j & 1)\r
-        {\r
-          LERPBYTE( 0);\r
-          LERPBYTE( 1);\r
-          LERPBYTE( 2);\r
-          out += 3;\r
-          row1 += 3;\r
-          row2 += 3;\r
-        }\r
-        row1 -= outwidth3;\r
-        row2 -= outwidth3;\r
-      }\r
-      else\r
-      {\r
-        if (yi != oldy)\r
-        {\r
-          inrow = (byte *)indata + inwidth3*yi;\r
-          if (yi == oldy+1)\r
-            memcpy(row1, row2, outwidth3);\r
-          else\r
-            R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);\r
-\r
-          oldy = yi;\r
-        }\r
-        memcpy(out, row1, outwidth3);\r
-      }\r
-    }\r
-  }\r
-  else\r
-    Sys_Printf("R_ResampleTexture: unsupported bytesperpixel %i\n", bytesperpixel);\r
-}\r
-\r
-// in can be the same as out\r
-void GL_MipReduce(byte *in, byte *out, int width, int height, int destwidth, int destheight)\r
-{\r
-  int x, y, width2, height2, nextrow;\r
-  if (width > destwidth)\r
-  {\r
-    if (height > destheight)\r
-    {\r
-      // reduce both\r
-      width2 = width >> 1;\r
-      height2 = height >> 1;\r
-      nextrow = width << 2;\r
-      for (y = 0;y < height2;y++)\r
-      {\r
-        for (x = 0;x < width2;x++)\r
-        {\r
-          out[0] = (byte) ((in[0] + in[4] + in[nextrow  ] + in[nextrow+4]) >> 2);\r
-          out[1] = (byte) ((in[1] + in[5] + in[nextrow+1] + in[nextrow+5]) >> 2);\r
-          out[2] = (byte) ((in[2] + in[6] + in[nextrow+2] + in[nextrow+6]) >> 2);\r
-          out[3] = (byte) ((in[3] + in[7] + in[nextrow+3] + in[nextrow+7]) >> 2);\r
-          out += 4;\r
-          in += 8;\r
-        }\r
-        in += nextrow; // skip a line\r
-      }\r
-    }\r
-    else\r
-    {\r
-      // reduce width\r
-      width2 = width >> 1;\r
-      for (y = 0;y < height;y++)\r
-      {\r
-        for (x = 0;x < width2;x++)\r
-        {\r
-          out[0] = (byte) ((in[0] + in[4]) >> 1);\r
-          out[1] = (byte) ((in[1] + in[5]) >> 1);\r
-          out[2] = (byte) ((in[2] + in[6]) >> 1);\r
-          out[3] = (byte) ((in[3] + in[7]) >> 1);\r
-          out += 4;\r
-          in += 8;\r
-        }\r
-      }\r
-    }\r
-  }\r
-  else\r
-  {\r
-    if (height > destheight)\r
-    {\r
-      // reduce height\r
-      height2 = height >> 1;\r
-      nextrow = width << 2;\r
-      for (y = 0;y < height2;y++)\r
-      {\r
-        for (x = 0;x < width;x++)\r
-        {\r
-          out[0] = (byte) ((in[0] + in[nextrow  ]) >> 1);\r
-          out[1] = (byte) ((in[1] + in[nextrow+1]) >> 1);\r
-          out[2] = (byte) ((in[2] + in[nextrow+2]) >> 1);\r
-          out[3] = (byte) ((in[3] + in[nextrow+3]) >> 1);\r
-          out += 4;\r
-          in += 4;\r
-        }\r
-        in += nextrow; // skip a line\r
-      }\r
-    }\r
-    else\r
-      Sys_Printf("GL_MipReduce: desired size already achieved\n");\r
-  }\r
-}\r
+/*
+Copyright (c) 2002 Forest "LordHavoc" Hale
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list
+of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
+Neither the name of Forest Hale nor the names of other contributors may be used
+to endorse or promote products derived from this software without specific prior
+written permission. 
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 
+DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+*/
+
+#include "stdafx.h"
+#include "str.h"
+
+static byte *row1 = NULL, *row2 = NULL;
+static int rowsize = 0;
+
+void R_ResampleTextureLerpLine (byte *in, byte *out, int inwidth, int outwidth, int bytesperpixel)
+{
+  int   j, xi, oldx = 0, f, fstep, endx, lerp;
+#define LERPBYTE(i) out[i] = (byte) ((((row2[i] - row1[i]) * lerp) >> 16) + row1[i])
+
+  fstep = (int) (inwidth * 65536.0f / outwidth);
+  endx = (inwidth - 1);
+  if (bytesperpixel == 4)
+  {
+    for (j = 0,f = 0;j < outwidth;j++, f += fstep)
+    {
+      xi = f >> 16;
+      if (xi != oldx)
+      {
+        in += (xi - oldx) * 4;
+        oldx = xi;
+      }
+
+      if (xi < endx)
+      {
+        lerp = f & 0xFFFF;
+        *out++ = (byte) ((((in[4] - in[0]) * lerp) >> 16) + in[0]);
+        *out++ = (byte) ((((in[5] - in[1]) * lerp) >> 16) + in[1]);
+        *out++ = (byte) ((((in[6] - in[2]) * lerp) >> 16) + in[2]);
+        *out++ = (byte) ((((in[7] - in[3]) * lerp) >> 16) + in[3]);
+      }
+      else // last pixel of the line has no pixel to lerp to
+      {
+        *out++ = in[0];
+        *out++ = in[1];
+        *out++ = in[2];
+        *out++ = in[3];
+      }
+    }
+  }
+  else if (bytesperpixel == 3)
+  {
+    for (j = 0, f = 0; j < outwidth; j++, f += fstep)
+    {
+      xi = f >> 16;
+      if (xi != oldx)
+      {
+        in += (xi - oldx) * 3;
+        oldx = xi;
+      }
+
+      if (xi < endx)
+      {
+        lerp = f & 0xFFFF;
+        *out++ = (byte) ((((in[3] - in[0]) * lerp) >> 16) + in[0]);
+        *out++ = (byte) ((((in[4] - in[1]) * lerp) >> 16) + in[1]);
+        *out++ = (byte) ((((in[5] - in[2]) * lerp) >> 16) + in[2]);
+      }
+      else // last pixel of the line has no pixel to lerp to
+      {
+        *out++ = in[0];
+        *out++ = in[1];
+        *out++ = in[2];
+      }
+    }
+  }
+  else
+    Sys_Printf("R_ResampleTextureLerpLine: unsupported bytesperpixel %i\n", bytesperpixel);
+}
+
+/*
+================
+R_ResampleTexture
+================
+*/
+void R_ResampleTexture (void *indata, int inwidth, int inheight, void *outdata,  int outwidth, int outheight, int bytesperpixel)
+{
+  if (rowsize < outwidth * bytesperpixel)
+  {
+    if (row1)
+      free(row1);
+    if (row2)
+      free(row2);
+
+    rowsize = outwidth * bytesperpixel;
+    row1 = (byte *)malloc(rowsize);
+    row2 = (byte *)malloc(rowsize);
+  }
+
+  if (bytesperpixel == 4)
+  {
+    int                i, j, yi, oldy, f, fstep, lerp, endy = (inheight-1), inwidth4 = inwidth*4, outwidth4 = outwidth*4;
+    byte       *inrow, *out;
+    out = (byte *)outdata;
+    fstep = (int) (inheight * 65536.0f / outheight);
+#define LERPBYTE(i) out[i] = (byte) ((((row2[i] - row1[i]) * lerp) >> 16) + row1[i])
+
+    inrow = (byte *)indata;
+    oldy = 0;
+    R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);
+    R_ResampleTextureLerpLine (inrow + inwidth4, row2, inwidth, outwidth, bytesperpixel);
+
+    for (i = 0, f = 0;i < outheight;i++,f += fstep)
+    {
+      yi = f >> 16;
+      if (yi < endy)
+      {
+        lerp = f & 0xFFFF;
+        if (yi != oldy)
+        {
+          inrow = (byte *)indata + inwidth4 * yi;
+          if (yi == oldy+1)
+            memcpy(row1, row2, outwidth4);
+          else
+            R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);
+
+          R_ResampleTextureLerpLine (inrow + inwidth4, row2, inwidth, outwidth, bytesperpixel);
+          oldy = yi;
+        }
+        j = outwidth - 4;
+        while(j >= 0)
+        {
+          LERPBYTE( 0);
+          LERPBYTE( 1);
+          LERPBYTE( 2);
+          LERPBYTE( 3);
+          LERPBYTE( 4);
+          LERPBYTE( 5);
+          LERPBYTE( 6);
+          LERPBYTE( 7);
+          LERPBYTE( 8);
+          LERPBYTE( 9);
+          LERPBYTE(10);
+          LERPBYTE(11);
+          LERPBYTE(12);
+          LERPBYTE(13);
+          LERPBYTE(14);
+          LERPBYTE(15);
+          out += 16;
+          row1 += 16;
+          row2 += 16;
+          j -= 4;
+        }
+        if (j & 2)
+        {
+          LERPBYTE( 0);
+          LERPBYTE( 1);
+          LERPBYTE( 2);
+          LERPBYTE( 3);
+          LERPBYTE( 4);
+          LERPBYTE( 5);
+          LERPBYTE( 6);
+          LERPBYTE( 7);
+          out += 8;
+          row1 += 8;
+          row2 += 8;
+        }
+        if (j & 1)
+        {
+          LERPBYTE( 0);
+          LERPBYTE( 1);
+          LERPBYTE( 2);
+          LERPBYTE( 3);
+          out += 4;
+          row1 += 4;
+          row2 += 4;
+        }
+        row1 -= outwidth4;
+        row2 -= outwidth4;
+      }
+      else
+      {
+        if (yi != oldy)
+        {
+          inrow = (byte *)indata + inwidth4*yi;
+          if (yi == oldy+1)
+            memcpy(row1, row2, outwidth4);
+          else
+            R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);
+
+          oldy = yi;
+        }
+        memcpy(out, row1, outwidth4);
+      }
+    }
+  }
+  else if (bytesperpixel == 3)
+  {
+    int                i, j, yi, oldy, f, fstep, lerp, endy = (inheight-1), inwidth3 = inwidth * 3, outwidth3 = outwidth * 3;
+    byte       *inrow, *out;
+    out = (byte *)outdata;
+    fstep = (int) (inheight*65536.0f/outheight);
+#define LERPBYTE(i) out[i] = (byte) ((((row2[i] - row1[i]) * lerp) >> 16) + row1[i])
+
+    inrow = (byte *)indata;
+    oldy = 0;
+    R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);
+    R_ResampleTextureLerpLine (inrow + inwidth3, row2, inwidth, outwidth, bytesperpixel);
+    for (i = 0, f = 0;i < outheight;i++,f += fstep)
+    {
+      yi = f >> 16;
+      if (yi < endy)
+      {
+        lerp = f & 0xFFFF;
+        if (yi != oldy)
+        {
+          inrow = (byte *)indata + inwidth3*yi;
+          if (yi == oldy+1)
+            memcpy(row1, row2, outwidth3);
+          else
+            R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);
+
+          R_ResampleTextureLerpLine (inrow + inwidth3, row2, inwidth, outwidth, bytesperpixel);
+          oldy = yi;
+        }
+        j = outwidth - 4;
+        while(j >= 0)
+        {
+          LERPBYTE( 0);
+          LERPBYTE( 1);
+          LERPBYTE( 2);
+          LERPBYTE( 3);
+          LERPBYTE( 4);
+          LERPBYTE( 5);
+          LERPBYTE( 6);
+          LERPBYTE( 7);
+          LERPBYTE( 8);
+          LERPBYTE( 9);
+          LERPBYTE(10);
+          LERPBYTE(11);
+          out += 12;
+          row1 += 12;
+          row2 += 12;
+          j -= 4;
+        }
+        if (j & 2)
+        {
+          LERPBYTE( 0);
+          LERPBYTE( 1);
+          LERPBYTE( 2);
+          LERPBYTE( 3);
+          LERPBYTE( 4);
+          LERPBYTE( 5);
+          out += 6;
+          row1 += 6;
+          row2 += 6;
+        }
+        if (j & 1)
+        {
+          LERPBYTE( 0);
+          LERPBYTE( 1);
+          LERPBYTE( 2);
+          out += 3;
+          row1 += 3;
+          row2 += 3;
+        }
+        row1 -= outwidth3;
+        row2 -= outwidth3;
+      }
+      else
+      {
+        if (yi != oldy)
+        {
+          inrow = (byte *)indata + inwidth3*yi;
+          if (yi == oldy+1)
+            memcpy(row1, row2, outwidth3);
+          else
+            R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);
+
+          oldy = yi;
+        }
+        memcpy(out, row1, outwidth3);
+      }
+    }
+  }
+  else
+    Sys_Printf("R_ResampleTexture: unsupported bytesperpixel %i\n", bytesperpixel);
+}
+
+// in can be the same as out
+void GL_MipReduce(byte *in, byte *out, int width, int height, int destwidth, int destheight)
+{
+  int x, y, width2, height2, nextrow;
+  if (width > destwidth)
+  {
+    if (height > destheight)
+    {
+      // reduce both
+      width2 = width >> 1;
+      height2 = height >> 1;
+      nextrow = width << 2;
+      for (y = 0;y < height2;y++)
+      {
+        for (x = 0;x < width2;x++)
+        {
+          out[0] = (byte) ((in[0] + in[4] + in[nextrow  ] + in[nextrow+4]) >> 2);
+          out[1] = (byte) ((in[1] + in[5] + in[nextrow+1] + in[nextrow+5]) >> 2);
+          out[2] = (byte) ((in[2] + in[6] + in[nextrow+2] + in[nextrow+6]) >> 2);
+          out[3] = (byte) ((in[3] + in[7] + in[nextrow+3] + in[nextrow+7]) >> 2);
+          out += 4;
+          in += 8;
+        }
+        in += nextrow; // skip a line
+      }
+    }
+    else
+    {
+      // reduce width
+      width2 = width >> 1;
+      for (y = 0;y < height;y++)
+      {
+        for (x = 0;x < width2;x++)
+        {
+          out[0] = (byte) ((in[0] + in[4]) >> 1);
+          out[1] = (byte) ((in[1] + in[5]) >> 1);
+          out[2] = (byte) ((in[2] + in[6]) >> 1);
+          out[3] = (byte) ((in[3] + in[7]) >> 1);
+          out += 4;
+          in += 8;
+        }
+      }
+    }
+  }
+  else
+  {
+    if (height > destheight)
+    {
+      // reduce height
+      height2 = height >> 1;
+      nextrow = width << 2;
+      for (y = 0;y < height2;y++)
+      {
+        for (x = 0;x < width;x++)
+        {
+          out[0] = (byte) ((in[0] + in[nextrow  ]) >> 1);
+          out[1] = (byte) ((in[1] + in[nextrow+1]) >> 1);
+          out[2] = (byte) ((in[2] + in[nextrow+2]) >> 1);
+          out[3] = (byte) ((in[3] + in[nextrow+3]) >> 1);
+          out += 4;
+          in += 4;
+        }
+        in += nextrow; // skip a line
+      }
+    }
+    else
+      Sys_Printf("GL_MipReduce: desired size already achieved\n");
+  }
+}