Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /************************************************************************** |
2 | * |
||
3 | * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. |
||
4 | * Copyright (c) 2008 VMware, Inc. |
||
5 | * |
||
6 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
7 | * copy of this software and associated documentation files (the "Software"), |
||
8 | * to deal in the Software without restriction, including without limitation |
||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
10 | * and/or sell copies of the Software, and to permit persons to whom the |
||
11 | * Software is furnished to do so, subject to the following conditions: |
||
12 | * |
||
13 | * The above copyright notice and this permission notice shall be included |
||
14 | * in all copies or substantial portions of the Software. |
||
15 | * |
||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||
17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
||
20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||
22 | * OTHER DEALINGS IN THE SOFTWARE. |
||
23 | * |
||
24 | **************************************************************************/ |
||
25 | |||
26 | #include "u_dl.h" |
||
27 | #include "u_math.h" |
||
28 | #include "u_format.h" |
||
29 | #include "u_format_s3tc.h" |
||
30 | #include "u_format_srgb.h" |
||
31 | |||
32 | |||
33 | #if defined(_WIN32) || defined(WIN32) |
||
34 | #define DXTN_LIBNAME "dxtn.dll" |
||
35 | #elif defined(__APPLE__) |
||
36 | #define DXTN_LIBNAME "libtxc_dxtn.dylib" |
||
37 | #else |
||
38 | #define DXTN_LIBNAME "libtxc_dxtn.so" |
||
39 | #endif |
||
40 | |||
41 | |||
42 | static void |
||
43 | util_format_dxt1_rgb_fetch_stub(int src_stride, |
||
44 | const uint8_t *src, |
||
45 | int col, int row, |
||
46 | uint8_t *dst) |
||
47 | { |
||
48 | assert(0); |
||
49 | } |
||
50 | |||
51 | |||
52 | static void |
||
53 | util_format_dxt1_rgba_fetch_stub(int src_stride, |
||
54 | const uint8_t *src, |
||
55 | int col, int row, |
||
56 | uint8_t *dst ) |
||
57 | { |
||
58 | assert(0); |
||
59 | } |
||
60 | |||
61 | |||
62 | static void |
||
63 | util_format_dxt3_rgba_fetch_stub(int src_stride, |
||
64 | const uint8_t *src, |
||
65 | int col, int row, |
||
66 | uint8_t *dst ) |
||
67 | { |
||
68 | assert(0); |
||
69 | } |
||
70 | |||
71 | |||
72 | static void |
||
73 | util_format_dxt5_rgba_fetch_stub(int src_stride, |
||
74 | const uint8_t *src, |
||
75 | int col, int row, |
||
76 | uint8_t *dst ) |
||
77 | { |
||
78 | assert(0); |
||
79 | } |
||
80 | |||
81 | |||
82 | static void |
||
83 | util_format_dxtn_pack_stub(int src_comps, |
||
84 | int width, int height, |
||
85 | const uint8_t *src, |
||
86 | enum util_format_dxtn dst_format, |
||
87 | uint8_t *dst, |
||
88 | int dst_stride) |
||
89 | { |
||
90 | assert(0); |
||
91 | } |
||
92 | |||
93 | |||
94 | boolean util_format_s3tc_enabled = FALSE; |
||
95 | |||
96 | util_format_dxtn_fetch_t util_format_dxt1_rgb_fetch = util_format_dxt1_rgb_fetch_stub; |
||
97 | util_format_dxtn_fetch_t util_format_dxt1_rgba_fetch = util_format_dxt1_rgba_fetch_stub; |
||
98 | util_format_dxtn_fetch_t util_format_dxt3_rgba_fetch = util_format_dxt3_rgba_fetch_stub; |
||
99 | util_format_dxtn_fetch_t util_format_dxt5_rgba_fetch = util_format_dxt5_rgba_fetch_stub; |
||
100 | |||
101 | util_format_dxtn_pack_t util_format_dxtn_pack = util_format_dxtn_pack_stub; |
||
102 | |||
103 | |||
104 | void |
||
105 | util_format_s3tc_init(void) |
||
106 | { |
||
107 | static boolean first_time = TRUE; |
||
108 | struct util_dl_library *library = NULL; |
||
109 | util_dl_proc fetch_2d_texel_rgb_dxt1; |
||
110 | util_dl_proc fetch_2d_texel_rgba_dxt1; |
||
111 | util_dl_proc fetch_2d_texel_rgba_dxt3; |
||
112 | util_dl_proc fetch_2d_texel_rgba_dxt5; |
||
113 | util_dl_proc tx_compress_dxtn; |
||
5063 | serge | 114 | char *force_s3tc_enable; |
115 | |||
116 | return; |
||
117 | #if 0 |
||
4358 | Serge | 118 | if (!first_time) |
119 | return; |
||
120 | first_time = FALSE; |
||
121 | |||
122 | if (util_format_s3tc_enabled) |
||
123 | return; |
||
124 | |||
5063 | serge | 125 | // library = util_dl_open(DXTN_LIBNAME); |
4358 | Serge | 126 | if (!library) { |
5063 | serge | 127 | if ((force_s3tc_enable = getenv("force_s3tc_enable")) && |
128 | !strcmp(force_s3tc_enable, "true")) { |
||
129 | debug_printf("couldn't open " DXTN_LIBNAME ", enabling DXTn due to " |
||
130 | "force_s3tc_enable=true environment variable\n"); |
||
131 | util_format_s3tc_enabled = TRUE; |
||
132 | } else { |
||
133 | debug_printf("couldn't open " DXTN_LIBNAME ", software DXTn " |
||
134 | "compression/decompression unavailable\n"); |
||
135 | } |
||
4358 | Serge | 136 | return; |
137 | } |
||
138 | |||
139 | fetch_2d_texel_rgb_dxt1 = |
||
140 | util_dl_get_proc_address(library, "fetch_2d_texel_rgb_dxt1"); |
||
141 | fetch_2d_texel_rgba_dxt1 = |
||
142 | util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt1"); |
||
143 | fetch_2d_texel_rgba_dxt3 = |
||
144 | util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt3"); |
||
145 | fetch_2d_texel_rgba_dxt5 = |
||
146 | util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt5"); |
||
147 | tx_compress_dxtn = |
||
148 | util_dl_get_proc_address(library, "tx_compress_dxtn"); |
||
149 | |||
150 | if (!util_format_dxt1_rgb_fetch || |
||
151 | !util_format_dxt1_rgba_fetch || |
||
152 | !util_format_dxt3_rgba_fetch || |
||
153 | !util_format_dxt5_rgba_fetch || |
||
154 | !util_format_dxtn_pack) { |
||
155 | debug_printf("couldn't reference all symbols in " DXTN_LIBNAME |
||
156 | ", software DXTn compression/decompression " |
||
157 | "unavailable\n"); |
||
158 | util_dl_close(library); |
||
159 | return; |
||
160 | } |
||
161 | |||
162 | util_format_dxt1_rgb_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgb_dxt1; |
||
163 | util_format_dxt1_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt1; |
||
164 | util_format_dxt3_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt3; |
||
165 | util_format_dxt5_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt5; |
||
166 | util_format_dxtn_pack = (util_format_dxtn_pack_t)tx_compress_dxtn; |
||
167 | util_format_s3tc_enabled = TRUE; |
||
5063 | serge | 168 | #endif |
4358 | Serge | 169 | } |
170 | |||
171 | |||
172 | /* |
||
173 | * Pixel fetch. |
||
174 | */ |
||
175 | |||
176 | void |
||
177 | util_format_dxt1_rgb_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
||
178 | { |
||
179 | util_format_dxt1_rgb_fetch(0, src, i, j, dst); |
||
180 | } |
||
181 | |||
182 | void |
||
183 | util_format_dxt1_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
||
184 | { |
||
185 | util_format_dxt1_rgba_fetch(0, src, i, j, dst); |
||
186 | } |
||
187 | |||
188 | void |
||
189 | util_format_dxt3_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
||
190 | { |
||
191 | util_format_dxt3_rgba_fetch(0, src, i, j, dst); |
||
192 | } |
||
193 | |||
194 | void |
||
195 | util_format_dxt5_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
||
196 | { |
||
197 | util_format_dxt5_rgba_fetch(0, src, i, j, dst); |
||
198 | } |
||
199 | |||
200 | void |
||
201 | util_format_dxt1_rgb_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
||
202 | { |
||
203 | uint8_t tmp[4]; |
||
204 | util_format_dxt1_rgb_fetch(0, src, i, j, tmp); |
||
205 | dst[0] = ubyte_to_float(tmp[0]); |
||
206 | dst[1] = ubyte_to_float(tmp[1]); |
||
207 | dst[2] = ubyte_to_float(tmp[2]); |
||
208 | dst[3] = 1.0; |
||
209 | } |
||
210 | |||
211 | void |
||
212 | util_format_dxt1_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
||
213 | { |
||
214 | uint8_t tmp[4]; |
||
215 | util_format_dxt1_rgba_fetch(0, src, i, j, tmp); |
||
216 | dst[0] = ubyte_to_float(tmp[0]); |
||
217 | dst[1] = ubyte_to_float(tmp[1]); |
||
218 | dst[2] = ubyte_to_float(tmp[2]); |
||
219 | dst[3] = ubyte_to_float(tmp[3]); |
||
220 | } |
||
221 | |||
222 | void |
||
223 | util_format_dxt3_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
||
224 | { |
||
225 | uint8_t tmp[4]; |
||
226 | util_format_dxt3_rgba_fetch(0, src, i, j, tmp); |
||
227 | dst[0] = ubyte_to_float(tmp[0]); |
||
228 | dst[1] = ubyte_to_float(tmp[1]); |
||
229 | dst[2] = ubyte_to_float(tmp[2]); |
||
230 | dst[3] = ubyte_to_float(tmp[3]); |
||
231 | } |
||
232 | |||
233 | void |
||
234 | util_format_dxt5_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
||
235 | { |
||
236 | uint8_t tmp[4]; |
||
237 | util_format_dxt5_rgba_fetch(0, src, i, j, tmp); |
||
238 | dst[0] = ubyte_to_float(tmp[0]); |
||
239 | dst[1] = ubyte_to_float(tmp[1]); |
||
240 | dst[2] = ubyte_to_float(tmp[2]); |
||
241 | dst[3] = ubyte_to_float(tmp[3]); |
||
242 | } |
||
243 | |||
244 | |||
245 | /* |
||
246 | * Block decompression. |
||
247 | */ |
||
248 | |||
249 | static INLINE void |
||
250 | util_format_dxtn_rgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
||
251 | const uint8_t *src_row, unsigned src_stride, |
||
252 | unsigned width, unsigned height, |
||
253 | util_format_dxtn_fetch_t fetch, |
||
5063 | serge | 254 | unsigned block_size) |
4358 | Serge | 255 | { |
256 | const unsigned bw = 4, bh = 4, comps = 4; |
||
257 | unsigned x, y, i, j; |
||
258 | for(y = 0; y < height; y += bh) { |
||
259 | const uint8_t *src = src_row; |
||
260 | for(x = 0; x < width; x += bw) { |
||
261 | for(j = 0; j < bh; ++j) { |
||
262 | for(i = 0; i < bw; ++i) { |
||
263 | uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps; |
||
264 | fetch(0, src, i, j, dst); |
||
265 | } |
||
266 | } |
||
267 | src += block_size; |
||
268 | } |
||
269 | src_row += src_stride; |
||
270 | } |
||
271 | } |
||
272 | |||
273 | void |
||
274 | util_format_dxt1_rgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
||
275 | const uint8_t *src_row, unsigned src_stride, |
||
276 | unsigned width, unsigned height) |
||
277 | { |
||
278 | util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, |
||
279 | src_row, src_stride, |
||
280 | width, height, |
||
5063 | serge | 281 | util_format_dxt1_rgb_fetch, 8); |
4358 | Serge | 282 | } |
283 | |||
284 | void |
||
285 | util_format_dxt1_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
||
286 | const uint8_t *src_row, unsigned src_stride, |
||
287 | unsigned width, unsigned height) |
||
288 | { |
||
289 | util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, |
||
290 | src_row, src_stride, |
||
291 | width, height, |
||
5063 | serge | 292 | util_format_dxt1_rgba_fetch, 8); |
4358 | Serge | 293 | } |
294 | |||
295 | void |
||
296 | util_format_dxt3_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
||
297 | const uint8_t *src_row, unsigned src_stride, |
||
298 | unsigned width, unsigned height) |
||
299 | { |
||
300 | util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, |
||
301 | src_row, src_stride, |
||
302 | width, height, |
||
5063 | serge | 303 | util_format_dxt3_rgba_fetch, 16); |
4358 | Serge | 304 | } |
305 | |||
306 | void |
||
307 | util_format_dxt5_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
||
308 | const uint8_t *src_row, unsigned src_stride, |
||
309 | unsigned width, unsigned height) |
||
310 | { |
||
311 | util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, |
||
312 | src_row, src_stride, |
||
313 | width, height, |
||
5063 | serge | 314 | util_format_dxt5_rgba_fetch, 16); |
4358 | Serge | 315 | } |
316 | |||
317 | static INLINE void |
||
318 | util_format_dxtn_rgb_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
||
319 | const uint8_t *src_row, unsigned src_stride, |
||
320 | unsigned width, unsigned height, |
||
321 | util_format_dxtn_fetch_t fetch, |
||
5063 | serge | 322 | unsigned block_size) |
4358 | Serge | 323 | { |
324 | unsigned x, y, i, j; |
||
325 | for(y = 0; y < height; y += 4) { |
||
326 | const uint8_t *src = src_row; |
||
327 | for(x = 0; x < width; x += 4) { |
||
328 | for(j = 0; j < 4; ++j) { |
||
329 | for(i = 0; i < 4; ++i) { |
||
330 | float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; |
||
331 | uint8_t tmp[4]; |
||
332 | fetch(0, src, i, j, tmp); |
||
5063 | serge | 333 | dst[0] = ubyte_to_float(tmp[0]); |
334 | dst[1] = ubyte_to_float(tmp[1]); |
||
335 | dst[2] = ubyte_to_float(tmp[2]); |
||
4358 | Serge | 336 | dst[3] = ubyte_to_float(tmp[3]); |
337 | } |
||
338 | } |
||
339 | src += block_size; |
||
340 | } |
||
341 | src_row += src_stride; |
||
342 | } |
||
343 | } |
||
344 | |||
345 | void |
||
346 | util_format_dxt1_rgb_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
||
347 | const uint8_t *src_row, unsigned src_stride, |
||
348 | unsigned width, unsigned height) |
||
349 | { |
||
350 | util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, |
||
351 | src_row, src_stride, |
||
352 | width, height, |
||
5063 | serge | 353 | util_format_dxt1_rgb_fetch, 8); |
4358 | Serge | 354 | } |
355 | |||
356 | void |
||
357 | util_format_dxt1_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
||
358 | const uint8_t *src_row, unsigned src_stride, |
||
359 | unsigned width, unsigned height) |
||
360 | { |
||
361 | util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, |
||
362 | src_row, src_stride, |
||
363 | width, height, |
||
5063 | serge | 364 | util_format_dxt1_rgba_fetch, 8); |
4358 | Serge | 365 | } |
366 | |||
367 | void |
||
368 | util_format_dxt3_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
||
369 | const uint8_t *src_row, unsigned src_stride, |
||
370 | unsigned width, unsigned height) |
||
371 | { |
||
372 | util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, |
||
373 | src_row, src_stride, |
||
374 | width, height, |
||
5063 | serge | 375 | util_format_dxt3_rgba_fetch, 16); |
4358 | Serge | 376 | } |
377 | |||
378 | void |
||
379 | util_format_dxt5_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
||
380 | const uint8_t *src_row, unsigned src_stride, |
||
381 | unsigned width, unsigned height) |
||
382 | { |
||
383 | util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, |
||
384 | src_row, src_stride, |
||
385 | width, height, |
||
5063 | serge | 386 | util_format_dxt5_rgba_fetch, 16); |
4358 | Serge | 387 | } |
388 | |||
389 | |||
390 | /* |
||
391 | * Block compression. |
||
392 | */ |
||
393 | |||
5063 | serge | 394 | void |
395 | util_format_dxt1_rgb_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
||
396 | const uint8_t *src, unsigned src_stride, |
||
397 | unsigned width, unsigned height) |
||
4358 | Serge | 398 | { |
5063 | serge | 399 | const unsigned bw = 4, bh = 4, bytes_per_block = 8; |
4358 | Serge | 400 | unsigned x, y, i, j, k; |
401 | for(y = 0; y < height; y += bh) { |
||
402 | uint8_t *dst = dst_row; |
||
403 | for(x = 0; x < width; x += bw) { |
||
5063 | serge | 404 | uint8_t tmp[4][4][3]; /* [bh][bw][comps] */ |
4358 | Serge | 405 | for(j = 0; j < bh; ++j) { |
406 | for(i = 0; i < bw; ++i) { |
||
407 | for(k = 0; k < 3; ++k) { |
||
5063 | serge | 408 | tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + (x + i)*4 + k]; |
4358 | Serge | 409 | } |
410 | } |
||
411 | } |
||
5063 | serge | 412 | util_format_dxtn_pack(3, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGB, dst, 0); |
413 | dst += bytes_per_block; |
||
4358 | Serge | 414 | } |
415 | dst_row += dst_stride / sizeof(*dst_row); |
||
416 | } |
||
417 | } |
||
418 | |||
419 | void |
||
420 | util_format_dxt1_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
||
421 | const uint8_t *src, unsigned src_stride, |
||
422 | unsigned width, unsigned height) |
||
423 | { |
||
5063 | serge | 424 | const unsigned bw = 4, bh = 4, comps = 4, bytes_per_block = 8; |
425 | unsigned x, y, i, j, k; |
||
426 | for(y = 0; y < height; y += bh) { |
||
427 | uint8_t *dst = dst_row; |
||
428 | for(x = 0; x < width; x += bw) { |
||
429 | uint8_t tmp[4][4][4]; /* [bh][bw][comps] */ |
||
430 | for(j = 0; j < bh; ++j) { |
||
431 | for(i = 0; i < bw; ++i) { |
||
432 | for(k = 0; k < comps; ++k) { |
||
433 | tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + (x + i)*comps + k]; |
||
434 | } |
||
435 | } |
||
436 | } |
||
437 | util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGBA, dst, 0); |
||
438 | dst += bytes_per_block; |
||
439 | } |
||
440 | dst_row += dst_stride / sizeof(*dst_row); |
||
441 | } |
||
4358 | Serge | 442 | } |
443 | |||
444 | void |
||
445 | util_format_dxt3_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
||
446 | const uint8_t *src, unsigned src_stride, |
||
447 | unsigned width, unsigned height) |
||
448 | { |
||
5063 | serge | 449 | const unsigned bw = 4, bh = 4, comps = 4, bytes_per_block = 16; |
450 | unsigned x, y, i, j, k; |
||
451 | for(y = 0; y < height; y += bh) { |
||
452 | uint8_t *dst = dst_row; |
||
453 | for(x = 0; x < width; x += bw) { |
||
454 | uint8_t tmp[4][4][4]; /* [bh][bw][comps] */ |
||
455 | for(j = 0; j < bh; ++j) { |
||
456 | for(i = 0; i < bw; ++i) { |
||
457 | for(k = 0; k < comps; ++k) { |
||
458 | tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + (x + i)*comps + k]; |
||
459 | } |
||
460 | } |
||
461 | } |
||
462 | util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT3_RGBA, dst, 0); |
||
463 | dst += bytes_per_block; |
||
464 | } |
||
465 | dst_row += dst_stride / sizeof(*dst_row); |
||
466 | } |
||
4358 | Serge | 467 | } |
468 | |||
469 | void |
||
470 | util_format_dxt5_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
||
471 | const uint8_t *src, unsigned src_stride, |
||
472 | unsigned width, unsigned height) |
||
473 | { |
||
5063 | serge | 474 | const unsigned bw = 4, bh = 4, comps = 4, bytes_per_block = 16; |
475 | unsigned x, y, i, j, k; |
||
476 | |||
477 | for(y = 0; y < height; y += bh) { |
||
478 | uint8_t *dst = dst_row; |
||
479 | for(x = 0; x < width; x += bw) { |
||
480 | uint8_t tmp[4][4][4]; /* [bh][bw][comps] */ |
||
481 | for(j = 0; j < bh; ++j) { |
||
482 | for(i = 0; i < bw; ++i) { |
||
483 | for(k = 0; k < comps; ++k) { |
||
484 | tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + (x + i)*comps + k]; |
||
485 | } |
||
486 | } |
||
487 | } |
||
488 | util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT5_RGBA, dst, 0); |
||
489 | dst += bytes_per_block; |
||
490 | } |
||
491 | dst_row += dst_stride / sizeof(*dst_row); |
||
492 | } |
||
4358 | Serge | 493 | } |
494 | |||
5063 | serge | 495 | void |
496 | util_format_dxt1_rgb_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
||
497 | const float *src, unsigned src_stride, |
||
498 | unsigned width, unsigned height) |
||
4358 | Serge | 499 | { |
500 | unsigned x, y, i, j, k; |
||
501 | for(y = 0; y < height; y += 4) { |
||
502 | uint8_t *dst = dst_row; |
||
503 | for(x = 0; x < width; x += 4) { |
||
5063 | serge | 504 | uint8_t tmp[4][4][3]; |
4358 | Serge | 505 | for(j = 0; j < 4; ++j) { |
506 | for(i = 0; i < 4; ++i) { |
||
507 | for(k = 0; k < 3; ++k) { |
||
5063 | serge | 508 | tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k]); |
4358 | Serge | 509 | } |
510 | } |
||
511 | } |
||
5063 | serge | 512 | util_format_dxtn_pack(3, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGB, dst, 0); |
513 | dst += 8; |
||
4358 | Serge | 514 | } |
515 | dst_row += 4*dst_stride/sizeof(*dst_row); |
||
516 | } |
||
517 | } |
||
518 | |||
519 | void |
||
520 | util_format_dxt1_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
||
521 | const float *src, unsigned src_stride, |
||
522 | unsigned width, unsigned height) |
||
523 | { |
||
5063 | serge | 524 | unsigned x, y, i, j, k; |
525 | for(y = 0; y < height; y += 4) { |
||
526 | uint8_t *dst = dst_row; |
||
527 | for(x = 0; x < width; x += 4) { |
||
528 | uint8_t tmp[4][4][4]; |
||
529 | for(j = 0; j < 4; ++j) { |
||
530 | for(i = 0; i < 4; ++i) { |
||
531 | for(k = 0; k < 4; ++k) { |
||
532 | tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k]); |
||
533 | } |
||
534 | } |
||
535 | } |
||
536 | util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGBA, dst, 0); |
||
537 | dst += 8; |
||
538 | } |
||
539 | dst_row += 4*dst_stride/sizeof(*dst_row); |
||
540 | } |
||
4358 | Serge | 541 | } |
542 | |||
543 | void |
||
544 | util_format_dxt3_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
||
545 | const float *src, unsigned src_stride, |
||
546 | unsigned width, unsigned height) |
||
547 | { |
||
5063 | serge | 548 | unsigned x, y, i, j, k; |
549 | for(y = 0; y < height; y += 4) { |
||
550 | uint8_t *dst = dst_row; |
||
551 | for(x = 0; x < width; x += 4) { |
||
552 | uint8_t tmp[4][4][4]; |
||
553 | for(j = 0; j < 4; ++j) { |
||
554 | for(i = 0; i < 4; ++i) { |
||
555 | for(k = 0; k < 4; ++k) { |
||
556 | tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k]); |
||
557 | } |
||
558 | } |
||
559 | } |
||
560 | util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT3_RGBA, dst, 0); |
||
561 | dst += 16; |
||
562 | } |
||
563 | dst_row += 4*dst_stride/sizeof(*dst_row); |
||
564 | } |
||
4358 | Serge | 565 | } |
566 | |||
567 | void |
||
568 | util_format_dxt5_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
||
569 | const float *src, unsigned src_stride, |
||
570 | unsigned width, unsigned height) |
||
571 | { |
||
5063 | serge | 572 | unsigned x, y, i, j, k; |
573 | for(y = 0; y < height; y += 4) { |
||
574 | uint8_t *dst = dst_row; |
||
575 | for(x = 0; x < width; x += 4) { |
||
576 | uint8_t tmp[4][4][4]; |
||
577 | for(j = 0; j < 4; ++j) { |
||
578 | for(i = 0; i < 4; ++i) { |
||
579 | for(k = 0; k < 4; ++k) { |
||
580 | tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k]); |
||
581 | } |
||
582 | } |
||
583 | } |
||
584 | util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT5_RGBA, dst, 0); |
||
585 | dst += 16; |
||
586 | } |
||
587 | dst_row += 4*dst_stride/sizeof(*dst_row); |
||
588 | } |
||
4358 | Serge | 589 | } |
590 | |||
591 | |||
592 | /* |
||
593 | * SRGB variants. |
||
5063 | serge | 594 | * |
595 | * FIXME: shunts to RGB for now |
||
4358 | Serge | 596 | */ |
597 | |||
598 | void |
||
5063 | serge | 599 | util_format_dxt1_srgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 600 | { |
5063 | serge | 601 | util_format_dxt1_rgb_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 602 | } |
603 | |||
604 | void |
||
5063 | serge | 605 | util_format_dxt1_srgb_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 606 | { |
5063 | serge | 607 | util_format_dxt1_rgb_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 608 | } |
609 | |||
610 | void |
||
5063 | serge | 611 | util_format_dxt1_srgb_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
4358 | Serge | 612 | { |
5063 | serge | 613 | util_format_dxt1_rgb_fetch_rgba_8unorm(dst, src, i, j); |
4358 | Serge | 614 | } |
615 | |||
616 | void |
||
5063 | serge | 617 | util_format_dxt1_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 618 | { |
5063 | serge | 619 | util_format_dxt1_rgba_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 620 | } |
621 | |||
622 | void |
||
5063 | serge | 623 | util_format_dxt1_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 624 | { |
5063 | serge | 625 | util_format_dxt1_rgba_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 626 | } |
627 | |||
628 | void |
||
5063 | serge | 629 | util_format_dxt1_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
4358 | Serge | 630 | { |
5063 | serge | 631 | util_format_dxt1_rgba_fetch_rgba_8unorm(dst, src, i, j); |
4358 | Serge | 632 | } |
633 | |||
634 | void |
||
5063 | serge | 635 | util_format_dxt3_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 636 | { |
5063 | serge | 637 | util_format_dxt3_rgba_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 638 | } |
639 | |||
640 | void |
||
5063 | serge | 641 | util_format_dxt3_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 642 | { |
5063 | serge | 643 | util_format_dxt3_rgba_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 644 | } |
645 | |||
646 | void |
||
5063 | serge | 647 | util_format_dxt3_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
4358 | Serge | 648 | { |
5063 | serge | 649 | util_format_dxt3_rgba_fetch_rgba_8unorm(dst, src, i, j); |
4358 | Serge | 650 | } |
651 | |||
652 | void |
||
5063 | serge | 653 | util_format_dxt5_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 654 | { |
5063 | serge | 655 | util_format_dxt5_rgba_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 656 | } |
657 | |||
658 | void |
||
5063 | serge | 659 | util_format_dxt5_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 660 | { |
5063 | serge | 661 | util_format_dxt5_rgba_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 662 | } |
663 | |||
664 | void |
||
5063 | serge | 665 | util_format_dxt5_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
4358 | Serge | 666 | { |
5063 | serge | 667 | util_format_dxt5_rgba_fetch_rgba_8unorm(dst, src, i, j); |
4358 | Serge | 668 | } |
669 | |||
670 | void |
||
671 | util_format_dxt1_srgb_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
||
672 | { |
||
5063 | serge | 673 | util_format_dxt1_rgb_unpack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 674 | } |
675 | |||
676 | void |
||
5063 | serge | 677 | util_format_dxt1_srgb_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 678 | { |
5063 | serge | 679 | util_format_dxt1_rgb_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 680 | } |
681 | |||
682 | void |
||
5063 | serge | 683 | util_format_dxt1_srgb_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
4358 | Serge | 684 | { |
5063 | serge | 685 | util_format_dxt1_rgb_fetch_rgba_float(dst, src, i, j); |
4358 | Serge | 686 | } |
687 | |||
688 | void |
||
5063 | serge | 689 | util_format_dxt1_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 690 | { |
5063 | serge | 691 | util_format_dxt1_rgba_unpack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 692 | } |
693 | |||
694 | void |
||
5063 | serge | 695 | util_format_dxt1_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 696 | { |
5063 | serge | 697 | util_format_dxt1_rgba_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 698 | } |
699 | |||
700 | void |
||
5063 | serge | 701 | util_format_dxt1_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
4358 | Serge | 702 | { |
5063 | serge | 703 | util_format_dxt1_rgba_fetch_rgba_float(dst, src, i, j); |
4358 | Serge | 704 | } |
705 | |||
706 | void |
||
5063 | serge | 707 | util_format_dxt3_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 708 | { |
5063 | serge | 709 | util_format_dxt3_rgba_unpack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 710 | } |
711 | |||
712 | void |
||
5063 | serge | 713 | util_format_dxt3_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 714 | { |
5063 | serge | 715 | util_format_dxt3_rgba_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 716 | } |
717 | |||
718 | void |
||
5063 | serge | 719 | util_format_dxt3_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
4358 | Serge | 720 | { |
5063 | serge | 721 | util_format_dxt3_rgba_fetch_rgba_float(dst, src, i, j); |
4358 | Serge | 722 | } |
723 | |||
724 | void |
||
5063 | serge | 725 | util_format_dxt5_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 726 | { |
5063 | serge | 727 | util_format_dxt5_rgba_unpack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 728 | } |
729 | |||
730 | void |
||
5063 | serge | 731 | util_format_dxt5_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
4358 | Serge | 732 | { |
5063 | serge | 733 | util_format_dxt5_rgba_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); |
4358 | Serge | 734 | } |
735 | |||
736 | void |
||
5063 | serge | 737 | util_format_dxt5_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
4358 | Serge | 738 | { |
5063 | serge | 739 | util_format_dxt5_rgba_fetch_rgba_float(dst, src, i, j); |
4358 | Serge | 740 | }>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> |
741 |