File: rgt.c

package info (click to toggle)
glide 2002.04.10ds1-16
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 59,540 kB
  • sloc: ansic: 290,125; asm: 23,305; sh: 8,089; pascal: 3,854; makefile: 1,276; perl: 73
file content (179 lines) | stat: -rw-r--r-- 4,954 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

/*
** 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 $
** $Date: 2000/06/15 00:11:40 $
**
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "texusint.h"

const FxU16 IMAGIC         = 0x01DA;
const FxU16 ITYPE_RLE      = 0x01;
const FxU16 ITYPE_NCC      = 0x02;
const FxU16 ITYPE_BGR      = 0x04;
const FxU16 ITYPE_RGT      = 0x08;
    
typedef struct _rgtHeader{
    FxU16 magic;
    FxU8 typeLo;
    FxU8 typeHi;
    FxU8 dimLo;
    FxU8 dimHi;
    FxU8 sizeXLo;
    FxU8 sizeXHi;
    FxU8 sizeYLo;
    FxU8 sizeYHi;
    FxU8 sizeZLo;
    FxU8 sizeZHigh;
} RgtHeader;



static void swapShorts(unsigned short *array, int length)
{
    unsigned short s;
    while (length--) {
        s = *array;
        *array++ = (s << 8) | (s>>8);
    }
}

static void swapLongs(unsigned int *array, int length)
{
    unsigned int s;
    while (length--) {
        s = *array;
        *array++ = (s << 24) | ((s >> 8)&0xFF00) | 
                        ((s&0xFF00) << 8) | (s>>24);
    }
}

// just swap RGB into BGR (leave MSB undefined)
static void swapRGB(unsigned int *array, int length)
{
    unsigned int s;
    while (length--) {
        s = *array;
        *array++ = (s << 16) | (s & 0xFF00) | (s>>16);
    }
}


FxBool 
_txReadRGTHeader( FILE *stream, FxU32 cookie, TxMip *info)
{
    RgtHeader   *rgtHeader = (RgtHeader *) info->pal;

    rgtHeader->magic = (FxU16) cookie;
    if ( stream == NULL ) {
        txPanic("RGT file: Bad file handle.");
        return FXFALSE;
    }
    
    if ( fread( &(rgtHeader->typeLo), 1, sizeof(RgtHeader)-2, stream ) != 10 ) {
        txPanic("RGT file: Unexpected end of file.");
        return FXFALSE;
    }
    if (rgtHeader->magic == IMAGIC) {
        // Needs byte swapping; don't swap magic cookie.
        swapShorts((FxU16 *) &(rgtHeader->typeLo), 5);
    }


    info->format = GR_TEXFMT_ARGB_8888; 
    info->width = rgtHeader->sizeXHi << 8 | rgtHeader->sizeXLo;
    info->height = rgtHeader->sizeYHi << 8 | rgtHeader->sizeYLo;
    info->depth = 1;
    info->size = info->width * info->height * 4;
    if( txVerbose )
      {
        printf("Magic: %.04x w = %d, h = %d, z = %d, typehi = %d, typelo = %d, swap=%d\n", rgtHeader->magic, 
               info->width, info->height, rgtHeader->sizeZLo, rgtHeader->typeHi, rgtHeader->typeLo, rgtHeader->magic == IMAGIC);
      }
    return FXTRUE;
}

// RGT is RGBA in memory (low byte to high byte), or ABGR in a register

FxBool 
_txReadRGTData( FILE *stream, TxMip *info)
{
    RgtHeader   *rgtHeader = (RgtHeader *) info->pal;
    FxU16 type = (rgtHeader->typeHi);
    FxU16 swap = (rgtHeader->magic == IMAGIC); 
    int   x, y;
    
    if ( stream == NULL ) {
        txPanic("RGT file: Bad file handle.");
        return FXFALSE;
    }
    if (type & ITYPE_NCC) {
        txPanic("RGT file: RGT NCC files not supported.");
        return FXFALSE;
    }
    if (type & ITYPE_RLE) {
        txPanic("RGT file: RGT RLE files not supported.");
        return FXFALSE;
    }
    
    // load rgt, rgt's are bottom up
    for ( y = 0; y < info->height; y++ ) {
        FxU32 *data32;
        int     r, g, b, a;

        data32 = (FxU32 *) info->data[0];
        data32 += info->width * (info->height -1 - y);

        // Read scanline worth of data.
        for (x=0; x < info->width; x++) {
            /* Read b, g, r, a  from disk.*/
            r = getc( stream );
            g = getc( stream );
            b = getc( stream );
            a = getc( stream );

            if ( a == EOF ) {
                txPanic("RGT file: Unexpected End of File.");
                return FXFALSE;
            }
            data32[x] = (a << 24) | (r << 16) | (g << 8) | b;
        }

#if 1
        if (swap) {
            swapRGB((unsigned int *)data32, (int)info->width);
        }
#endif

#if 0
        if (type & ITYPE_BGR) {
            /* Swap just blue & red channels */
            swapRGB(data32, info->width);
        }
#endif
    }
    return FXTRUE;
}