2 Copyright (c) 2002 Forest "LordHavoc" Hale
6 Redistribution and use in source and binary forms, with or without modification,
7 are permitted provided that the following conditions are met:
9 Redistributions of source code must retain the above copyright notice, this list
10 of conditions and the following disclaimer.
12 Redistributions in binary form must reproduce the above copyright notice, this
13 list of conditions and the following disclaimer in the documentation and/or
14 other materials provided with the distribution.
16 Neither the name of Forest Hale nor the names of other contributors may be used
17 to endorse or promote products derived from this software without specific prior
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
24 DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 static byte *row1 = NULL, *row2 = NULL;
36 static int rowsize = 0;
38 void R_ResampleTextureLerpLine (byte *in, byte *out, int inwidth, int outwidth, int bytesperpixel)
40 int j, xi, oldx = 0, f, fstep, endx, lerp;
41 #define LERPBYTE(i) out[i] = (byte) ((((row2[i] - row1[i]) * lerp) >> 16) + row1[i])
43 fstep = (int) (inwidth * 65536.0f / outwidth);
45 if (bytesperpixel == 4)
47 for (j = 0,f = 0;j < outwidth;j++, f += fstep)
52 in += (xi - oldx) * 4;
59 *out++ = (byte) ((((in[4] - in[0]) * lerp) >> 16) + in[0]);
60 *out++ = (byte) ((((in[5] - in[1]) * lerp) >> 16) + in[1]);
61 *out++ = (byte) ((((in[6] - in[2]) * lerp) >> 16) + in[2]);
62 *out++ = (byte) ((((in[7] - in[3]) * lerp) >> 16) + in[3]);
64 else // last pixel of the line has no pixel to lerp to
73 else if (bytesperpixel == 3)
75 for (j = 0, f = 0; j < outwidth; j++, f += fstep)
80 in += (xi - oldx) * 3;
87 *out++ = (byte) ((((in[3] - in[0]) * lerp) >> 16) + in[0]);
88 *out++ = (byte) ((((in[4] - in[1]) * lerp) >> 16) + in[1]);
89 *out++ = (byte) ((((in[5] - in[2]) * lerp) >> 16) + in[2]);
91 else // last pixel of the line has no pixel to lerp to
100 Sys_Printf("R_ResampleTextureLerpLine: unsupported bytesperpixel %i\n", bytesperpixel);
108 void R_ResampleTexture (void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight, int bytesperpixel)
110 if (rowsize < outwidth * bytesperpixel)
117 rowsize = outwidth * bytesperpixel;
118 row1 = (byte *)malloc(rowsize);
119 row2 = (byte *)malloc(rowsize);
122 if (bytesperpixel == 4)
124 int i, j, yi, oldy, f, fstep, lerp, endy = (inheight-1), inwidth4 = inwidth*4, outwidth4 = outwidth*4;
126 out = (byte *)outdata;
127 fstep = (int) (inheight * 65536.0f / outheight);
128 #define LERPBYTE(i) out[i] = (byte) ((((row2[i] - row1[i]) * lerp) >> 16) + row1[i])
130 inrow = (byte *)indata;
132 R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);
133 R_ResampleTextureLerpLine (inrow + inwidth4, row2, inwidth, outwidth, bytesperpixel);
135 for (i = 0, f = 0;i < outheight;i++,f += fstep)
143 inrow = (byte *)indata + inwidth4 * yi;
145 memcpy(row1, row2, outwidth4);
147 R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);
149 R_ResampleTextureLerpLine (inrow + inwidth4, row2, inwidth, outwidth, bytesperpixel);
207 inrow = (byte *)indata + inwidth4*yi;
209 memcpy(row1, row2, outwidth4);
211 R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);
215 memcpy(out, row1, outwidth4);
219 else if (bytesperpixel == 3)
221 int i, j, yi, oldy, f, fstep, lerp, endy = (inheight-1), inwidth3 = inwidth * 3, outwidth3 = outwidth * 3;
223 out = (byte *)outdata;
224 fstep = (int) (inheight*65536.0f/outheight);
225 #define LERPBYTE(i) out[i] = (byte) ((((row2[i] - row1[i]) * lerp) >> 16) + row1[i])
227 inrow = (byte *)indata;
229 R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);
230 R_ResampleTextureLerpLine (inrow + inwidth3, row2, inwidth, outwidth, bytesperpixel);
231 for (i = 0, f = 0;i < outheight;i++,f += fstep)
239 inrow = (byte *)indata + inwidth3*yi;
241 memcpy(row1, row2, outwidth3);
243 R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);
245 R_ResampleTextureLerpLine (inrow + inwidth3, row2, inwidth, outwidth, bytesperpixel);
296 inrow = (byte *)indata + inwidth3*yi;
298 memcpy(row1, row2, outwidth3);
300 R_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth, bytesperpixel);
304 memcpy(out, row1, outwidth3);
309 Sys_Printf("R_ResampleTexture: unsupported bytesperpixel %i\n", bytesperpixel);
312 // in can be the same as out
313 void GL_MipReduce(byte *in, byte *out, int width, int height, int destwidth, int destheight)
315 int x, y, width2, height2, nextrow;
316 if (width > destwidth)
318 if (height > destheight)
322 height2 = height >> 1;
323 nextrow = width << 2;
324 for (y = 0;y < height2;y++)
326 for (x = 0;x < width2;x++)
328 out[0] = (byte) ((in[0] + in[4] + in[nextrow ] + in[nextrow+4]) >> 2);
329 out[1] = (byte) ((in[1] + in[5] + in[nextrow+1] + in[nextrow+5]) >> 2);
330 out[2] = (byte) ((in[2] + in[6] + in[nextrow+2] + in[nextrow+6]) >> 2);
331 out[3] = (byte) ((in[3] + in[7] + in[nextrow+3] + in[nextrow+7]) >> 2);
335 in += nextrow; // skip a line
342 for (y = 0;y < height;y++)
344 for (x = 0;x < width2;x++)
346 out[0] = (byte) ((in[0] + in[4]) >> 1);
347 out[1] = (byte) ((in[1] + in[5]) >> 1);
348 out[2] = (byte) ((in[2] + in[6]) >> 1);
349 out[3] = (byte) ((in[3] + in[7]) >> 1);
358 if (height > destheight)
361 height2 = height >> 1;
362 nextrow = width << 2;
363 for (y = 0;y < height2;y++)
365 for (x = 0;x < width;x++)
367 out[0] = (byte) ((in[0] + in[nextrow ]) >> 1);
368 out[1] = (byte) ((in[1] + in[nextrow+1]) >> 1);
369 out[2] = (byte) ((in[2] + in[nextrow+2]) >> 1);
370 out[3] = (byte) ((in[3] + in[nextrow+3]) >> 1);
374 in += nextrow; // skip a line
378 Sys_Printf("GL_MipReduce: desired size already achieved\n");