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