Skip to content

Latest commit

 

History

History
502 lines (429 loc) · 15.4 KB

mojodds.c

File metadata and controls

502 lines (429 loc) · 15.4 KB
 
1
2
3
4
5
6
7
8
9
10
11
/**
* MojoDDS; tools for dealing with DDS files.
*
* Please see the file LICENSE.txt in the source's root directory.
*/
// Specs on DDS format: http://msdn.microsoft.com/en-us/library/bb943991.aspx/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
May 10, 2011
May 10, 2011
12
#include <assert.h>
13
14
15
16
17
18
19
20
21
22
#ifdef _MSC_VER
typedef unsigned __int8 uint8;
typedef unsigned __int32 uint32;
#else
#include <stdint.h>
typedef uint8_t uint8;
typedef uint32_t uint32;
#endif
Jul 10, 2021
Jul 10, 2021
23
24
25
26
#ifndef UINT32_MAX
#define UINT32_MAX 0xFFFFFFFF
#endif
Apr 29, 2015
Apr 29, 2015
27
28
#include "mojodds.h"
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#define STATICARRAYLEN(x) ( (sizeof ((x))) / (sizeof ((x)[0])) )
#define DDS_MAGIC 0x20534444 // 'DDS ' in littleendian.
#define DDS_HEADERSIZE 124
#define DDS_PIXFMTSIZE 32
#define DDSD_CAPS 0x1
#define DDSD_HEIGHT 0x2
#define DDSD_WIDTH 0x4
#define DDSD_PITCH 0x8
#define DDSD_FMT 0x1000
#define DDSD_MIPMAPCOUNT 0x20000
#define DDSD_LINEARSIZE 0x80000
#define DDSD_DEPTH 0x800000
#define DDSD_REQ (DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_FMT)
May 10, 2011
May 10, 2011
43
#define DDSCAPS_ALPHA 0x2
44
45
46
#define DDSCAPS_COMPLEX 0x8
#define DDSCAPS_MIPMAP 0x400000
#define DDSCAPS_TEXTURE 0x1000
Apr 29, 2015
Apr 29, 2015
47
48
49
50
51
52
53
54
#define DDSCAPS2_CUBEMAP 0x200
#define DDSCAPS2_CUBEMAP_POSITIVEX 0x400
#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x800
#define DDSCAPS2_CUBEMAP_POSITIVEY 0x1000
#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x2000
#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x4000
#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x8000
#define DDSCAPS2_VOLUME 0x200000
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#define DDPF_ALPHAPIXELS 0x1
#define DDPF_ALPHA 0x2
#define DDPF_FOURCC 0x4
#define DDPF_RGB 0x40
#define DDPF_YUV 0x200
#define DDPF_LUMINANCE 0x20000
#define FOURCC_DXT1 0x31545844
#define FOURCC_DXT2 0x32545844
#define FOURCC_DXT3 0x33545844
#define FOURCC_DXT4 0x34545844
#define FOURCC_DXT5 0x35545844
#define FOURCC_DX10 0x30315844
May 10, 2011
May 10, 2011
69
70
71
72
73
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#define GL_BGR 0x80E0
#define GL_BGRA 0x80E1
Apr 28, 2015
Apr 28, 2015
74
#define GL_LUMINANCE_ALPHA 0x190A
May 10, 2011
May 10, 2011
75
Apr 29, 2015
Apr 29, 2015
76
77
#define MAX( a, b ) ((a) > (b) ? (a) : (b))
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
typedef struct
{
uint32 dwSize;
uint32 dwFlags;
uint32 dwFourCC;
uint32 dwRGBBitCount;
uint32 dwRBitMask;
uint32 dwGBitMask;
uint32 dwBBitMask;
uint32 dwABitMask;
} MOJODDS_PixelFormat;
typedef struct
{
uint32 dwSize;
uint32 dwFlags;
uint32 dwHeight;
uint32 dwWidth;
uint32 dwPitchOrLinearSize;
uint32 dwDepth;
uint32 dwMipMapCount;
uint32 dwReserved1[11];
MOJODDS_PixelFormat ddspf;
uint32 dwCaps;
uint32 dwCaps2;
uint32 dwCaps3;
uint32 dwCaps4;
uint32 dwReserved2;
} MOJODDS_Header;
Jul 10, 2021
Jul 10, 2021
109
// https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
Jul 10, 2021
Jul 10, 2021
110
static const uint32 MultiplyDeBruijnBitPosition[32] =
Jul 6, 2021
Jul 6, 2021
111
{
Jul 10, 2021
Jul 10, 2021
112
113
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
Jul 6, 2021
Jul 6, 2021
114
115
116
};
Jul 10, 2021
Jul 10, 2021
117
118
static uint32 uintLog2(uint32 v)
{
Jul 6, 2021
Jul 6, 2021
119
120
121
122
123
124
v |= v >> 1; // first round down to one less than a power of 2
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
Jul 10, 2021
Jul 10, 2021
125
return MultiplyDeBruijnBitPosition[(uint32)(v * 0x07C4ACDDU) >> 27];
Jul 6, 2021
Jul 6, 2021
126
127
128
}
129
130
131
static uint32 readui32(const uint8 **_ptr, size_t *_len)
{
uint32 retval = 0;
Jul 10, 2021
Jul 10, 2021
132
if (*_len < sizeof (retval)) {
Jul 10, 2021
Jul 10, 2021
134
} else {
135
136
137
138
139
const uint8 *ptr = *_ptr;
retval = (((uint32) ptr[0]) << 0) | (((uint32) ptr[1]) << 8) |
(((uint32) ptr[2]) << 16) | (((uint32) ptr[3]) << 24) ;
*_ptr += sizeof (retval);
*_len -= sizeof (retval);
Jul 10, 2021
Jul 10, 2021
140
}
Jul 10, 2021
Jul 10, 2021
142
}
May 10, 2011
May 10, 2011
144
static int parse_dds(MOJODDS_Header *header, const uint8 **ptr, size_t *len,
Apr 29, 2015
Apr 29, 2015
145
146
147
unsigned int *_glfmt, unsigned int *_miplevels,
unsigned int *_cubemapfacelen,
MOJODDS_textureType *_textureType)
May 10, 2011
May 10, 2011
149
150
151
152
153
const uint32 pitchAndLinear = (DDSD_PITCH | DDSD_LINEARSIZE);
uint32 width = 0;
uint32 height = 0;
uint32 calcSize = 0;
uint32 calcSizeFlag = DDSD_LINEARSIZE;
Apr 29, 2015
Apr 29, 2015
154
155
uint32 blockDim = 1;
uint32 blockSize = 0;
Jul 10, 2021
Jul 10, 2021
158
if (readui32(ptr, len) != DDS_MAGIC) { // Files start with magic value...
159
return 0; // not a DDS file.
Jul 10, 2021
Jul 10, 2021
160
} else if (*len < DDS_HEADERSIZE) { // Then comes the DDS header...
Jul 10, 2021
Jul 10, 2021
162
}
163
164
165
166
167
168
169
170
header->dwSize = readui32(ptr, len);
header->dwFlags = readui32(ptr, len);
header->dwHeight = readui32(ptr, len);
header->dwWidth = readui32(ptr, len);
header->dwPitchOrLinearSize = readui32(ptr, len);
header->dwDepth = readui32(ptr, len);
header->dwMipMapCount = readui32(ptr, len);
Jul 10, 2021
Jul 10, 2021
171
for (i = 0; i < STATICARRAYLEN(header->dwReserved1); i++) {
172
header->dwReserved1[i] = readui32(ptr, len);
Jul 10, 2021
Jul 10, 2021
173
}
174
175
176
177
178
179
180
181
182
183
184
185
186
187
header->ddspf.dwSize = readui32(ptr, len);
header->ddspf.dwFlags = readui32(ptr, len);
header->ddspf.dwFourCC = readui32(ptr, len);
header->ddspf.dwRGBBitCount = readui32(ptr, len);
header->ddspf.dwRBitMask = readui32(ptr, len);
header->ddspf.dwGBitMask = readui32(ptr, len);
header->ddspf.dwBBitMask = readui32(ptr, len);
header->ddspf.dwABitMask = readui32(ptr, len);
header->dwCaps = readui32(ptr, len);
header->dwCaps2 = readui32(ptr, len);
header->dwCaps3 = readui32(ptr, len);
header->dwCaps4 = readui32(ptr, len);
header->dwReserved2 = readui32(ptr, len);
May 10, 2011
May 10, 2011
188
189
190
width = header->dwWidth;
height = header->dwHeight;
Jul 10, 2021
Jul 10, 2021
191
if (width == 0 || height == 0) {
Jul 6, 2021
Jul 6, 2021
192
193
194
return 0;
}
Jul 6, 2021
Jul 6, 2021
195
// check for overflow in width * height
Jul 10, 2021
Jul 10, 2021
196
if (height > 0xFFFFFFFFU / width) {
Jul 6, 2021
Jul 6, 2021
197
198
199
return 0;
}
May 10, 2011
May 10, 2011
200
201
header->dwCaps &= ~DDSCAPS_ALPHA; // we'll get this from the pixel format.
Jul 10, 2021
Jul 10, 2021
202
if (header->dwSize != DDS_HEADERSIZE) { // header size must be 124.
Jul 10, 2021
Jul 10, 2021
204
} else if (header->ddspf.dwSize != DDS_PIXFMTSIZE) { // size must be 32.
Jul 10, 2021
Jul 10, 2021
206
} else if ((header->dwFlags & DDSD_REQ) != DDSD_REQ) { // must have these bits.
Jul 10, 2021
Jul 10, 2021
208
} else if ((header->dwCaps & DDSCAPS_TEXTURE) == 0) {
Jul 10, 2021
Jul 10, 2021
210
} else if ((header->dwFlags & pitchAndLinear) == pitchAndLinear) {
May 10, 2011
May 10, 2011
211
return 0; // can't specify both.
Jul 10, 2021
Jul 10, 2021
212
}
May 10, 2011
May 10, 2011
214
215
*_miplevels = (header->dwCaps & DDSCAPS_MIPMAP) ? header->dwMipMapCount : 1;
Jul 6, 2021
Jul 6, 2021
216
unsigned int calculatedMipLevels = uintLog2(MAX(width, height)) + 1;
Jul 10, 2021
Jul 10, 2021
217
if (*_miplevels == 0) { // invalid, calculate it ourselves from size
Jul 6, 2021
Jul 6, 2021
218
*_miplevels = calculatedMipLevels;
Jul 10, 2021
Jul 10, 2021
219
220
} else if (*_miplevels > calculatedMipLevels) { // too many mip levels, several would be 1x1
return 0; // file is corrupted
Jul 6, 2021
Jul 6, 2021
221
}
Jul 6, 2021
Jul 6, 2021
222
Jul 10, 2021
Jul 10, 2021
223
224
if (header->ddspf.dwFlags & DDPF_FOURCC) {
switch (header->ddspf.dwFourCC) {
May 10, 2011
May 10, 2011
226
*_glfmt = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
May 10, 2011
May 10, 2011
227
228
calcSize = ((width ? ((width + 3) / 4) : 1) * 8) *
(height ? ((height + 3) / 4) : 1);
Apr 29, 2015
Apr 29, 2015
229
230
blockDim = 4;
blockSize = 8;
May 10, 2011
May 10, 2011
231
break;
May 10, 2011
May 10, 2011
233
*_glfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
May 10, 2011
May 10, 2011
234
235
calcSize = ((width ? ((width + 3) / 4) : 1) * 16) *
(height ? ((height + 3) / 4) : 1);
Apr 29, 2015
Apr 29, 2015
236
237
blockDim = 4;
blockSize = 16;
May 10, 2011
May 10, 2011
238
break;
May 10, 2011
May 10, 2011
240
*_glfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
May 10, 2011
May 10, 2011
241
242
calcSize = ((width ? ((width + 3) / 4) : 1) * 16) *
(height ? ((height + 3) / 4) : 1);
Apr 29, 2015
Apr 29, 2015
243
244
blockDim = 4;
blockSize = 16;
May 10, 2011
May 10, 2011
245
break;
May 10, 2011
May 10, 2011
246
247
// !!! FIXME: DX10 is an extended header, introduced by DirectX 10.
May 10, 2011
May 10, 2011
248
249
250
251
//case FOURCC_DX10: do_something(); break;
//case FOURCC_DXT2: // premultiplied alpha unsupported.
//case FOURCC_DXT4: // premultiplied alpha unsupported.
252
253
default:
return 0; // unsupported data format.
Jul 10, 2021
Jul 10, 2021
254
}
Jul 10, 2021
Jul 10, 2021
256
} else if (header->ddspf.dwFlags & DDPF_RGB) { // no FourCC...uncompressed data.
May 10, 2011
May 10, 2011
257
258
if ( (header->ddspf.dwRBitMask != 0x00FF0000) ||
(header->ddspf.dwGBitMask != 0x0000FF00) ||
Jul 10, 2021
Jul 10, 2021
259
(header->ddspf.dwBBitMask != 0x000000FF) ) {
May 10, 2011
May 10, 2011
260
return 0; // !!! FIXME: deal with this.
Jul 10, 2021
Jul 10, 2021
261
}
May 10, 2011
May 10, 2011
262
Jul 10, 2021
Jul 10, 2021
263
if (header->ddspf.dwFlags & DDPF_ALPHAPIXELS) {
May 10, 2011
May 10, 2011
264
if ( (header->ddspf.dwRGBBitCount != 32) ||
Jul 10, 2021
Jul 10, 2021
265
(header->ddspf.dwABitMask != 0xFF000000) ) {
May 10, 2011
May 10, 2011
266
return 0; // unsupported.
Jul 10, 2021
Jul 10, 2021
267
}
May 10, 2011
May 10, 2011
268
*_glfmt = GL_BGRA;
Apr 29, 2015
Apr 29, 2015
269
blockSize = 4;
Jul 10, 2021
Jul 10, 2021
270
271
} else {
if (header->ddspf.dwRGBBitCount != 24) {
May 10, 2011
May 10, 2011
272
return 0; // unsupported.
Jul 10, 2021
Jul 10, 2021
273
}
May 10, 2011
May 10, 2011
274
*_glfmt = GL_BGR;
Apr 29, 2015
Apr 29, 2015
275
blockSize = 3;
Jul 10, 2021
Jul 10, 2021
276
}
May 10, 2011
May 10, 2011
277
278
279
calcSizeFlag = DDSD_PITCH;
calcSize = ((width * header->ddspf.dwRGBBitCount) + 7) / 8;
Apr 28, 2015
Apr 28, 2015
280
Jul 10, 2021
Jul 10, 2021
281
282
} else if (header->ddspf.dwFlags & (DDPF_LUMINANCE | DDPF_ALPHA) ) {
*_glfmt = GL_LUMINANCE_ALPHA;
Apr 28, 2015
Apr 28, 2015
283
calcSizeFlag = DDSD_PITCH;
Jul 6, 2021
Jul 6, 2021
284
blockSize = 2;
Apr 28, 2015
Apr 28, 2015
285
286
calcSize = ((width * header->ddspf.dwRGBBitCount) + 7) / 8;
}
May 10, 2011
May 10, 2011
287
288
289
290
//else if (header->ddspf.dwFlags & DDPF_LUMINANCE) // !!! FIXME
//else if (header->ddspf.dwFlags & DDPF_YUV) // !!! FIXME
//else if (header->ddspf.dwFlags & DDPF_ALPHA) // !!! FIXME
Jul 10, 2021
Jul 10, 2021
291
292
else {
May 10, 2011
May 10, 2011
293
return 0; // unsupported data format.
Jul 10, 2021
Jul 10, 2021
294
}
May 10, 2011
May 10, 2011
295
May 10, 2011
May 10, 2011
296
// no pitch or linear size? Calculate it.
Jul 10, 2021
Jul 10, 2021
297
298
if ((header->dwFlags & pitchAndLinear) == 0) {
if (!calcSizeFlag) {
May 10, 2011
May 10, 2011
299
300
assert(0 && "should have caught this up above");
return 0; // uh oh.
Jul 10, 2021
Jul 10, 2021
301
}
May 10, 2011
May 10, 2011
302
303
304
header->dwPitchOrLinearSize = calcSize;
header->dwFlags |= calcSizeFlag;
Jul 10, 2021
Jul 10, 2021
305
}
May 10, 2011
May 10, 2011
306
Apr 29, 2015
Apr 29, 2015
307
*_textureType = MOJODDS_TEXTURE_2D;
Jul 10, 2021
Jul 10, 2021
308
309
310
311
312
313
314
315
316
317
318
319
// figure out texture type.
if ( (header->dwCaps & DDSCAPS_COMPLEX) &&
(header->dwCaps2 & DDSCAPS2_CUBEMAP) &&
(header->dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEX) &&
(header->dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEX) &&
(header->dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEY) &&
(header->dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEY) &&
(header->dwCaps2 & DDSCAPS2_CUBEMAP_POSITIVEZ) &&
(header->dwCaps2 & DDSCAPS2_CUBEMAP_NEGATIVEZ) ) {
*_textureType = MOJODDS_TEXTURE_CUBE;
} else if (header->dwCaps2 & DDSCAPS2_VOLUME) {
*_textureType = MOJODDS_TEXTURE_VOLUME;
Apr 29, 2015
Apr 29, 2015
320
321
322
}
// figure out how much memory makes up a single face mip chain.
Jul 10, 2021
Jul 10, 2021
323
if (*_textureType == MOJODDS_TEXTURE_CUBE) {
Apr 29, 2015
Apr 29, 2015
324
325
uint32 wd = header->dwWidth;
uint32 ht = header->dwHeight;
Jul 10, 2021
Jul 10, 2021
326
327
if (wd != ht) {
return 0; // cube maps must be square
Jul 6, 2021
Jul 6, 2021
328
}
Jul 10, 2021
Jul 10, 2021
329
Apr 29, 2015
Apr 29, 2015
330
*_cubemapfacelen = 0;
Jul 10, 2021
Jul 10, 2021
331
332
333
for (i = 0; i < (int)*_miplevels; i++) {
const uint32 mipLen = MAX((wd + blockDim - 1) / blockDim, 1) * MAX((ht + blockDim - 1) / blockDim, 1) * blockSize;
Jul 6, 2021
Jul 6, 2021
334
335
336
337
338
if (UINT32_MAX - mipLen < *_cubemapfacelen) {
// data size would overflow 32-bit uint, invalid file
return 0;
}
*_cubemapfacelen += mipLen;
Apr 29, 2015
Apr 29, 2015
339
340
341
wd >>= 1;
ht >>= 1;
}
Jul 6, 2021
Jul 6, 2021
342
Jul 10, 2021
Jul 10, 2021
343
if (*len < (*_cubemapfacelen) * 6) { // 6 because cube faces
Jul 6, 2021
Jul 6, 2021
344
345
return 0;
}
Jul 10, 2021
Jul 10, 2021
346
347
} else if (*_textureType == MOJODDS_TEXTURE_2D) {
Jul 6, 2021
Jul 6, 2021
348
349
350
351
// check that file contains enough data like the header says
// TODO: also do this for other texture types
uint32 wd = header->dwWidth;
uint32 ht = header->dwHeight;
Jul 10, 2021
Jul 10, 2021
352
uint32 dataLen = 0;
Jul 10, 2021
Jul 10, 2021
353
354
for (i = 0; i < (int)*_miplevels; i++) {
const uint32 mipLen = MAX((wd + blockDim - 1) / blockDim, 1) * MAX((ht + blockDim - 1) / blockDim, 1) * blockSize;
Jul 6, 2021
Jul 6, 2021
355
356
357
358
359
if (UINT32_MAX - mipLen < dataLen) {
// data size would overflow 32-bit uint, invalid file
return 0;
}
dataLen += mipLen;
Jul 6, 2021
Jul 6, 2021
360
361
362
363
364
365
366
367
wd >>= 1;
ht >>= 1;
}
if (*len < dataLen) {
return 0;
}
}
Apr 29, 2015
Apr 29, 2015
368
Jul 6, 2021
Jul 6, 2021
369
if (header->dwPitchOrLinearSize > *len) {
Jul 10, 2021
Jul 10, 2021
370
return 0; // dwPitchOrLinearSize is incorrect
Jul 6, 2021
Jul 6, 2021
371
372
}
Jul 10, 2021
Jul 10, 2021
373
374
if (calcSize > *len) { // there's not enough data to contain the advertised images
return 0; // trying to read mips would fail
Jul 6, 2021
Jul 6, 2021
375
376
}
Jul 10, 2021
Jul 10, 2021
378
}
379
380
381
// !!! FIXME: improve the crap out of this API later.
May 9, 2011
May 9, 2011
382
383
384
385
386
int MOJODDS_isDDS(const void *_ptr, const unsigned long _len)
{
size_t len = (size_t) _len;
const uint8 *ptr = (const uint8 *) _ptr;
return (readui32(&ptr, &len) == DDS_MAGIC);
Jul 10, 2021
Jul 10, 2021
387
}
May 9, 2011
May 9, 2011
388
May 7, 2011
May 7, 2011
389
int MOJODDS_getTexture(const void *_ptr, const unsigned long _len,
May 10, 2011
May 10, 2011
390
391
const void **_tex, unsigned long *_texlen,
unsigned int *_glfmt, unsigned int *_w,
Apr 29, 2015
Apr 29, 2015
392
393
394
unsigned int *_h, unsigned int *_miplevels,
unsigned int *_cubemapfacelen,
MOJODDS_textureType *_textureType)
395
396
397
398
{
size_t len = (size_t) _len;
const uint8 *ptr = (const uint8 *) _ptr;
MOJODDS_Header header;
Jul 10, 2021
Jul 10, 2021
399
if (!parse_dds(&header, &ptr, &len, _glfmt, _miplevels, _cubemapfacelen, _textureType)) {
Jul 10, 2021
Jul 10, 2021
401
}
402
403
*_tex = (const void *) ptr;
May 8, 2011
May 8, 2011
404
405
*_w = (unsigned int) header.dwWidth;
*_h = (unsigned int) header.dwHeight;
May 10, 2011
May 10, 2011
406
*_texlen = (unsigned long) header.dwPitchOrLinearSize;
Jul 10, 2021
Jul 10, 2021
408
if (header.dwFlags & DDSD_PITCH) {
May 10, 2011
May 10, 2011
409
*_texlen *= header.dwHeight;
Jul 10, 2021
Jul 10, 2021
410
}
Jul 10, 2021
Jul 10, 2021
413
}
Apr 28, 2015
Apr 28, 2015
415
int MOJODDS_getMipMapTexture(unsigned int miplevel, unsigned int glfmt,
Jul 10, 2021
Jul 10, 2021
416
const void *_basetex,
Apr 28, 2015
Apr 28, 2015
417
418
419
420
unsigned int w, unsigned h,
const void **_tex, unsigned long *_texlen,
unsigned int *_texw, unsigned int *_texh)
{
Jul 10, 2021
Jul 10, 2021
421
unsigned int i;
Jul 6, 2021
Jul 6, 2021
422
const char* newtex;
Apr 28, 2015
Apr 28, 2015
423
424
425
unsigned long newtexlen;
unsigned int neww;
unsigned int newh;
Jul 6, 2021
Jul 6, 2021
426
427
uint32 blockDim = 1;
uint32 blockSize = 0;
Jul 6, 2021
Jul 6, 2021
428
Jul 6, 2021
Jul 6, 2021
429
switch (glfmt) {
Jul 10, 2021
Jul 10, 2021
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
blockDim = 4;
blockSize = 8;
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
blockDim = 4;
blockSize = 16;
break;
case GL_BGR:
blockSize = 3;
break;
case GL_BGRA:
blockSize = 4;
break;
case GL_LUMINANCE_ALPHA:
blockSize = 2;
break;
Jul 6, 2021
Jul 6, 2021
452
Jul 10, 2021
Jul 10, 2021
453
454
455
default:
//assert(!"unsupported GL format");
return 0;
Jul 6, 2021
Jul 6, 2021
456
}
Apr 28, 2015
Apr 28, 2015
457
Jul 6, 2021
Jul 6, 2021
458
459
assert(blockSize != 0);
Apr 28, 2015
Apr 28, 2015
460
461
462
newtex = _basetex;
neww = w;
newh = h;
Jul 6, 2021
Jul 6, 2021
463
newtexlen = ((neww + blockDim - 1) / blockDim) * ((newh + blockDim - 1) / blockDim) * blockSize;
Apr 28, 2015
Apr 28, 2015
464
465
// Calculate size of miplevel
Jul 10, 2021
Jul 10, 2021
466
for (i = 0; i < miplevel; i++) {
Apr 28, 2015
Apr 28, 2015
467
468
469
470
471
472
473
// move position to next texture start
newtex += newtexlen;
// calculate texture size
neww >>= 1;
newh >>= 1;
if (neww < 1) neww = 1;
if (newh < 1) newh = 1;
Jul 6, 2021
Jul 6, 2021
474
newtexlen = ((neww + blockDim - 1) / blockDim) * ((newh + blockDim - 1) / blockDim) * blockSize;
Jul 10, 2021
Jul 10, 2021
475
}
Apr 28, 2015
Apr 28, 2015
476
477
478
479
480
481
482
*_tex = newtex;
if (_texlen) {
*_texlen = newtexlen;
}
*_texw = neww;
*_texh = newh;
Jul 10, 2021
Jul 10, 2021
483
Apr 28, 2015
Apr 28, 2015
484
return 1;
Jul 10, 2021
Jul 10, 2021
485
}
Apr 28, 2015
Apr 28, 2015
486
487
Jul 6, 2021
Jul 6, 2021
488
489
int MOJODDS_getCubeFace(MOJODDS_cubeFace cubeFace, unsigned int miplevel,
unsigned int glfmt, const void *_basetex,
Jul 6, 2021
Jul 6, 2021
490
unsigned long _cubemapfacelen, unsigned int w, unsigned h,
Jul 6, 2021
Jul 6, 2021
491
492
493
494
const void **_tex, unsigned long *_texlen,
unsigned int *_texw, unsigned int *_texh)
{
// pick correct face
Jul 10, 2021
Jul 10, 2021
495
const char *faceBaseTex = ((const char *) _basetex) + cubeFace * _cubemapfacelen;
Jul 6, 2021
Jul 6, 2021
496
497
// call MOJODDS_getMipMapTexture to get offset in that face
Jul 6, 2021
Jul 6, 2021
498
return MOJODDS_getMipMapTexture(miplevel, glfmt, faceBaseTex, w, h, _tex, _texlen, _texw, _texh);
Jul 6, 2021
Jul 6, 2021
499
500
}
501
// end of mojodds.c ...