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 ){
39 int j, xi, oldx = 0, f, fstep, endx, lerp;
40 #define LERPBYTE( i ) out[i] = (byte) ( ( ( ( row2[i] - row1[i] ) * lerp ) >> 16 ) + row1[i] )
42 fstep = (int) ( inwidth * 65536.0f / outwidth );
43 endx = ( inwidth - 1 );
44 if ( bytesperpixel == 4 ) {
45 for ( j = 0,f = 0; j < outwidth; j++, f += fstep )
49 in += ( xi - oldx ) * 4;
55 *out++ = (byte) ( ( ( ( in[4] - in[0] ) * lerp ) >> 16 ) + in[0] );
56 *out++ = (byte) ( ( ( ( in[5] - in[1] ) * lerp ) >> 16 ) + in[1] );
57 *out++ = (byte) ( ( ( ( in[6] - in[2] ) * lerp ) >> 16 ) + in[2] );
58 *out++ = (byte) ( ( ( ( in[7] - in[3] ) * lerp ) >> 16 ) + in[3] );
60 else // last pixel of the line has no pixel to lerp to
69 else if ( bytesperpixel == 3 ) {
70 for ( j = 0, f = 0; j < outwidth; j++, f += fstep )
74 in += ( xi - oldx ) * 3;
80 *out++ = (byte) ( ( ( ( in[3] - in[0] ) * lerp ) >> 16 ) + in[0] );
81 *out++ = (byte) ( ( ( ( in[4] - in[1] ) * lerp ) >> 16 ) + in[1] );
82 *out++ = (byte) ( ( ( ( in[5] - in[2] ) * lerp ) >> 16 ) + in[2] );
84 else // last pixel of the line has no pixel to lerp to
93 Sys_Printf( "R_ResampleTextureLerpLine: unsupported bytesperpixel %i\n", bytesperpixel );
102 void R_ResampleTexture( void *indata, int inwidth, int inheight, void *outdata, int outwidth, int outheight, int bytesperpixel ){
103 if ( rowsize < outwidth * bytesperpixel ) {
111 rowsize = outwidth * bytesperpixel;
112 row1 = (byte *)malloc( rowsize );
113 row2 = (byte *)malloc( rowsize );
116 if ( bytesperpixel == 4 ) {
117 int i, j, yi, oldy, f, fstep, lerp, endy = ( inheight - 1 ), inwidth4 = inwidth * 4, outwidth4 = outwidth * 4;
119 out = (byte *)outdata;
120 fstep = (int) ( inheight * 65536.0f / outheight );
121 #define LERPBYTE( i ) out[i] = (byte) ( ( ( ( row2[i] - row1[i] ) * lerp ) >> 16 ) + row1[i] )
123 inrow = (byte *)indata;
125 R_ResampleTextureLerpLine( inrow, row1, inwidth, outwidth, bytesperpixel );
126 R_ResampleTextureLerpLine( inrow + inwidth4, row2, inwidth, outwidth, bytesperpixel );
128 for ( i = 0, f = 0; i < outheight; i++,f += fstep )
134 inrow = (byte *)indata + inwidth4 * yi;
135 if ( yi == oldy + 1 ) {
136 memcpy( row1, row2, outwidth4 );
139 R_ResampleTextureLerpLine( inrow, row1, inwidth, outwidth, bytesperpixel );
142 R_ResampleTextureLerpLine( inrow + inwidth4, row2, inwidth, outwidth, bytesperpixel );
197 inrow = (byte *)indata + inwidth4 * yi;
198 if ( yi == oldy + 1 ) {
199 memcpy( row1, row2, outwidth4 );
202 R_ResampleTextureLerpLine( inrow, row1, inwidth, outwidth, bytesperpixel );
207 memcpy( out, row1, outwidth4 );
211 else if ( bytesperpixel == 3 ) {
212 int i, j, yi, oldy, f, fstep, lerp, endy = ( inheight - 1 ), inwidth3 = inwidth * 3, outwidth3 = outwidth * 3;
214 out = (byte *)outdata;
215 fstep = (int) ( inheight * 65536.0f / outheight );
216 #define LERPBYTE( i ) out[i] = (byte) ( ( ( ( row2[i] - row1[i] ) * lerp ) >> 16 ) + row1[i] )
218 inrow = (byte *)indata;
220 R_ResampleTextureLerpLine( inrow, row1, inwidth, outwidth, bytesperpixel );
221 R_ResampleTextureLerpLine( inrow + inwidth3, row2, inwidth, outwidth, bytesperpixel );
222 for ( i = 0, f = 0; i < outheight; i++,f += fstep )
228 inrow = (byte *)indata + inwidth3 * yi;
229 if ( yi == oldy + 1 ) {
230 memcpy( row1, row2, outwidth3 );
233 R_ResampleTextureLerpLine( inrow, row1, inwidth, outwidth, bytesperpixel );
236 R_ResampleTextureLerpLine( inrow + inwidth3, row2, inwidth, outwidth, bytesperpixel );
284 inrow = (byte *)indata + inwidth3 * yi;
285 if ( yi == oldy + 1 ) {
286 memcpy( row1, row2, outwidth3 );
289 R_ResampleTextureLerpLine( inrow, row1, inwidth, outwidth, bytesperpixel );
294 memcpy( out, row1, outwidth3 );
299 Sys_Printf( "R_ResampleTexture: unsupported bytesperpixel %i\n", bytesperpixel );
303 // in can be the same as out
304 void GL_MipReduce( byte *in, byte *out, int width, int height, int destwidth, int destheight ){
305 int x, y, width2, height2, nextrow;
306 if ( width > destwidth ) {
307 if ( height > destheight ) {
310 height2 = height >> 1;
311 nextrow = width << 2;
312 for ( y = 0; y < height2; y++ )
314 for ( x = 0; x < width2; x++ )
316 out[0] = (byte) ( ( in[0] + in[4] + in[nextrow ] + in[nextrow + 4] ) >> 2 );
317 out[1] = (byte) ( ( in[1] + in[5] + in[nextrow + 1] + in[nextrow + 5] ) >> 2 );
318 out[2] = (byte) ( ( in[2] + in[6] + in[nextrow + 2] + in[nextrow + 6] ) >> 2 );
319 out[3] = (byte) ( ( in[3] + in[7] + in[nextrow + 3] + in[nextrow + 7] ) >> 2 );
323 in += nextrow; // skip a line
330 for ( y = 0; y < height; y++ )
332 for ( x = 0; x < width2; x++ )
334 out[0] = (byte) ( ( in[0] + in[4] ) >> 1 );
335 out[1] = (byte) ( ( in[1] + in[5] ) >> 1 );
336 out[2] = (byte) ( ( in[2] + in[6] ) >> 1 );
337 out[3] = (byte) ( ( in[3] + in[7] ) >> 1 );
346 if ( height > destheight ) {
348 height2 = height >> 1;
349 nextrow = width << 2;
350 for ( y = 0; y < height2; y++ )
352 for ( x = 0; x < width; x++ )
354 out[0] = (byte) ( ( in[0] + in[nextrow ] ) >> 1 );
355 out[1] = (byte) ( ( in[1] + in[nextrow + 1] ) >> 1 );
356 out[2] = (byte) ( ( in[2] + in[nextrow + 2] ) >> 1 );
357 out[3] = (byte) ( ( in[3] + in[nextrow + 3] ) >> 1 );
361 in += nextrow; // skip a line
365 Sys_Printf( "GL_MipReduce: desired size already achieved\n" );