util: don't define isfinite(), isnan() for MSVC >= 1800
[mesa.git] / src / gallium / auxiliary / util / u_format_rgtc.c
1 /**************************************************************************
2 *
3 * Copyright (C) 2011 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 **************************************************************************/
24
25 #include <stdio.h>
26 #include "u_math.h"
27 #include "u_format.h"
28 #include "u_format_rgtc.h"
29
30 static void u_format_unsigned_encode_rgtc_ubyte(uint8_t *blkaddr, uint8_t srccolors[4][4],
31 int numxpixels, int numypixels);
32
33 static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata,
34 unsigned i, unsigned j, uint8_t *value, unsigned comps);
35
36 static void u_format_signed_encode_rgtc_ubyte(int8_t *blkaddr, int8_t srccolors[4][4],
37 int numxpixels, int numypixels);
38
39 static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata,
40 unsigned i, unsigned j, int8_t *value, unsigned comps);
41
42 void
43 util_format_rgtc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
44 {
45 u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
46 dst[1] = 0;
47 dst[2] = 0;
48 dst[3] = 255;
49 }
50
51 void
52 util_format_rgtc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
53 {
54 const unsigned bw = 4, bh = 4, comps = 4;
55 unsigned x, y, i, j;
56 unsigned block_size = 8;
57
58 for(y = 0; y < height; y += bh) {
59 const uint8_t *src = src_row;
60 for(x = 0; x < width; x += bw) {
61 for(j = 0; j < bh; ++j) {
62 for(i = 0; i < bw; ++i) {
63 uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
64 u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
65 dst[1] = 0;
66 dst[2] = 0;
67 dst[3] = 255;
68 }
69 }
70 src += block_size;
71 }
72 src_row += src_stride;
73 }
74 }
75
76 void
77 util_format_rgtc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row,
78 unsigned src_stride, unsigned width, unsigned height)
79 {
80 const unsigned bw = 4, bh = 4, bytes_per_block = 8;
81 unsigned x, y, i, j;
82
83 for(y = 0; y < height; y += bh) {
84 uint8_t *dst = dst_row;
85 for(x = 0; x < width; x += bw) {
86 uint8_t tmp[4][4]; /* [bh][bw][comps] */
87 for(j = 0; j < bh; ++j) {
88 for(i = 0; i < bw; ++i) {
89 tmp[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4];
90 }
91 }
92 u_format_unsigned_encode_rgtc_ubyte(dst, tmp, 4, 4);
93 dst += bytes_per_block;
94 }
95 dst_row += dst_stride / sizeof(*dst_row);
96 }
97 }
98
99 void
100 util_format_rgtc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
101 {
102 unsigned x, y, i, j;
103 int block_size = 8;
104 for(y = 0; y < height; y += 4) {
105 const uint8_t *src = src_row;
106 for(x = 0; x < width; x += 4) {
107 for(j = 0; j < 4; ++j) {
108 for(i = 0; i < 4; ++i) {
109 float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
110 uint8_t tmp_r;
111 u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
112 dst[0] = ubyte_to_float(tmp_r);
113 dst[1] = 0.0;
114 dst[2] = 0.0;
115 dst[3] = 1.0;
116 }
117 }
118 src += block_size;
119 }
120 src_row += src_stride;
121 }
122 }
123
124 void
125 util_format_rgtc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
126 {
127 const unsigned bw = 4, bh = 4, bytes_per_block = 8;
128 unsigned x, y, i, j;
129
130 for(y = 0; y < height; y += bh) {
131 uint8_t *dst = dst_row;
132 for(x = 0; x < width; x += bw) {
133 uint8_t tmp[4][4]; /* [bh][bw][comps] */
134 for(j = 0; j < bh; ++j) {
135 for(i = 0; i < bw; ++i) {
136 tmp[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
137 }
138 }
139 u_format_unsigned_encode_rgtc_ubyte(dst, tmp, 4, 4);
140 dst += bytes_per_block;
141 }
142 dst_row += dst_stride / sizeof(*dst_row);
143 }
144 }
145
146 void
147 util_format_rgtc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
148 {
149 uint8_t tmp_r;
150 u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
151 dst[0] = ubyte_to_float(tmp_r);
152 dst[1] = 0.0;
153 dst[2] = 0.0;
154 dst[3] = 1.0;
155 }
156
157 void
158 util_format_rgtc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
159 {
160 fprintf(stderr,"%s\n", __func__);
161 }
162
163 void
164 util_format_rgtc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
165 {
166 fprintf(stderr,"%s\n", __func__);
167 }
168
169 void
170 util_format_rgtc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
171 {
172 fprintf(stderr,"%s\n", __func__);
173 }
174
175 void
176 util_format_rgtc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
177 {
178 const unsigned bw = 4, bh = 4, bytes_per_block = 8;
179 unsigned x, y, i, j;
180
181 for(y = 0; y < height; y += bh) {
182 int8_t *dst = (int8_t *)dst_row;
183 for(x = 0; x < width; x += bw) {
184 int8_t tmp[4][4]; /* [bh][bw][comps] */
185 for(j = 0; j < bh; ++j) {
186 for(i = 0; i < bw; ++i) {
187 tmp[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
188 }
189 }
190 u_format_signed_encode_rgtc_ubyte(dst, tmp, 4, 4);
191 dst += bytes_per_block;
192 }
193 dst_row += dst_stride / sizeof(*dst_row);
194 }
195 }
196
197 void
198 util_format_rgtc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
199 {
200 unsigned x, y, i, j;
201 int block_size = 8;
202 for(y = 0; y < height; y += 4) {
203 const int8_t *src = (int8_t *)src_row;
204 for(x = 0; x < width; x += 4) {
205 for(j = 0; j < 4; ++j) {
206 for(i = 0; i < 4; ++i) {
207 float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
208 int8_t tmp_r;
209 u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
210 dst[0] = byte_to_float_tex(tmp_r);
211 dst[1] = 0.0;
212 dst[2] = 0.0;
213 dst[3] = 1.0;
214 }
215 }
216 src += block_size;
217 }
218 src_row += src_stride;
219 }
220 }
221
222 void
223 util_format_rgtc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
224 {
225 int8_t tmp_r;
226 u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1);
227 dst[0] = byte_to_float_tex(tmp_r);
228 dst[1] = 0.0;
229 dst[2] = 0.0;
230 dst[3] = 1.0;
231 }
232
233
234 void
235 util_format_rgtc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
236 {
237 u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
238 u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
239 dst[2] = 0;
240 dst[3] = 255;
241 }
242
243 void
244 util_format_rgtc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
245 {
246 const unsigned bw = 4, bh = 4, comps = 4;
247 unsigned x, y, i, j;
248 unsigned block_size = 16;
249
250 for(y = 0; y < height; y += bh) {
251 const uint8_t *src = src_row;
252 for(x = 0; x < width; x += bw) {
253 for(j = 0; j < bh; ++j) {
254 for(i = 0; i < bw; ++i) {
255 uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
256 u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
257 u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
258 dst[2] = 0;
259 dst[3] = 255;
260 }
261 }
262 src += block_size;
263 }
264 src_row += src_stride;
265 }
266 }
267
268 void
269 util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
270 {
271 const unsigned bw = 4, bh = 4, bytes_per_block = 16;
272 unsigned x, y, i, j;
273
274 for(y = 0; y < height; y += bh) {
275 uint8_t *dst = dst_row;
276 for(x = 0; x < width; x += bw) {
277 uint8_t tmp_r[4][4]; /* [bh][bw] */
278 uint8_t tmp_g[4][4]; /* [bh][bw] */
279 for(j = 0; j < bh; ++j) {
280 for(i = 0; i < bw; ++i) {
281 tmp_r[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4];
282 tmp_g[j][i] = src_row[((y + j)*src_stride/sizeof(*src_row) + (x + i)*4) + 1];
283 }
284 }
285 u_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
286 u_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
287 dst += bytes_per_block;
288 }
289 dst_row += dst_stride / sizeof(*dst_row);
290 }
291 }
292
293 void
294 util_format_rxtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off)
295 {
296 const unsigned bw = 4, bh = 4, bytes_per_block = 16;
297 unsigned x, y, i, j;
298
299 for(y = 0; y < height; y += bh) {
300 uint8_t *dst = dst_row;
301 for(x = 0; x < width; x += bw) {
302 uint8_t tmp_r[4][4]; /* [bh][bw][comps] */
303 uint8_t tmp_g[4][4]; /* [bh][bw][comps] */
304 for(j = 0; j < bh; ++j) {
305 for(i = 0; i < bw; ++i) {
306 tmp_r[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
307 tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
308 }
309 }
310 u_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
311 u_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
312 dst += bytes_per_block;
313 }
314 dst_row += dst_stride / sizeof(*dst_row);
315 }
316 }
317
318 void
319 util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
320 {
321 util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1);
322 }
323
324 void
325 util_format_rgtc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
326 {
327 unsigned x, y, i, j;
328 int block_size = 16;
329 for(y = 0; y < height; y += 4) {
330 const uint8_t *src = src_row;
331 for(x = 0; x < width; x += 4) {
332 for(j = 0; j < 4; ++j) {
333 for(i = 0; i < 4; ++i) {
334 float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
335 uint8_t tmp_r, tmp_g;
336 u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
337 u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
338 dst[0] = ubyte_to_float(tmp_r);
339 dst[1] = ubyte_to_float(tmp_g);
340 dst[2] = 0.0;
341 dst[3] = 1.0;
342 }
343 }
344 src += block_size;
345 }
346 src_row += src_stride;
347 }
348 }
349
350 void
351 util_format_rgtc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
352 {
353 uint8_t tmp_r, tmp_g;
354 u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
355 u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
356 dst[0] = ubyte_to_float(tmp_r);
357 dst[1] = ubyte_to_float(tmp_g);
358 dst[2] = 0.0;
359 dst[3] = 1.0;
360 }
361
362
363 void
364 util_format_rgtc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
365 {
366 fprintf(stderr,"%s\n", __func__);
367 }
368
369 void
370 util_format_rgtc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
371 {
372 fprintf(stderr,"%s\n", __func__);
373 }
374
375 void
376 util_format_rgtc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
377 {
378 fprintf(stderr,"%s\n", __func__);
379 }
380
381 void
382 util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
383 {
384 unsigned x, y, i, j;
385 int block_size = 16;
386 for(y = 0; y < height; y += 4) {
387 const int8_t *src = (int8_t *)src_row;
388 for(x = 0; x < width; x += 4) {
389 for(j = 0; j < 4; ++j) {
390 for(i = 0; i < 4; ++i) {
391 float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
392 int8_t tmp_r, tmp_g;
393 u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
394 u_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
395 dst[0] = byte_to_float_tex(tmp_r);
396 dst[1] = byte_to_float_tex(tmp_g);
397 dst[2] = 0.0;
398 dst[3] = 1.0;
399 }
400 }
401 src += block_size;
402 }
403 src_row += src_stride;
404 }
405 }
406
407 void
408 util_format_rxtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off)
409 {
410 const unsigned bw = 4, bh = 4, bytes_per_block = 16;
411 unsigned x, y, i, j;
412
413 for(y = 0; y < height; y += bh) {
414 int8_t *dst = (int8_t *)dst_row;
415 for(x = 0; x < width; x += bw) {
416 int8_t tmp_r[4][4]; /* [bh][bw][comps] */
417 int8_t tmp_g[4][4]; /* [bh][bw][comps] */
418 for(j = 0; j < bh; ++j) {
419 for(i = 0; i < bw; ++i) {
420 tmp_r[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
421 tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
422 }
423 }
424 u_format_signed_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
425 u_format_signed_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
426 dst += bytes_per_block;
427 }
428 dst_row += dst_stride / sizeof(*dst_row);
429 }
430 }
431
432 void
433 util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
434 {
435 util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1);
436 }
437
438 void
439 util_format_rgtc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
440 {
441 int8_t tmp_r, tmp_g;
442 u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2);
443 u_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2);
444 dst[0] = byte_to_float_tex(tmp_r);
445 dst[1] = byte_to_float_tex(tmp_g);
446 dst[2] = 0.0;
447 dst[3] = 1.0;
448 }
449
450
451 #define TAG(x) u_format_unsigned_##x
452 #define TYPE uint8_t
453 #define T_MIN 0
454 #define T_MAX 255
455
456 #include "../../../mesa/main/texcompress_rgtc_tmp.h"
457
458 #undef TYPE
459 #undef TAG
460 #undef T_MIN
461 #undef T_MAX
462
463
464 #define TAG(x) u_format_signed_##x
465 #define TYPE int8_t
466 #define T_MIN (int8_t)-128
467 #define T_MAX (int8_t)127
468
469 #include "../../../mesa/main/texcompress_rgtc_tmp.h"
470
471 #undef TYPE
472 #undef TAG
473 #undef T_MIN
474 #undef T_MAX