blob: 1c499ef11198f06d98e70c369037a5194208071d (
plain)
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
|
/*
* Created on Nov 18, 2003
*
*/
package jake2.imageio;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* @author cwei
*
*/
public class WAL {
public static final int HEADER_SIZE = 100;
/* struct wal_header
{
char name[32]; // name of the texture
uint32 width; // width (in pixels) of the largest mipmap level
uint32 height; // height (in pixels) of the largest mipmap level
int32 offset[4]; // byte offset of the start of each of the 4 mipmap levels
char next_name[32]; // name of the next texture in the animation
uint32 flags; // ?
uint32 contents; // ?
uint32 value; // ?
};
*/
public static class Header {
// size of byte arrays
static final int NAME_SIZE = 32;
static final int OFFSET_SIZE = 4;
String name;
int width;
int height;
int[] offset; // file offsets for the 4 mipmap images
String nextName;
int flags; // unused
int contents; // unused
int value; // unused
public Header(byte[] headerBytes) {
if (headerBytes == null || headerBytes.length != HEADER_SIZE) {
throw new IllegalArgumentException("invalid quake2 wal header");
}
ByteBuffer b = ByteBuffer.wrap(headerBytes);
// is stored as little endian
b.order(ByteOrder.LITTLE_ENDIAN);
byte[] tmp = new byte[NAME_SIZE];
// fill header
// name
b.get(tmp);
try {
name = new String(tmp, "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
name = new String(tmp);
}
// width
width = b.getInt();
assert(width >= 0) : "unsigned int bug"; // true means ok.
// height
height = b.getInt();
assert(height >= 0) : "unsigned int bug"; // true means ok.
// 4 offsets
offset =
new int[] { b.getInt(), b.getInt(), b.getInt(), b.getInt()};
// nextName
b.get(tmp);
try {
nextName = new String(tmp, "ISO-8859-1");
} catch (UnsupportedEncodingException e1) {
name = new String(tmp);
}
// unused entries
flags = b.getInt();
contents = b.getInt();
value = b.getInt();
// check some attributes
checkHeader();
}
private void checkHeader() {
// start of mipmaps
int mipmap0 = HEADER_SIZE;
int mipmap1 = mipmap0 + getWidth() * getHeight();
int mipmap2 = mipmap1 + getWidth() / 2 * getHeight() / 2;
int mipmap3 = mipmap2 + getWidth() / 4 * getHeight() / 4;
if (offset[0] != mipmap0
|| offset[1] != mipmap1
|| offset[2] != mipmap2
|| offset[3] != mipmap3) {
throw new IllegalArgumentException("invalid quake2 wal header");
}
}
/**
* @return
*/
public int getContents() {
return contents;
}
/**
* @return
*/
public int getFlags() {
return flags;
}
/**
* @return
*/
public int getHeight() {
return height;
}
/**
* @return
*/
public String getName() {
return name;
}
/**
* @return
*/
public String getNextName() {
return nextName;
}
/**
* @return
*/
public int getOffset(int index) {
if (index < 0 || index > 3) {
throw new ArrayIndexOutOfBoundsException("mipmap offset range is 0 to 3");
}
return offset[index];
}
/**
* @return
*/
public int getValue() {
return value;
}
/**
* @return
*/
public int getWidth() {
return width;
}
}
}
|