/* ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com). ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A ** FULL TEXT OF THE NON-WARRANTY PROVISIONS. ** ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013, ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF ** THE UNITED STATES. ** ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED ** ** $Revision: 1.2.2.1 $ ** $Date: 2000/09/11 08:48:08 $ */ #include #include #include #include #include "texusint.h" int txVerbose = 0; char *Format_Name[] = { "rgb332", // GR_TEXFMT_RGB_332 "yiq", // GR_TEXFMT_YIQ_422 "a8", // GR_TEXFMT_ALPHA_8 "i8", // GR_TEXFMT_INTENSITY_8 "ai44", // GR_TEXFMT_ALPHA_INTENSITY_44 "p8", // GR_TEXFMT_P_8 "rsvd1", // GR_TEXFMT_RSVD1 "rsvd2", // GR_TEXFMT_RSVD2 "argb8332", // GR_TEXFMT_ARGB_8332 "ayiq8422", // GR_TEXFMT_AYIQ_8422 "rgb565", // GR_TEXFMT_RGB_565 "argb1555", // GR_TEXFMT_ARGB_1555 "argb4444", // GR_TEXFMT_ARGB_4444 "ai88", // GR_TEXFMT_ALPHA_INTENSITY_88 "ap88", // GR_TEXFMT_AP_88 "rsvd4", // GR_TEXFMT_RSVD4 "argb8888", // GR_TEXFMT_ARGB_8888 }; int txLog2(int n) { switch (n) { case 1: return 0; case 2: return 1; case 4: return 2; case 8: return 3; case 16: return 4; case 32: return 5; case 64: return 6; case 128: return 7; case 256: return 8; } txPanic("Bad arg to Log2\n"); return 0; // to keep compiler quiet. } int txFloorPow2(int n) { // Find next smallest integer which is also a power of 2. int i; if ((n & (n -1)) == 0) { return n; // already a power of 2. } for (i=1; i<= n; i+=i); return i>>1; } int txCeilPow2(int n) { // Find next smallest integer which is also a power of 2. int i; if ((n & (n -1)) == 0) return n; // already a power of 2. for (i=1; i<= n; i+=i); return i; } extern TxErrorCallbackFnc_t _txErrorCallback; void txPanic(char *message) { _txErrorCallback( message, FXTRUE ); } void txError(char *message) { _txErrorCallback( message, FXFALSE ); } int txGCD(int a, int b) { // Greatest common divisor, used in resampling. if (b > a) { int t; t = a; a = b; b = t;} // a>b here. while (b > 0) { int t; t = a % b; a = b; b = t; } return a; } void txYABtoPal256(int *palette, const int* yabTable) { // Convert YAB table to a 256 color palette // Assume yabTable[] has first 16Y's, 12 A's, 12 B's const int *Y = yabTable; const int *A = yabTable + 16; const int *B = yabTable + 16 + 12; int i; for (i=0; i<256; i++) { int iy, ia, ib, r, g, b; iy = (i >> 4) & 0xF; ia = (i >> 2) & 0x3; ib = (i >> 0) & 0x3; r = Y[iy] + A[3*ia + 0] + B[3*ib + 0]; g = Y[iy] + A[3*ia + 1] + B[3*ib + 1]; b = Y[iy] + A[3*ia + 2] + B[3*ib + 2]; if (r < 0) r = 0; if (r > 255) r = 255; if (g < 0) g = 0; if (g > 255) g = 255; if (b < 0) b = 0; if (b > 255) b = 255; palette[i] = (r << 16) | (g << 8) | b; } } /* * The following table was generated from this piece of code: main() { int i; printf("static int _explode3[256+256+4] = {\n"); for (i=-255; i<256; i++) { int k; int bits; k = (i < 0) ? -i : i; bits = 0; if (k & 0x01) bits += 0x00000001 << 0; if (k & 0x02) bits += 0x00000001 << 3; if (k & 0x04) bits += 0x00000001 << 6; if (k & 0x08) bits += 0x00000001 << 9; if (k & 0x10) bits += 0x00000001 << 12; if (k & 0x20) bits += 0x00000001 << 15; if (k & 0x40) bits += 0x00000001 << 18; if (k & 0x80) bits += 0x00000001 << 21; // explode3[i] = bits; printf("0x%.06x,", bits); if (((i + 255) % 8) == 7) printf("\n"); } printf("\n};\n"); printf("static int *explode3 = &_explode3[255];\n"); } */ int _explode3[255+256] = { 0x249249,0x249248,0x249241,0x249240,0x249209,0x249208,0x249201,0x249200, 0x249049,0x249048,0x249041,0x249040,0x249009,0x249008,0x249001,0x249000, 0x248249,0x248248,0x248241,0x248240,0x248209,0x248208,0x248201,0x248200, 0x248049,0x248048,0x248041,0x248040,0x248009,0x248008,0x248001,0x248000, 0x241249,0x241248,0x241241,0x241240,0x241209,0x241208,0x241201,0x241200, 0x241049,0x241048,0x241041,0x241040,0x241009,0x241008,0x241001,0x241000, 0x240249,0x240248,0x240241,0x240240,0x240209,0x240208,0x240201,0x240200, 0x240049,0x240048,0x240041,0x240040,0x240009,0x240008,0x240001,0x240000, 0x209249,0x209248,0x209241,0x209240,0x209209,0x209208,0x209201,0x209200, 0x209049,0x209048,0x209041,0x209040,0x209009,0x209008,0x209001,0x209000, 0x208249,0x208248,0x208241,0x208240,0x208209,0x208208,0x208201,0x208200, 0x208049,0x208048,0x208041,0x208040,0x208009,0x208008,0x208001,0x208000, 0x201249,0x201248,0x201241,0x201240,0x201209,0x201208,0x201201,0x201200, 0x201049,0x201048,0x201041,0x201040,0x201009,0x201008,0x201001,0x201000, 0x200249,0x200248,0x200241,0x200240,0x200209,0x200208,0x200201,0x200200, 0x200049,0x200048,0x200041,0x200040,0x200009,0x200008,0x200001,0x200000, 0x049249,0x049248,0x049241,0x049240,0x049209,0x049208,0x049201,0x049200, 0x049049,0x049048,0x049041,0x049040,0x049009,0x049008,0x049001,0x049000, 0x048249,0x048248,0x048241,0x048240,0x048209,0x048208,0x048201,0x048200, 0x048049,0x048048,0x048041,0x048040,0x048009,0x048008,0x048001,0x048000, 0x041249,0x041248,0x041241,0x041240,0x041209,0x041208,0x041201,0x041200, 0x041049,0x041048,0x041041,0x041040,0x041009,0x041008,0x041001,0x041000, 0x040249,0x040248,0x040241,0x040240,0x040209,0x040208,0x040201,0x040200, 0x040049,0x040048,0x040041,0x040040,0x040009,0x040008,0x040001,0x040000, 0x009249,0x009248,0x009241,0x009240,0x009209,0x009208,0x009201,0x009200, 0x009049,0x009048,0x009041,0x009040,0x009009,0x009008,0x009001,0x009000, 0x008249,0x008248,0x008241,0x008240,0x008209,0x008208,0x008201,0x008200, 0x008049,0x008048,0x008041,0x008040,0x008009,0x008008,0x008001,0x008000, 0x001249,0x001248,0x001241,0x001240,0x001209,0x001208,0x001201,0x001200, 0x001049,0x001048,0x001041,0x001040,0x001009,0x001008,0x001001,0x001000, 0x000249,0x000248,0x000241,0x000240,0x000209,0x000208,0x000201,0x000200, 0x000049,0x000048,0x000041,0x000040,0x000009,0x000008,0x000001,0x000000, 0x000001,0x000008,0x000009,0x000040,0x000041,0x000048,0x000049,0x000200, 0x000201,0x000208,0x000209,0x000240,0x000241,0x000248,0x000249,0x001000, 0x001001,0x001008,0x001009,0x001040,0x001041,0x001048,0x001049,0x001200, 0x001201,0x001208,0x001209,0x001240,0x001241,0x001248,0x001249,0x008000, 0x008001,0x008008,0x008009,0x008040,0x008041,0x008048,0x008049,0x008200, 0x008201,0x008208,0x008209,0x008240,0x008241,0x008248,0x008249,0x009000, 0x009001,0x009008,0x009009,0x009040,0x009041,0x009048,0x009049,0x009200, 0x009201,0x009208,0x009209,0x009240,0x009241,0x009248,0x009249,0x040000, 0x040001,0x040008,0x040009,0x040040,0x040041,0x040048,0x040049,0x040200, 0x040201,0x040208,0x040209,0x040240,0x040241,0x040248,0x040249,0x041000, 0x041001,0x041008,0x041009,0x041040,0x041041,0x041048,0x041049,0x041200, 0x041201,0x041208,0x041209,0x041240,0x041241,0x041248,0x041249,0x048000, 0x048001,0x048008,0x048009,0x048040,0x048041,0x048048,0x048049,0x048200, 0x048201,0x048208,0x048209,0x048240,0x048241,0x048248,0x048249,0x049000, 0x049001,0x049008,0x049009,0x049040,0x049041,0x049048,0x049049,0x049200, 0x049201,0x049208,0x049209,0x049240,0x049241,0x049248,0x049249,0x200000, 0x200001,0x200008,0x200009,0x200040,0x200041,0x200048,0x200049,0x200200, 0x200201,0x200208,0x200209,0x200240,0x200241,0x200248,0x200249,0x201000, 0x201001,0x201008,0x201009,0x201040,0x201041,0x201048,0x201049,0x201200, 0x201201,0x201208,0x201209,0x201240,0x201241,0x201248,0x201249,0x208000, 0x208001,0x208008,0x208009,0x208040,0x208041,0x208048,0x208049,0x208200, 0x208201,0x208208,0x208209,0x208240,0x208241,0x208248,0x208249,0x209000, 0x209001,0x209008,0x209009,0x209040,0x209041,0x209048,0x209049,0x209200, 0x209201,0x209208,0x209209,0x209240,0x209241,0x209248,0x209249,0x240000, 0x240001,0x240008,0x240009,0x240040,0x240041,0x240048,0x240049,0x240200, 0x240201,0x240208,0x240209,0x240240,0x240241,0x240248,0x240249,0x241000, 0x241001,0x241008,0x241009,0x241040,0x241041,0x241048,0x241049,0x241200, 0x241201,0x241208,0x241209,0x241240,0x241241,0x241248,0x241249,0x248000, 0x248001,0x248008,0x248009,0x248040,0x248041,0x248048,0x248049,0x248200, 0x248201,0x248208,0x248209,0x248240,0x248241,0x248248,0x248249,0x249000, 0x249001,0x249008,0x249009,0x249040,0x249041,0x249048,0x249049,0x249200, 0x249201,0x249208,0x249209,0x249240,0x249241,0x249248,0x249249, }; int *explode3 = &_explode3[255]; int txNearestColor(int ir, int ig, int ib, const FxU32 *pal, int ncolors) { int i, d; int mindist, minpos; // closest distance to input if (&explode3[-255] != &_explode3[0]) txPanic("Bad explode\n"); mindist = DISTANCE((*pal>>16)&0xff, (*pal>>8)&0xff, (*pal)&0xff, ir, ig, ib); minpos = 0; pal ++; /* Find closest color */ for (i=1; i>16)&0xff, (*pal>>8)&0xff, (*pal)&0xff, ir, ig, ib); if (d < mindist) { mindist = d; minpos = i; } } return minpos; // best fit color is returned. } #ifdef GLIDE3 int txAspectRatio(int w, int h) { int ar; ar = (w >= h) ? (((w/h) << 4) | 1) : ((1 << 4) | (h/w)); switch (ar) { case 0x81: return 6; case 0x41: return 5; case 0x21: return 4; case 0x11: return 3; case 0x12: return 2; case 0x14: return 1; case 0x18: return 0; } return 0; } #else int txAspectRatio(int w, int h) { int ar; ar = (w >= h) ? (((w/h) << 4) | 1) : ((1 << 4) | (h/w)); switch (ar) { case 0x81: return 0; case 0x41: return 1; case 0x21: return 2; case 0x11: return 3; case 0x12: return 4; case 0x14: return 5; case 0x18: return 6; } return 0; } #endif /* GLIDE3 */ void txRectCopy(FxU8 *dst, int dstStride, const FxU8 *src, int srcStride, int width, int height) { // Copy a rectangular region from src to dst, each with different strides. while (height--) { int i; for (i=0; iwidth; h = txMip->height; memsize = 0; for (i=0; idepth; i++) { memsize += (w * h); if (w > 1) w >>= 1; if (h > 1) h >>= 1; } return memsize * GR_TEXFMT_SIZE(txMip->format); } FxBool txMipAlloc(TxMip *txMip) { int i, w, h; FxU8 *data; txMip->size = txMemRequired(txMip); data = (FxU8 *) txMalloc(txMip->size); if (data == NULL) return FXFALSE; w = txMip->width; h = txMip->height; for (i=0; i= txMip->depth) { txMip->data[i] = NULL; continue; } txMip->data[i] = data; data += (w * h * GR_TEXFMT_SIZE(txMip->format)); if (w > 1) w >>= 1; if (h > 1) h >>= 1; } return FXTRUE; } FxBool txMipSetMipPointers(TxMip *txMip) { int i, w, h; FxU8 *data = txMip->data[0]; txMip->size = txMemRequired(txMip); w = txMip->width; h = txMip->height; for (i=0; i= txMip->depth) { txMip->data[i] = NULL; continue; } txMip->data[i] = data; data += (w * h * GR_TEXFMT_SIZE(txMip->format)); if (w > 1) w >>= 1; if (h > 1) h >>= 1; } return FXTRUE; } void txBasename(const char *name, char* basename) { /* Strip the pathname and leave us with filename.ext */ char *s; const char *p, *slash; /* Find the last slash */ for (p = slash = name; *p; p++) { if ((*p == '/') || (*p == '\\')) slash = p + 1; } /* Copy everything after the last slash to output */ strcpy(basename, slash); // Walk to end of string */ for (s = basename; *s; s++); // Walk backwards; replace any . with 0 while (--s >= basename) { if (*s == '.') {*s = 0; break;} } } void txPathAndBasename(const char *name, char* basename) { /* Strip the extension and leave us with path,basename */ char *s; strcpy(basename, name); /* Walk to the end of the string */ for (s = basename; *s; s++); /* Walk backwards; stop when you hit a slash; replace any . with 0. */ while (--s >= basename) { if ((*s == '/') || (*s == '\\')) break; if (*s == '.') {*s = 0; break;} } } void txExtension(const char *name, char *extname) { const char *p, *ext; ext = NULL; for (p = name; *p; p++) { if (*p == '.') ext = p; } if (ext) while (*ext) *extname++ = *ext++; *extname = 0; } void txMipFree( TxMip *mip ) { int i; txFree( mip->data[0] ); for( i = 0; i < TX_MAX_LEVEL; i++ ) mip->data[i] = NULL; } void *txMalloc( size_t size ) { return malloc( size ); } void txFree( void *ptr ) { free( ptr ); } void *txRealloc( void *ptr, size_t size ) { return realloc( ptr, size ); }