source: trunk/src/opengl/glide/cvg/texus/resample.c

Last change on this file was 6653, checked in by bird, 24 years ago

Added $Id:$ keyword.

File size: 8.0 KB
Line 
1/* $Id: resample.c,v 1.2 2001-09-05 14:30:46 bird Exp $ */
2
3/*
4** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
5** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
6** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
7** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
8** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
9** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
10** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
11** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
12**
13** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
14** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
15** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
16** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
17** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
18** THE UNITED STATES.
19**
20** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
21**
22** $Revision: 1.2 $
23** $Date: 2001-09-05 14:30:46 $
24*/
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <math.h>
30
31#include "texusint.h"
32
33/*
34 * For resampling in the x direction:
35 * Assume ix input pixels become ox output pixels.
36 * Imagine that ix input pixels are each divided into ox fragments, for a total
37 * of ix * ox fragments.
38 * Imagine also that ox output pixels are each divided into ix fragments, for a
39 * total of ox * ix fragments, same as before.
40 * Initialize an accumulator to 0. Add the first input pixel, multiplied by ox
41 * the number of fragments per input pixel. Keep track of the number of
42 * fragments in the accumulator; when this is >= ix, (the number of fragments
43 * it takes to make an output pixel), multiply the accumulator by
44 */
45
46static void
47_txResampleX(FxU32 *out, const FxU32 *in, int ox, int ix)
48{
49 FxU32 accr, accg, accb, acca, r, g, b, a;
50 int i, accf, o, nf;
51
52 // printf("\n");
53 accf = accr = accg = accb = acca = o = 0;
54
55 for (i=0; i<ix; i++) {
56 a = (in[i] & 0xff000000) >> 24;
57 r = (in[i] & 0x00ff0000) >> 16;
58 g = (in[i] & 0x0000ff00) >> 8;
59 b = (in[i] & 0x000000ff) ;
60
61 // Each input pixel brings ox fragments
62 nf = ox;
63
64 while ((accf + nf) >= ix) {
65 int ef;
66 int oa, or, og, ob;
67
68 // Yes, we have (possibly more than) enough to generate an output
69 // pixel. Of the nf new fragments, use up enough to generate an
70 // output pixel.
71
72 ef = ix - accf; // the excessive # of fragments.
73
74 // printf("New: accf = %3d, nf = %3d, ef = %3d, ix = %3d, ox = %3d\n",
75 // accf, nf, ef, ix, ox);
76
77 acca += a * ef;
78 accr += r * ef;
79 accg += g * ef;
80 accb += b * ef;
81
82 oa = acca / ix;
83 or = accr / ix;
84 og = accg / ix;
85 ob = accb / ix;
86
87 if( (oa < 0) || (oa > 255) ||
88 (or < 0) || (or > 255) ||
89 (og < 0) || (og > 255) ||
90 (ob < 0) || (ob > 255) ) {
91
92 printf(" %d %d %d %d\n" , oa, or, og, ob);
93 txPanic("ARGB: out of range\n");
94 }
95
96 *out++ = (oa << 24) | (or << 16) | (og << 8) | ob;
97 // printf("Output pixel %4d: %.02x %.02x %.02x %.02x\n",
98 // o, oa, or, og, ob);
99 o++;
100 acca = accr = accg = accb = accf = 0;
101 nf -= ef;
102 }
103
104 // If there's any fragments left over, accumulate them.
105 if (nf) {
106 acca += a * nf;
107 accr += r * nf;
108 accg += g * nf;
109 accb += b * nf;
110 accf += nf;
111 // printf("i= %4d, accf = %4d, aa=%.06x, ar=%.06x, ag=%.06x, ab=%.06x\n",
112 // i, accf, acca, accr, accg, accb);
113 }
114 }
115 if (accf != 0) {
116 txPanic("Row resampling: accf != 0!\n");
117 }
118}
119
120static FxU32 AccA[MAX_TEXWIDTH];
121static FxU32 AccR[MAX_TEXWIDTH];
122static FxU32 AccG[MAX_TEXWIDTH];
123static FxU32 AccB[MAX_TEXWIDTH];
124static FxU32 argb[MAX_TEXWIDTH];
125
126static void
127_txImgResample(FxU32 *out, int ox, int oy,
128 const FxU32 *in, int ix, int iy)
129{
130 int r, g, b, a;
131 int i, j, accf, o, nf;
132
133 for (i=0; i<ox; i++) AccA[i] = AccR[i] = AccG[i] = AccB[i] = 0;
134
135 accf = 0;
136 o = 0;
137 for (i=0; i<iy; i++) {
138
139 // Resample a row of input into temporary array.
140 // printf("Resampling input row %4d\n", i);
141 _txResampleX( argb, in, ox, ix);
142 in += ix;
143
144 // This row brings in oy fragments per scanline.
145 nf = oy;
146
147 while ((accf + nf) >= iy) {
148 int ef;
149
150 // Yes, we have (possibly more than) enough to generate an output
151 // pixel. Of the nf new fragments, use up enough to generate an
152 // output pixel.
153
154 ef = iy - accf; // the excessive # of fragments.
155
156 // Accumulate input * ef + acc, and generate a line of output.
157 for (j=0; j<ox; j++) {
158
159 a = (argb[j] & 0xff000000) >> 24;
160 r = (argb[j] & 0x00ff0000) >> 16;
161 g = (argb[j] & 0x0000ff00) >> 8;
162 b = (argb[j] & 0x000000ff) ;
163
164 AccA[j] += a * ef;
165 AccR[j] += r * ef;
166 AccG[j] += g * ef;
167 AccB[j] += b * ef;
168
169 a = AccA[j] / iy;
170 r = AccR[j] / iy;
171 g = AccG[j] / iy;
172 b = AccB[j] / iy;
173
174 if( (a < 0) || (a > 255) ||
175 (r < 0) || (r > 255) ||
176 (g < 0) || (g > 255) ||
177 (b < 0) || (b > 255) ) {
178 printf(" %d %d %d %d\n" , a, r, g, b);
179 txPanic("ARGB: out of range\n");
180 }
181 out[j] = (a << 24) | (r << 16) | (g << 8) | b;
182 AccA[j] = 0;
183 AccR[j] = 0;
184 AccG[j] = 0;
185 AccB[j] = 0;
186
187 }
188 out += ox;
189 accf = 0;
190 nf -= ef;
191 // printf("[%4d] Generating output row %4d\n", i, o);
192 o++;
193 }
194
195 // If there's any fragments left over, accumulate them.
196 if (nf) {
197 for (j=0; j<ox; j++) {
198 a = (argb[j] & 0xff000000) >> 24;
199 r = (argb[j] & 0x00ff0000) >> 16;
200 g = (argb[j] & 0x0000ff00) >> 8;
201 b = (argb[j] & 0x000000ff) ;
202
203 AccA[j] += a * nf;
204 AccR[j] += r * nf;
205 AccG[j] += g * nf;
206 AccB[j] += b * nf;
207 }
208 accf += nf;
209 // printf("i= %4d, accf = %4d\n", i, accf);
210 }
211 }
212 if (accf != 0) {
213 txPanic("Img resampling: accf != 0!\n");
214 }
215 // Ideally, accf must be 0 now.
216 // printf("Finally: accf = %d\n", accf);
217}
218
219void
220txMipResample(TxMip *destMip, TxMip *srcMip)
221{
222 int i, sw, sh, dw, dh;
223
224
225 if ((destMip->width > MAX_TEXWIDTH) || (destMip->height > MAX_TEXWIDTH)) {
226 txPanic("Bad width/height in txImageResize()\n");
227 }
228 if ((srcMip->format != GR_TEXFMT_ARGB_8888) ||
229 (destMip->format != GR_TEXFMT_ARGB_8888)) {
230 txPanic("Bad image format in txMipResample.");
231 }
232
233 if ((srcMip->width == destMip->width) && (srcMip->height == destMip->height) &&
234 (srcMip->data[0] == destMip->data[0])) {
235 if( txVerbose )
236 printf("No Resampling necessary.\n");
237 return;
238 }
239
240 if ((srcMip->data[0] == NULL) || (destMip->data[0] == NULL))
241 txPanic("txImageResize: Null buffer\n");
242
243 if( txVerbose )
244 printf("Resampling to %dx%d: ", destMip->width, destMip->height);
245
246
247 sw = srcMip->width;
248 sh = srcMip->height;
249 dw = destMip->width;
250 dh = destMip->height;
251
252 for (i=0; i< srcMip->depth; i++) {
253 if(!destMip->data[i])
254 txPanic("txImageResize: no miplevel present\n");
255 _txImgResample (destMip->data[i], dw, dh,
256 srcMip->data[i], sw, sh);
257 if( txVerbose )
258 {
259 printf(" %dx%d", sw, sh); fflush(stdout);
260 }
261 if (sw > 1) sw >>= 1;
262 if (sh > 1) sh >>= 1;
263 if (dw > 1) dw >>= 1;
264 if (dh > 1) dh >>= 1;
265 }
266 if( txVerbose )
267 printf(".\n");
268}
Note: See TracBrowser for help on using the repository browser.