Files
glide/swlibs/texus/lib/3df.c

240 lines
7.2 KiB
C

/*
** 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
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "texusint.h"
/*************************************** 3df files ****************************/
/* Read word, msb first */
static FxBool
_txRead16 (FILE *stream, FxU16* data)
{
FxU8 byte[2];
if (fread (byte, 2, 1, stream) != 1) return FXFALSE;
*data = (((FxU16) byte[0]) << 8) | ((FxU16) byte[1]);
return FXTRUE;
}
/* Read long word, msb first */
static FxBool
_txRead32 (FILE *stream, FxU32* data)
{
FxU8 byte[4];
if (fread (byte, 4, 1, stream) != 1) return FXFALSE;
*data = (((FxU32) byte[0]) << 24) |
(((FxU32) byte[1]) << 16) |
(((FxU32) byte[2]) << 8) |
((FxU32) byte[3]);
return FXTRUE;
}
/* Read NCC table */
static FxBool
_txRead3DFNCCTable (FILE* stream, FxI32* ncc_table)
{
FxU32 i;
FxI16 data;
/* read Y */
for (i = 0; i < 16; i ++) {
if (FXFALSE == _txRead16 (stream, (FxU16 *)&data)) return FXFALSE;
ncc_table[i] = (FxU8) data;
}
/* read A */
for (i = 0; i < 4; i++) {
if (!_txRead16 (stream, (FxU16 *)&data)) return FXFALSE;
ncc_table[16 + 3 * i + 0] = (FxI32) data;
if (!_txRead16 (stream, (FxU16 *)&data)) return FXFALSE;
ncc_table[16 + 3 * i + 1] = (FxI32) data;
if (!_txRead16 (stream, (FxU16 *)&data)) return FXFALSE;
ncc_table[16 + 3 * i + 2] = (FxI32) data;
}
/* read B */
for (i = 0; i < 4; i++) {
if (!_txRead16 (stream, (FxU16 *)&data)) return FXFALSE;
ncc_table[28 + 3 * i + 0] = (FxI32) data;
if (!_txRead16 (stream, (FxU16 *)&data)) return FXFALSE;
ncc_table[28 + 3 * i + 1] = (FxI32) data;
if (!_txRead16 (stream, (FxU16 *)&data)) return FXFALSE;
ncc_table[28 + 3 * i + 2] = (FxI32) data;
}
return FXTRUE;
}
static FxBool
_txRead3DFPalTable (FILE* stream, FxI32* pal)
{
FxU32 i;
/* read Y */
for (i = 0; i < 256; i ++) {
if (FXFALSE == _txRead32 (stream, (FxU32 *)&pal[i])) return FXFALSE;
}
return FXTRUE;
}
/* Read 3df header */
FxBool
_txRead3DFHeader(FILE* stream, FxU32 cookie, TxMip *txMip)
{
int c, i;
char version[6];
char color_format[10];
int lod_min, lod_max;
int aspect_width, aspect_height;
int w, h;
/* magic cookie starts with 3df v%6...., of which we've eaten 3d */
// printf("3df file header\n");
if (fscanf (stream, "f v%6s", version) != 1) return FXFALSE;
/*
* skip comments
*/
while (((c = getc (stream)) != EOF) && (c == '#')) {
while (((c = getc (stream)) != EOF) && (c != '\n'));
if (c == EOF) return FXFALSE;
}
if (c == EOF) return FXFALSE;
ungetc (c, stream);
/* color format, lod range, aspect ratio */
if (5 != fscanf (stream, "%10s lod range: %i %i aspect ratio: %i %i",
color_format, &lod_min, &lod_max, &aspect_width, &aspect_height))
return FXFALSE;
// printf("%s %d %d (lods) %d %d (aspect)\n", color_format, lod_min, lod_max, aspect_width, aspect_height);
/* eat final nl */
if (((c = getc (stream)) == EOF) && (c != '\n'))
return FXFALSE;
/* make sure null terminated */
color_format[9] = 0;
/* lookup name */
for (i = 0; i <= GR_TEXFMT_ARGB_8888; i++)
if (strcmp (Format_Name[i], color_format) == 0) break;
if (i > GR_TEXFMT_ARGB_8888) return FXFALSE;
txMip->format = i;
/* Validate lod */
if ((lod_max & (lod_max-1)) || (lod_min & (lod_min-1))) return FXFALSE;
if ((lod_max > 256) || (lod_max < 1)) return FXFALSE;
if ((lod_min > 256) || (lod_min < 1)) return FXFALSE;
if (lod_min > lod_max) return FXFALSE;
/* validate aspect ratio */
w = h = lod_max;
switch ((aspect_width << 4) | (aspect_height)) {
case 0x81: h = h/8; break;
case 0x41: h = h/4; break;
case 0x21: h = h/2; break;
case 0x11: h = h/1; break;
case 0x12: w = w/2; break;
case 0x14: w = w/4; break;
case 0x18: w = w/8; break;
default: return FXFALSE;
}
txMip->width = w;
txMip->height = h;
txMip->size = w * h;
for (txMip->depth=1; lod_max > lod_min; lod_max >>= 1) {
// printf("w = %d, h = %d, lod_max = %d\n", w, h, lod_max);
txMip->depth++;
if (w > 1) w >>= 1;
if (h > 1) h >>= 1;
txMip->size += (w * h);
}
txMip->size *= GR_TEXFMT_SIZE(txMip->format);
// printf("3df file: %dx%dx%d:%d\n", txMip->width, txMip->height, txMip->depth, txMip->size);
return FXTRUE;
}
FxBool
_txRead3DFData( FILE *stream, TxMip *txMip)
{
int i, npixels;
// printf("3df file data\n");
/* First read NCC tables */
if ((txMip->format == GR_TEXFMT_YIQ_422) ||
(txMip->format == GR_TEXFMT_AYIQ_8422)) {
if (!_txRead3DFNCCTable (stream, (FxI32 *)txMip->pal)) {
txError("Bad Ncc table\n");
return FXFALSE;
}
}
if ((txMip->format == GR_TEXFMT_P_8) ||
(txMip->format == GR_TEXFMT_AP_88)) {
if (!_txRead3DFPalTable (stream, (FxI32*)txMip->pal)) {
txError("Bad Palette table\n");
return FXFALSE;
}
}
/* read mipmap image data */
if (txMip->format < GR_TEXFMT_16BIT) {
npixels = txMip->size;
if ((FxU32) npixels != fread (txMip->data[0], 1, npixels, stream)) {
txError("Bad 8 bit data");
return FXFALSE;
}
}
else if (txMip->format < GR_TEXFMT_32BIT) {
FxU16* data = (FxU16 *) txMip->data[0];
npixels = txMip->size >> 1;
for (i = 0; i < npixels; i++, data++)
if (FXFALSE == _txRead16 (stream, data)) {
txError("Bad 16 bit data");
return FXFALSE;
}
}
else {
FxU32* data = (FxU32*) txMip->data[0];
npixels = txMip->size >> 2;
for (i = 0; i < npixels; i ++, data++)
if (FXFALSE == _txRead32 (stream, data)) {
txError("Bad 32 bit data");
return FXFALSE;
}
}
return FXTRUE;
}