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