2 * Copyright (C) 2011 Rudolf Polzer All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * RUDOLF POLZER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 #define S2TC_LICENSE_IDENTIFIER s2tc_decompress_license
22 #include "s2tc_license.h"
30 #include "s2tc_common.h"
32 #ifdef ENABLE_RUNTIME_LINKING
37 typedef void (fetch_2d_texel_rgb_dxt1_t)(GLint srcRowStride, const GLubyte *pixdata,
38 GLint i, GLint j, GLvoid *texel);
39 typedef void (fetch_2d_texel_rgba_dxt1_t)(GLint srcRowStride, const GLubyte *pixdata,
40 GLint i, GLint j, GLvoid *texel);
41 typedef void (fetch_2d_texel_rgba_dxt3_t)(GLint srcRowStride, const GLubyte *pixdata,
42 GLint i, GLint j, GLvoid *texel);
43 typedef void (fetch_2d_texel_rgba_dxt5_t)(GLint srcRowStride, const GLubyte *pixdata,
44 GLint i, GLint j, GLvoid *texel);
46 fetch_2d_texel_rgb_dxt1_t *fetch_2d_texel_rgb_dxt1 = NULL;
47 fetch_2d_texel_rgba_dxt1_t *fetch_2d_texel_rgba_dxt1 = NULL;
48 fetch_2d_texel_rgba_dxt3_t *fetch_2d_texel_rgba_dxt3 = NULL;
49 fetch_2d_texel_rgba_dxt5_t *fetch_2d_texel_rgba_dxt5 = NULL;
50 inline bool load_libraries(const char *n)
52 void *l = dlopen(n, RTLD_NOW);
55 fprintf(stderr, "Cannot load library: %s\n", dlerror());
58 fetch_2d_texel_rgb_dxt1 = (fetch_2d_texel_rgb_dxt1_t *) dlsym(l, "fetch_2d_texel_rgb_dxt1");
59 fetch_2d_texel_rgba_dxt1 = (fetch_2d_texel_rgba_dxt1_t *) dlsym(l, "fetch_2d_texel_rgba_dxt1");
60 fetch_2d_texel_rgba_dxt3 = (fetch_2d_texel_rgba_dxt3_t *) dlsym(l, "fetch_2d_texel_rgba_dxt3");
61 fetch_2d_texel_rgba_dxt5 = (fetch_2d_texel_rgba_dxt5_t *) dlsym(l, "fetch_2d_texel_rgba_dxt5");
62 if(!fetch_2d_texel_rgb_dxt1 || !fetch_2d_texel_rgba_dxt1 || !fetch_2d_texel_rgba_dxt3 || !fetch_2d_texel_rgba_dxt5)
64 fprintf(stderr, "The selected libtxc_dxtn.so does not contain all required symbols.");
77 uint32_t LittleLong(uint32_t w)
92 int usage(const char *me)
94 fprintf(stderr, "usage:\n"
98 #ifdef ENABLE_RUNTIME_LINKING
99 " [-l path_to_libtxc_dxtn.so]\n"
106 int main(int argc, char **argv)
108 const char *infile = NULL, *outfile = NULL;
110 #ifdef ENABLE_RUNTIME_LINKING
111 const char *library = "libtxc_dxtn.so";
115 while((opt = getopt(argc, argv, "i:o:"
116 #ifdef ENABLE_RUNTIME_LINKING
129 #ifdef ENABLE_RUNTIME_LINKING
135 return usage(argv[0]);
139 #ifdef ENABLE_RUNTIME_LINKING
140 if(!load_libraries(library))
144 FILE *infh = infile ? fopen(infile, "rb") : stdin;
147 printf("opening input failed\n");
151 FILE *outfh = outfile ? fopen(outfile, "wb") : stdout;
154 printf("opening output failed\n");
159 fread(h, sizeof(h), 1, infh);
160 int height = LittleLong(h[3]);
161 int width = LittleLong(h[4]);
163 void (*fetch)(GLint srcRowStride, const GLubyte *pixdata, GLint i, GLint j, GLvoid *texel) = NULL;
164 int fourcc = LittleLong(h[21]);
169 fetch = fetch_2d_texel_rgba_dxt1;
173 fetch = fetch_2d_texel_rgba_dxt3;
177 fetch = fetch_2d_texel_rgba_dxt5;
181 fprintf(stderr, "Only DXT1, DXT3, DXT5 are supported!\n");
190 t[14] = height % 256;
191 t[15] = height / 256;
194 fwrite(t, 18, 1, outfh);
196 int n = ((width + 3) / 4) * ((height + 3) / 4);
197 unsigned char *buf = (unsigned char *) malloc(n * blocksize);
198 fread(buf, blocksize, n, infh);
201 for(y = 0; y < height; ++y)
202 for(x = 0; x < width; ++x)
205 fetch(width, buf, x, y, &data);
206 std::swap(data[0], data[2]);
207 fwrite(data, 4, 1, outfh);