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

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

Added $Id:$ keyword.

File size: 15.8 KB
Line 
1/* $Id: util.c,v 1.2 2001-09-05 14:30:47 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:47 $
24*/
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <math.h>
30
31#include "texusint.h"
32
33int txVerbose = 0;
34
35char *Format_Name[] = {
36 "rgb332", // GR_TEXFMT_RGB_332
37 "yiq", // GR_TEXFMT_YIQ_422
38 "a8", // GR_TEXFMT_ALPHA_8
39 "i8", // GR_TEXFMT_INTENSITY_8
40 "ai44", // GR_TEXFMT_ALPHA_INTENSITY_44
41 "p8", // GR_TEXFMT_P_8
42 "rsvd1", // GR_TEXFMT_RSVD1
43 "rsvd2", // GR_TEXFMT_RSVD2
44 "argb8332", // GR_TEXFMT_ARGB_8332
45 "ayiq8422", // GR_TEXFMT_AYIQ_8422
46 "rgb565", // GR_TEXFMT_RGB_565
47 "argb1555", // GR_TEXFMT_ARGB_1555
48 "argb4444", // GR_TEXFMT_ARGB_4444
49 "ai88", // GR_TEXFMT_ALPHA_INTENSITY_88
50 "ap88", // GR_TEXFMT_AP_88
51 "rsvd4", // GR_TEXFMT_RSVD4
52 "argb8888", // GR_TEXFMT_ARGB_8888
53};
54
55
56int
57txLog2(int n)
58{
59 switch (n) {
60 case 1: return 0;
61 case 2: return 1;
62 case 4: return 2;
63 case 8: return 3;
64 case 16: return 4;
65 case 32: return 5;
66 case 64: return 6;
67 case 128: return 7;
68 case 256: return 8;
69 }
70
71 txPanic("Bad arg to Log2\n");
72 return 0; // to keep compiler quiet.
73}
74
75int
76txFloorPow2(int n)
77{
78 // Find next smallest integer which is also a power of 2.
79
80 int i;
81
82 if ((n & (n -1)) == 0) {
83 return n; // already a power of 2.
84 }
85
86 for (i=1; i<= n; i+=i);
87 return i>>1;
88}
89
90int
91txCeilPow2(int n)
92{
93 // Find next smallest integer which is also a power of 2.
94
95 int i;
96
97 if ((n & (n -1)) == 0) return n; // already a power of 2.
98
99 for (i=1; i<= n; i+=i);
100 return i;
101}
102
103extern TxErrorCallbackFnc_t _txErrorCallback;
104
105void
106txPanic(char *message)
107{
108 _txErrorCallback( message, FXTRUE );
109}
110
111void
112txError(char *message)
113{
114 _txErrorCallback( message, FXFALSE );
115}
116
117int
118txGCD(int a, int b)
119{
120 // Greatest common divisor, used in resampling.
121
122 if (b > a) { int t; t = a; a = b; b = t;}
123
124 // a>b here.
125
126 while (b > 0) {
127 int t;
128
129 t = a % b;
130 a = b;
131 b = t;
132 }
133 return a;
134}
135
136void
137txYABtoPal256(long *palette, const long* yabTable)
138{
139 // Convert YAB table to a 256 color palette
140 // Assume yabTable[] has first 16Y's, 12 A's, 12 B's
141
142 const long *Y = yabTable;
143 const long *A = yabTable + 16;
144 const long *B = yabTable + 16 + 12;
145 int i;
146
147 for (i=0; i<256; i++) {
148 int iy, ia, ib, r, g, b;
149
150 iy = (i >> 4) & 0xF;
151 ia = (i >> 2) & 0x3;
152 ib = (i >> 0) & 0x3;
153
154 r = Y[iy] + A[3*ia + 0] + B[3*ib + 0];
155 g = Y[iy] + A[3*ia + 1] + B[3*ib + 1];
156 b = Y[iy] + A[3*ia + 2] + B[3*ib + 2];
157
158 if (r < 0) r = 0; if (r > 255) r = 255;
159 if (g < 0) g = 0; if (g > 255) g = 255;
160 if (b < 0) b = 0; if (b > 255) b = 255;
161
162 palette[i] = (r << 16) | (g << 8) | b;
163 }
164}
165
166/*
167 * The following table was generated from this piece of code:
168
169main()
170{
171 int i;
172
173 printf("static int _explode3[256+256+4] = {\n");
174
175 for (i=-255; i<256; i++) {
176 int k;
177 int bits;
178
179 k = (i < 0) ? -i : i;
180 bits = 0;
181
182 if (k & 0x01) bits += 0x00000001 << 0;
183 if (k & 0x02) bits += 0x00000001 << 3;
184 if (k & 0x04) bits += 0x00000001 << 6;
185 if (k & 0x08) bits += 0x00000001 << 9;
186 if (k & 0x10) bits += 0x00000001 << 12;
187 if (k & 0x20) bits += 0x00000001 << 15;
188 if (k & 0x40) bits += 0x00000001 << 18;
189 if (k & 0x80) bits += 0x00000001 << 21;
190
191 // explode3[i] = bits;
192 printf("0x%.06x,", bits);
193 if (((i + 255) % 8) == 7) printf("\n");
194 }
195 printf("\n};\n");
196 printf("static int *explode3 = &_explode3[255];\n");
197}
198 */
199
200int _explode3[255+256] = {
2010x249249,0x249248,0x249241,0x249240,0x249209,0x249208,0x249201,0x249200,
2020x249049,0x249048,0x249041,0x249040,0x249009,0x249008,0x249001,0x249000,
2030x248249,0x248248,0x248241,0x248240,0x248209,0x248208,0x248201,0x248200,
2040x248049,0x248048,0x248041,0x248040,0x248009,0x248008,0x248001,0x248000,
2050x241249,0x241248,0x241241,0x241240,0x241209,0x241208,0x241201,0x241200,
2060x241049,0x241048,0x241041,0x241040,0x241009,0x241008,0x241001,0x241000,
2070x240249,0x240248,0x240241,0x240240,0x240209,0x240208,0x240201,0x240200,
2080x240049,0x240048,0x240041,0x240040,0x240009,0x240008,0x240001,0x240000,
2090x209249,0x209248,0x209241,0x209240,0x209209,0x209208,0x209201,0x209200,
2100x209049,0x209048,0x209041,0x209040,0x209009,0x209008,0x209001,0x209000,
2110x208249,0x208248,0x208241,0x208240,0x208209,0x208208,0x208201,0x208200,
2120x208049,0x208048,0x208041,0x208040,0x208009,0x208008,0x208001,0x208000,
2130x201249,0x201248,0x201241,0x201240,0x201209,0x201208,0x201201,0x201200,
2140x201049,0x201048,0x201041,0x201040,0x201009,0x201008,0x201001,0x201000,
2150x200249,0x200248,0x200241,0x200240,0x200209,0x200208,0x200201,0x200200,
2160x200049,0x200048,0x200041,0x200040,0x200009,0x200008,0x200001,0x200000,
2170x049249,0x049248,0x049241,0x049240,0x049209,0x049208,0x049201,0x049200,
2180x049049,0x049048,0x049041,0x049040,0x049009,0x049008,0x049001,0x049000,
2190x048249,0x048248,0x048241,0x048240,0x048209,0x048208,0x048201,0x048200,
2200x048049,0x048048,0x048041,0x048040,0x048009,0x048008,0x048001,0x048000,
2210x041249,0x041248,0x041241,0x041240,0x041209,0x041208,0x041201,0x041200,
2220x041049,0x041048,0x041041,0x041040,0x041009,0x041008,0x041001,0x041000,
2230x040249,0x040248,0x040241,0x040240,0x040209,0x040208,0x040201,0x040200,
2240x040049,0x040048,0x040041,0x040040,0x040009,0x040008,0x040001,0x040000,
2250x009249,0x009248,0x009241,0x009240,0x009209,0x009208,0x009201,0x009200,
2260x009049,0x009048,0x009041,0x009040,0x009009,0x009008,0x009001,0x009000,
2270x008249,0x008248,0x008241,0x008240,0x008209,0x008208,0x008201,0x008200,
2280x008049,0x008048,0x008041,0x008040,0x008009,0x008008,0x008001,0x008000,
2290x001249,0x001248,0x001241,0x001240,0x001209,0x001208,0x001201,0x001200,
2300x001049,0x001048,0x001041,0x001040,0x001009,0x001008,0x001001,0x001000,
2310x000249,0x000248,0x000241,0x000240,0x000209,0x000208,0x000201,0x000200,
2320x000049,0x000048,0x000041,0x000040,0x000009,0x000008,0x000001,0x000000,
2330x000001,0x000008,0x000009,0x000040,0x000041,0x000048,0x000049,0x000200,
2340x000201,0x000208,0x000209,0x000240,0x000241,0x000248,0x000249,0x001000,
2350x001001,0x001008,0x001009,0x001040,0x001041,0x001048,0x001049,0x001200,
2360x001201,0x001208,0x001209,0x001240,0x001241,0x001248,0x001249,0x008000,
2370x008001,0x008008,0x008009,0x008040,0x008041,0x008048,0x008049,0x008200,
2380x008201,0x008208,0x008209,0x008240,0x008241,0x008248,0x008249,0x009000,
2390x009001,0x009008,0x009009,0x009040,0x009041,0x009048,0x009049,0x009200,
2400x009201,0x009208,0x009209,0x009240,0x009241,0x009248,0x009249,0x040000,
2410x040001,0x040008,0x040009,0x040040,0x040041,0x040048,0x040049,0x040200,
2420x040201,0x040208,0x040209,0x040240,0x040241,0x040248,0x040249,0x041000,
2430x041001,0x041008,0x041009,0x041040,0x041041,0x041048,0x041049,0x041200,
2440x041201,0x041208,0x041209,0x041240,0x041241,0x041248,0x041249,0x048000,
2450x048001,0x048008,0x048009,0x048040,0x048041,0x048048,0x048049,0x048200,
2460x048201,0x048208,0x048209,0x048240,0x048241,0x048248,0x048249,0x049000,
2470x049001,0x049008,0x049009,0x049040,0x049041,0x049048,0x049049,0x049200,
2480x049201,0x049208,0x049209,0x049240,0x049241,0x049248,0x049249,0x200000,
2490x200001,0x200008,0x200009,0x200040,0x200041,0x200048,0x200049,0x200200,
2500x200201,0x200208,0x200209,0x200240,0x200241,0x200248,0x200249,0x201000,
2510x201001,0x201008,0x201009,0x201040,0x201041,0x201048,0x201049,0x201200,
2520x201201,0x201208,0x201209,0x201240,0x201241,0x201248,0x201249,0x208000,
2530x208001,0x208008,0x208009,0x208040,0x208041,0x208048,0x208049,0x208200,
2540x208201,0x208208,0x208209,0x208240,0x208241,0x208248,0x208249,0x209000,
2550x209001,0x209008,0x209009,0x209040,0x209041,0x209048,0x209049,0x209200,
2560x209201,0x209208,0x209209,0x209240,0x209241,0x209248,0x209249,0x240000,
2570x240001,0x240008,0x240009,0x240040,0x240041,0x240048,0x240049,0x240200,
2580x240201,0x240208,0x240209,0x240240,0x240241,0x240248,0x240249,0x241000,
2590x241001,0x241008,0x241009,0x241040,0x241041,0x241048,0x241049,0x241200,
2600x241201,0x241208,0x241209,0x241240,0x241241,0x241248,0x241249,0x248000,
2610x248001,0x248008,0x248009,0x248040,0x248041,0x248048,0x248049,0x248200,
2620x248201,0x248208,0x248209,0x248240,0x248241,0x248248,0x248249,0x249000,
2630x249001,0x249008,0x249009,0x249040,0x249041,0x249048,0x249049,0x249200,
2640x249201,0x249208,0x249209,0x249240,0x249241,0x249248,0x249249,
265};
266int *explode3 = &_explode3[255];
267
268int
269txNearestColor(long ir, long ig, long ib, const FxU32 *pal, int ncolors)
270{
271 int i, d;
272 int mindist, minpos; // closest distance to input
273
274 if (&explode3[-255] != &_explode3[0])
275 txPanic("Bad explode\n");
276
277 mindist = DISTANCE((*pal>>16)&0xff, (*pal>>8)&0xff, (*pal)&0xff,
278 ir, ig, ib);
279 minpos = 0;
280 pal ++;
281
282 /* Find closest color */
283 for (i=1; i<ncolors; i++, pal ++) {
284 d = DISTANCE((*pal>>16)&0xff, (*pal>>8)&0xff, (*pal)&0xff,
285 ir, ig, ib);
286 if (d < mindist) { mindist = d; minpos = i; }
287 }
288 return minpos; // best fit color is returned.
289}
290
291#ifdef GLIDE3
292int
293txAspectRatio(int w, int h)
294{
295 int ar;
296
297 ar = (w >= h) ? (((w/h) << 4) | 1) : ((1 << 4) | (h/w));
298 switch (ar) {
299 case 0x81: return 6;
300 case 0x41: return 5;
301 case 0x21: return 4;
302 case 0x11: return 3;
303 case 0x12: return 2;
304 case 0x14: return 1;
305 case 0x18: return 0;
306 }
307 return 0;
308}
309#else
310int
311txAspectRatio(int w, int h)
312{
313 int ar;
314
315 ar = (w >= h) ? (((w/h) << 4) | 1) : ((1 << 4) | (h/w));
316 switch (ar) {
317 case 0x81: return 0;
318 case 0x41: return 1;
319 case 0x21: return 2;
320 case 0x11: return 3;
321 case 0x12: return 4;
322 case 0x14: return 5;
323 case 0x18: return 6;
324 }
325 return 0;
326}
327#endif /* GLIDE3 */
328
329void
330txRectCopy(FxU8 *dst, int dstStride, const FxU8 *src, int srcStride,
331 int width, int height)
332{
333 // Copy a rectangular region from src to dst, each with different strides.
334
335 while (height--) {
336 int i;
337 for (i=0; i<width; i++) {
338 dst[i] = src[i];
339 }
340 dst += dstStride;
341 src += srcStride;
342 }
343}
344
345int
346txMemRequired(TxMip *txMip)
347{
348 /* Tell me how much memory is need to hold this mipmap */
349 int w, h, memsize, i;
350
351 w = txMip->width;
352 h = txMip->height;
353 memsize = 0;
354
355 for (i=0; i<txMip->depth; i++) {
356 memsize += (w * h);
357 if (w > 1) w >>= 1;
358 if (h > 1) h >>= 1;
359 }
360 return memsize * GR_TEXFMT_SIZE(txMip->format);
361}
362
363FxBool
364txMipAlloc(TxMip *txMip)
365{
366 int i, w, h;
367 FxU8 *data;
368
369 txMip->size = txMemRequired(txMip);
370
371 data = (FxU8 *) txMalloc(txMip->size);
372 if (data == NULL) return FXFALSE;
373 w = txMip->width;
374 h = txMip->height;
375
376 for (i=0; i<TX_MAX_LEVEL; i++) {
377 if (i >= txMip->depth) {
378 txMip->data[i] = NULL;
379 continue;
380 }
381 txMip->data[i] = data;
382 data += (w * h * GR_TEXFMT_SIZE(txMip->format));
383 if (w > 1) w >>= 1;
384 if (h > 1) h >>= 1;
385 }
386 return FXTRUE;
387}
388
389FxBool
390txMipSetMipPointers(TxMip *txMip)
391{
392 int i, w, h;
393 FxU8 *data = txMip->data[0];
394
395 txMip->size = txMemRequired(txMip);
396
397 w = txMip->width;
398 h = txMip->height;
399
400 for (i=0; i<TX_MAX_LEVEL; i++) {
401 if (i >= txMip->depth) {
402 txMip->data[i] = NULL;
403 continue;
404 }
405 txMip->data[i] = data;
406 data += (w * h * GR_TEXFMT_SIZE(txMip->format));
407 if (w > 1) w >>= 1;
408 if (h > 1) h >>= 1;
409 }
410 return FXTRUE;
411}
412
413void
414txBasename(const char *name, char* basename)
415{
416 /* Strip the pathname and leave us with filename.ext */
417 char *s;
418 const char *p, *slash;
419
420 /* Find the last slash */
421 for (p = slash = name; *p; p++) {
422 if ((*p == '/') || (*p == '\\')) slash = p + 1;
423 }
424
425 /* Copy everything after the last slash to output */
426 strcpy(basename, slash);
427
428 // Walk to end of string */
429 for (s = basename; *s; s++);
430
431 // Walk backwards; replace any . with 0
432 while (--s >= basename) {
433 if (*s == '.') {*s = 0; break;}
434 }
435}
436
437void
438txPathAndBasename(const char *name, char* basename)
439{
440 /* Strip the extension and leave us with path,basename */
441 char *s;
442
443 strcpy(basename, name);
444
445 /* Walk to the end of the string */
446 for (s = basename; *s; s++);
447
448 /* Walk backwards; stop when you hit a slash; replace any . with 0. */
449 while (--s >= basename) {
450 if ((*s == '/') || (*s == '\\')) break;
451 if (*s == '.') {*s = 0; break;}
452
453 }
454}
455
456void
457txExtension(const char *name, char *extname)
458{
459 const char *p, *ext;
460
461 ext = NULL;
462 for (p = name; *p; p++) {
463 if (*p == '.') ext = p;
464 }
465
466 if (ext)
467 while (*ext) *extname++ = *ext++;
468
469 *extname = 0;
470}
471
472void
473txMipFree( TxMip *mip )
474{
475 int i;
476
477 txFree( mip->data[0] );
478 for( i = 0; i < TX_MAX_LEVEL; i++ )
479 mip->data[i] = NULL;
480}
481
482void *txMalloc( size_t size )
483{
484 return malloc( size );
485}
486
487void txFree( void *ptr )
488{
489 free( ptr );
490}
491
492void *txRealloc( void *ptr, size_t size )
493{
494 return realloc( ptr, size );
495}
496
Note: See TracBrowser for help on using the repository browser.