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