-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathformat0022.c
More file actions
130 lines (111 loc) · 3.67 KB
/
Copy pathformat0022.c
File metadata and controls
130 lines (111 loc) · 3.67 KB
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
// Converts 0022 files to tga
//
// (C) 2017 Jannik Vogel
//
// Licensed under GPLv2 or later.
// See LICENSE.txt for more information.
//FIXME: Somehow store used-size + mipmaps
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "txc_dxtn.h"
#include "tga.h"
#include "surface.h"
int main(int argc, char* argv[]) {
FILE* in = fopen(argv[1], "rb");
FILE* out = fopen(argv[2], "wb");
SurfaceHeader header;
fread(&header, sizeof(header), 1, in);
printSurfaceHeader(&header);
TgaHeader tgaHeader;
setupTgaHeader(&tgaHeader, UncompressedRGB, header.width_a, header.height_a);
fwrite(&tgaHeader, sizeof(tgaHeader), 1, out);
size_t bufferSize = header.stride * header.height_a;
uint8_t* buffer = malloc(bufferSize);
fread(buffer, bufferSize, 1, in);
for(unsigned int y = 0; y < header.height_a; y++) {
for(unsigned int x = 0; x < header.width_a; x++) {
switch(header.format) {
case 0x0001:
fwrite(&buffer[y * header.stride + x * 4], 4, 1, out);
break;
case 0x0006: {
// This is a weird format..
// It can be found in ToTAN 2004-0 (0006 no-mipmaps) where the same
// texture is also in 2004-5 (0009 mipmapped).
// The stride suggests it's 16bpp, however, you'll get garbage then
// as pixels seem to be 32bpp.
// Yet, that means only half the image fits into the file..
//
uint32_t pixel;
if (x >= header.width_a / 2) {
pixel = 0x00FFFFFF;
} else {
pixel = *(uint32_t*)&buffer[y * header.stride + x * 4];
}
uint8_t texel[4];
// Attempts at other 16bpp formats
#if 0
// 565
texel[0] = ((pixel >> 0) & ((1 << 5) - 1)) << 3;
texel[1] = ((pixel >> 5) & ((1 << 6) - 1)) << 2;
texel[2] = ((pixel >> 11) & ((1 << 5) - 1)) << 3;
texel[3] = 0xFF;
// 1555
texel[0] = ((pixel >> 0) & ((1 << 5) - 1)) << 3;
texel[1] = ((pixel >> 5) & ((1 << 5) - 1)) << 3;
texel[2] = ((pixel >> 10) & ((1 << 5) - 1)) << 3;
texel[3] = ((pixel >> 15) & ((1 << 1) - 1)) << 7;
// 4444
texel[0] = ((pixel >> 0) & ((1 << 4) - 1)) << 4;
texel[1] = ((pixel >> 4) & ((1 << 4) - 1)) << 4;
texel[2] = ((pixel >> 8) & ((1 << 4) - 1)) << 4;
texel[3] = ((pixel >> 12) & ((1 << 4) - 1)) << 4;
// 5551
texel[0] = ((pixel >> 11) & ((1 << 5) - 1)) << 3;
texel[1] = ((pixel >> 6) & ((1 << 5) - 1)) << 3;
texel[2] = ((pixel >> 1) & ((1 << 5) - 1)) << 3;
texel[3] = ((pixel >> 0) & ((1 << 1) - 1)) << 7;
#endif
texel[0] = (pixel >> 0) & 0xFF;
texel[1] = (pixel >> 8) & 0xFF;
texel[2] = (pixel >> 16) & 0xFF;
texel[3] = (pixel >> 24) & 0xFF;
fwrite(&texel[0], 1, 1, out);
fwrite(&texel[1], 1, 1, out);
fwrite(&texel[2], 1, 1, out);
fwrite(&texel[3], 1, 1, out);
break;
}
case 0x0009: {
uint8_t texel[4];
fetch_2d_texel_rgba_dxt1(header.width_a, buffer, x, y, texel);
fwrite(&texel[2], 1, 1, out);
fwrite(&texel[1], 1, 1, out);
fwrite(&texel[0], 1, 1, out);
fwrite(&texel[3], 1, 1, out);
break;
}
case 0x000D: {
uint8_t texel[4];
fetch_2d_texel_rgba_dxt5(header.width_a, buffer, x, y, texel);
fwrite(&texel[2], 1, 1, out);
fwrite(&texel[1], 1, 1, out);
fwrite(&texel[0], 1, 1, out);
fwrite(&texel[3], 1, 1, out);
break;
}
default:
assert(false);
break;
}
}
}
free(buffer);
fclose(out);
fclose(in);
return 0;
}