OSDN Git Service

more header tests
[android-x86/external-s2tc.git] / s2tc_decompress.cpp
1 /*
2  * Copyright (C) 2011  Rudolf Polzer   All Rights Reserved.
3  *
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:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
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.
20  */
21 #define S2TC_LICENSE_IDENTIFIER s2tc_decompress_license
22 #include "s2tc_license.h"
23
24 #include <stdio.h>
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <algorithm>
29
30 #ifdef ENABLE_RUNTIME_LINKING
31 #include <dlfcn.h>
32 #include <GL/gl.h>
33 extern "C"
34 {
35         typedef void (fetch_2d_texel_rgb_dxt1_t)(GLint srcRowStride, const GLubyte *pixdata,
36                              GLint i, GLint j, GLvoid *texel);
37         typedef void (fetch_2d_texel_rgba_dxt1_t)(GLint srcRowStride, const GLubyte *pixdata,
38                              GLint i, GLint j, GLvoid *texel);
39         typedef void (fetch_2d_texel_rgba_dxt3_t)(GLint srcRowStride, const GLubyte *pixdata,
40                              GLint i, GLint j, GLvoid *texel);
41         typedef void (fetch_2d_texel_rgba_dxt5_t)(GLint srcRowStride, const GLubyte *pixdata,
42                                      GLint i, GLint j, GLvoid *texel);
43 };
44 fetch_2d_texel_rgb_dxt1_t *fetch_2d_texel_rgb_dxt1 = NULL;
45 fetch_2d_texel_rgba_dxt1_t *fetch_2d_texel_rgba_dxt1 = NULL;
46 fetch_2d_texel_rgba_dxt3_t *fetch_2d_texel_rgba_dxt3 = NULL;
47 fetch_2d_texel_rgba_dxt5_t *fetch_2d_texel_rgba_dxt5 = NULL;
48 inline bool load_libraries()
49 {
50         void *l = dlopen("libtxc_dxtn.so", RTLD_NOW);
51         if(!l)
52         {
53                 fprintf(stderr, "Cannot load library: %s\n", dlerror());
54                 return false;
55         }
56         fetch_2d_texel_rgb_dxt1 = (fetch_2d_texel_rgb_dxt1_t *) dlsym(l, "fetch_2d_texel_rgb_dxt1");
57         fetch_2d_texel_rgba_dxt1 = (fetch_2d_texel_rgba_dxt1_t *) dlsym(l, "fetch_2d_texel_rgba_dxt1");
58         fetch_2d_texel_rgba_dxt3 = (fetch_2d_texel_rgba_dxt3_t *) dlsym(l, "fetch_2d_texel_rgba_dxt3");
59         fetch_2d_texel_rgba_dxt5 = (fetch_2d_texel_rgba_dxt5_t *) dlsym(l, "fetch_2d_texel_rgba_dxt5");
60         if(!fetch_2d_texel_rgb_dxt1 || !fetch_2d_texel_rgba_dxt1 || !fetch_2d_texel_rgba_dxt3 || !fetch_2d_texel_rgba_dxt5)
61         {
62                 fprintf(stderr, "The selected libtxc_dxtn.so does not contain all required symbols.");
63                 dlclose(l);
64                 return false;
65         }
66         return true;
67 }
68 #else
69 extern "C"
70 {
71 #include "txc_dxtn.h"
72 };
73 inline bool load_libraries()
74 {
75         return true;
76 }
77 #endif
78
79 uint32_t LittleLong(uint32_t w)
80 {
81         union
82         {
83                 unsigned char c[4];
84                 uint32_t u;
85         }
86         un;
87         un.c[0] = w;
88         un.c[1] = w >> 8;
89         un.c[2] = w >> 16;
90         un.c[3] = w >> 24;
91         return un.u;
92 }
93
94 int main()
95 {
96         uint32_t h[32];
97         fread(h, sizeof(h), 1, stdin);
98         int height = LittleLong(h[3]);
99         int width = LittleLong(h[4]);
100         int fourcc = LittleLong(h[21]);
101         void (*fetch)(GLint srcRowStride, const GLubyte *pixdata, GLint i, GLint j, GLvoid *texel) = NULL;
102         int blocksize;
103
104         if(!load_libraries())
105                 return 1;
106
107         switch(fourcc)
108         {
109                 case 0x31545844:
110                         fetch = fetch_2d_texel_rgba_dxt1;
111                         blocksize = 8;
112                         break;
113                 case 0x33545844:
114                         fetch = fetch_2d_texel_rgba_dxt3;
115                         blocksize = 16;
116                         break;
117                 case 0x35545844:
118                         fetch = fetch_2d_texel_rgba_dxt5;
119                         blocksize = 16;
120                         break;
121                 default:
122                         fprintf(stderr, "Only DXT1, DXT3, DXT5 are supported!\n");
123                         return 1;
124         }
125
126         unsigned char t[18];
127         memset(t, 0, 18);
128         t[2]  = 2;
129         t[12] = width % 256;
130         t[13] = width / 256;
131         t[14] = height % 256;
132         t[15] = height / 256;
133         t[16] = 32;
134         t[17] = 0x28;
135         fwrite(t, 18, 1, stdout);
136
137         int n = ((width + 3) / 4) * ((height + 3) / 4);
138         unsigned char *buf = (unsigned char *) malloc(n * blocksize);
139         fread(buf, blocksize, n, stdin);
140
141         int x, y;
142         for(y = 0; y < height; ++y)
143                 for(x = 0; x < width; ++x)
144                 {
145                         char data[4];
146                         fetch(width, buf, x, y, &data);
147                         std::swap(data[0], data[2]);
148                         fwrite(data, 4, 1, stdout);
149                 }
150         return 0;
151 }