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 "util/format/u_format.h"
27 #include "util/format/u_format_rgtc.h"
28 #include "util/u_math.h"
29 #include "util/rgtc.h"
30 
31 void
util_format_rgtc1_unorm_fetch_rgba_8unorm(uint8_t * restrict dst,const uint8_t * restrict src,unsigned i,unsigned j)32 util_format_rgtc1_unorm_fetch_rgba_8unorm(uint8_t *restrict dst, const uint8_t *restrict src, unsigned i, unsigned j)
33 {
34    util_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
35    dst[1] = 0;
36    dst[2] = 0;
37    dst[3] = 255;
38 }
39 
40 void
util_format_rgtc1_unorm_unpack_r_8unorm(uint8_t * restrict dst_row,unsigned dst_stride,const uint8_t * restrict src_row,unsigned src_stride,unsigned width,unsigned height)41 util_format_rgtc1_unorm_unpack_r_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, const uint8_t *restrict src_row, unsigned src_stride, unsigned width, unsigned height)
42 {
43    const unsigned bw = 4, bh = 4, comps = 1;
44    unsigned x, y, i, j;
45    unsigned block_size = 8;
46 
47    for(y = 0; y < height; y += bh) {
48       const uint8_t *src = src_row;
49       const unsigned h = MIN2(height - y, bh);
50       for(x = 0; x < width; x += bw) {
51          const unsigned w = MIN2(width - x, bw);
52          for(j = 0; j < h; ++j) {
53             for(i = 0; i < w; ++i) {
54                uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
55                util_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
56             }
57          }
58          src += block_size;
59       }
60       src_row += src_stride;
61    }
62 }
63 
64 void
util_format_rgtc1_unorm_unpack_rgba_8unorm(uint8_t * restrict dst_row,unsigned dst_stride,const uint8_t * restrict src_row,unsigned src_stride,unsigned width,unsigned height)65 util_format_rgtc1_unorm_unpack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, const uint8_t *restrict src_row, unsigned src_stride, unsigned width, unsigned height)
66 {
67    const unsigned bw = 4, bh = 4, comps = 4;
68    unsigned x, y, i, j;
69    unsigned block_size = 8;
70 
71    for(y = 0; y < height; y += bh) {
72       const uint8_t *src = src_row;
73       const unsigned h = MIN2(height - y, bh);
74       for(x = 0; x < width; x += bw) {
75          const unsigned w = MIN2(width - x, bw);
76          for(j = 0; j < h; ++j) {
77             for(i = 0; i < w; ++i) {
78                uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
79                util_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
80                dst[1] = 0;
81                dst[2] = 0;
82                dst[3] = 255;
83             }
84          }
85          src += block_size;
86       }
87       src_row += src_stride;
88    }
89 }
90 
91 void
util_format_rgtc1_unorm_pack_rgba_8unorm(uint8_t * restrict dst_row,unsigned dst_stride,const uint8_t * restrict src_row,unsigned src_stride,unsigned width,unsigned height)92 util_format_rgtc1_unorm_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, const uint8_t *restrict src_row,
93 					 unsigned src_stride, unsigned width, unsigned height)
94 {
95    const unsigned bw = 4, bh = 4, bytes_per_block = 8;
96    unsigned x, y, i, j;
97 
98    for(y = 0; y < height; y += bh) {
99       uint8_t *dst = dst_row;
100       for(x = 0; x < width; x += bw) {
101          uint8_t tmp[4][4];  /* [bh][bw][comps] */
102          for(j = 0; j < bh; ++j) {
103             for(i = 0; i < bw; ++i) {
104                tmp[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4];
105             }
106          }
107          util_format_unsigned_encode_rgtc_ubyte(dst, tmp, 4, 4);
108          dst += bytes_per_block;
109       }
110       dst_row += dst_stride / sizeof(*dst_row);
111    }
112 }
113 
114 void
util_format_rgtc1_unorm_unpack_rgba_float(void * restrict dst_row,unsigned dst_stride,const uint8_t * restrict src_row,unsigned src_stride,unsigned width,unsigned height)115 util_format_rgtc1_unorm_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride, const uint8_t *restrict src_row, unsigned src_stride, unsigned width, unsigned height)
116 {
117    unsigned x, y, i, j;
118    int block_size = 8;
119    for(y = 0; y < height; y += 4) {
120       const uint8_t *src = src_row;
121       const unsigned h = MIN2(height - y, 4);
122       for(x = 0; x < width; x += 4) {
123          const unsigned w = MIN2(width - x, 4);
124          for(j = 0; j < h; ++j) {
125             for(i = 0; i < w; ++i) {
126                float *dst = (float *)((uint8_t *)dst_row + (y + j)*dst_stride + (x + i)*16);
127                uint8_t tmp_r;
128                util_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
129                dst[0] = ubyte_to_float(tmp_r);
130                dst[1] = 0.0;
131                dst[2] = 0.0;
132                dst[3] = 1.0;
133             }
134          }
135          src += block_size;
136       }
137       src_row += src_stride;
138    }
139 }
140 
141 void
util_format_rgtc1_unorm_pack_rgba_float(uint8_t * restrict dst_row,unsigned dst_stride,const float * restrict src_row,unsigned src_stride,unsigned width,unsigned height)142 util_format_rgtc1_unorm_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, const float *restrict src_row, unsigned src_stride, unsigned width, unsigned height)
143 {
144    const unsigned bw = 4, bh = 4, bytes_per_block = 8;
145    unsigned x, y, i, j;
146 
147    for(y = 0; y < height; y += bh) {
148       uint8_t *dst = dst_row;
149       for(x = 0; x < width; x += bw) {
150          uint8_t tmp[4][4];  /* [bh][bw][comps] */
151          for(j = 0; j < bh; ++j) {
152             for(i = 0; i < bw; ++i) {
153                tmp[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
154             }
155          }
156          util_format_unsigned_encode_rgtc_ubyte(dst, tmp, 4, 4);
157          dst += bytes_per_block;
158       }
159       dst_row += dst_stride / sizeof(*dst_row);
160    }
161 }
162 
163 void
util_format_rgtc1_unorm_fetch_rgba(void * restrict in_dst,const uint8_t * restrict src,unsigned i,unsigned j)164 util_format_rgtc1_unorm_fetch_rgba(void *restrict in_dst, const uint8_t *restrict src, unsigned i, unsigned j)
165 {
166    float *dst = in_dst;
167    uint8_t tmp_r;
168    util_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
169    dst[0] = ubyte_to_float(tmp_r);
170    dst[1] = 0.0;
171    dst[2] = 0.0;
172    dst[3] = 1.0;
173 }
174 
175 void
util_format_rgtc1_snorm_fetch_rgba_8unorm(UNUSED uint8_t * restrict dst,UNUSED const uint8_t * restrict src,UNUSED unsigned i,UNUSED unsigned j)176 util_format_rgtc1_snorm_fetch_rgba_8unorm(UNUSED uint8_t *restrict dst, UNUSED const uint8_t *restrict src,
177                                           UNUSED unsigned i, UNUSED unsigned j)
178 {
179    fprintf(stderr,"%s\n", __func__);
180 }
181 
182 void
util_format_rgtc1_snorm_unpack_rgba_8unorm(UNUSED uint8_t * restrict dst_row,UNUSED unsigned dst_stride,UNUSED const uint8_t * restrict src_row,UNUSED unsigned src_stride,UNUSED unsigned width,UNUSED unsigned height)183 util_format_rgtc1_snorm_unpack_rgba_8unorm(UNUSED uint8_t *restrict dst_row, UNUSED unsigned dst_stride,
184                                            UNUSED const uint8_t *restrict src_row, UNUSED unsigned src_stride,
185                                            UNUSED unsigned width, UNUSED unsigned height)
186 {
187    fprintf(stderr,"%s\n", __func__);
188 }
189 
190 void
util_format_rgtc1_snorm_unpack_r_8snorm(int8_t * restrict dst_row,unsigned dst_stride,const uint8_t * restrict src_row,unsigned src_stride,unsigned width,unsigned height)191 util_format_rgtc1_snorm_unpack_r_8snorm(int8_t *restrict dst_row, unsigned dst_stride,
192                                         const uint8_t *restrict src_row, unsigned src_stride,
193                                         unsigned width, unsigned height)
194 {
195    const unsigned bw = 4, bh = 4, comps = 1;
196    unsigned x, y, i, j;
197    unsigned block_size = 8;
198 
199    for(y = 0; y < height; y += bh) {
200       const uint8_t *src = src_row;
201       const unsigned h = MIN2(height - y, bh);
202       for(x = 0; x < width; x += bw) {
203          const unsigned w = MIN2(width - x, bw);
204          for(j = 0; j < h; ++j) {
205             for(i = 0; i < w; ++i) {
206                int8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
207                util_format_signed_fetch_texel_rgtc(0, (const int8_t *)src, i, j, dst, 1);
208             }
209          }
210          src += block_size;
211       }
212       src_row += src_stride;
213    }
214 }
215 
216 void
util_format_rgtc1_snorm_pack_rgba_8unorm(UNUSED uint8_t * restrict dst_row,UNUSED unsigned dst_stride,UNUSED const uint8_t * restrict src_row,UNUSED unsigned src_stride,UNUSED unsigned width,UNUSED unsigned height)217 util_format_rgtc1_snorm_pack_rgba_8unorm(UNUSED uint8_t *restrict dst_row, UNUSED unsigned dst_stride,
218                                          UNUSED const uint8_t *restrict src_row, UNUSED unsigned src_stride,
219                                          UNUSED unsigned width, UNUSED unsigned height)
220 {
221    fprintf(stderr,"%s\n", __func__);
222 }
223 
224 void
util_format_rgtc1_snorm_pack_rgba_float(uint8_t * restrict dst_row,unsigned dst_stride,const float * restrict src_row,unsigned src_stride,unsigned width,unsigned height)225 util_format_rgtc1_snorm_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, const float *restrict src_row, unsigned src_stride, unsigned width, unsigned height)
226 {
227    const unsigned bw = 4, bh = 4, bytes_per_block = 8;
228    unsigned x, y, i, j;
229 
230    for(y = 0; y < height; y += bh) {
231       int8_t *dst = (int8_t *)dst_row;
232       for(x = 0; x < width; x += bw) {
233          int8_t tmp[4][4];  /* [bh][bw][comps] */
234          for(j = 0; j < bh; ++j) {
235             for(i = 0; i < bw; ++i) {
236                tmp[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
237             }
238          }
239          util_format_signed_encode_rgtc_ubyte(dst, tmp, 4, 4);
240          dst += bytes_per_block;
241       }
242       dst_row += dst_stride / sizeof(*dst_row);
243    }
244 }
245 
246 void
util_format_rgtc1_snorm_unpack_rgba_float(void * restrict dst_row,unsigned dst_stride,const uint8_t * restrict src_row,unsigned src_stride,unsigned width,unsigned height)247 util_format_rgtc1_snorm_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride, const uint8_t *restrict src_row, unsigned src_stride, unsigned width, unsigned height)
248 {
249    unsigned x, y, i, j;
250    int block_size = 8;
251    for(y = 0; y < height; y += 4) {
252       const int8_t *src = (int8_t *)src_row;
253       const unsigned h = MIN2(height - y, 4);
254       for(x = 0; x < width; x += 4) {
255          const unsigned w = MIN2(width - x, 4);
256          for(j = 0; j < h; ++j) {
257             for(i = 0; i < w; ++i) {
258                float *dst = (float *)((uint8_t *)dst_row + (y + j)*dst_stride + (x + i)*16);
259                int8_t tmp_r;
260                util_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
261                dst[0] = byte_to_float_tex(tmp_r);
262                dst[1] = 0.0;
263                dst[2] = 0.0;
264                dst[3] = 1.0;
265             }
266          }
267          src += block_size;
268       }
269       src_row += src_stride;
270    }
271 }
272 
273 void
util_format_rgtc1_snorm_fetch_rgba(void * restrict in_dst,const uint8_t * restrict src,unsigned i,unsigned j)274 util_format_rgtc1_snorm_fetch_rgba(void *restrict in_dst, const uint8_t *restrict src, unsigned i, unsigned j)
275 {
276    float *dst = in_dst;
277    int8_t tmp_r;
278    util_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1);
279    dst[0] = byte_to_float_tex(tmp_r);
280    dst[1] = 0.0;
281    dst[2] = 0.0;
282    dst[3] = 1.0;
283 }
284 
285 
286 void
util_format_rgtc2_unorm_fetch_rgba_8unorm(uint8_t * restrict dst,const uint8_t * restrict src,unsigned i,unsigned j)287 util_format_rgtc2_unorm_fetch_rgba_8unorm(uint8_t *restrict dst, const uint8_t *restrict src, unsigned i, unsigned j)
288 {
289    util_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
290    util_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
291    dst[2] = 0;
292    dst[3] = 255;
293 }
294 
295 void
util_format_rgtc2_unorm_unpack_rg_8unorm(uint8_t * restrict dst_row,unsigned dst_stride,const uint8_t * restrict src_row,unsigned src_stride,unsigned width,unsigned height)296 util_format_rgtc2_unorm_unpack_rg_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, const uint8_t *restrict src_row, unsigned src_stride, unsigned width, unsigned height)
297 {
298    const unsigned bw = 4, bh = 4, comps = 2;
299    unsigned x, y, i, j;
300    unsigned block_size = 16;
301 
302    for(y = 0; y < height; y += bh) {
303       const uint8_t *src = src_row;
304       const unsigned h = MIN2(height - y, bh);
305       for(x = 0; x < width; x += bw) {
306          const unsigned w = MIN2(width - x, bw);
307          for(j = 0; j < h; ++j) {
308             for(i = 0; i < w; ++i) {
309                uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
310                util_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
311                util_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
312             }
313          }
314          src += block_size;
315       }
316       src_row += src_stride;
317    }
318 }
319 
320 void
util_format_rgtc2_unorm_unpack_rgba_8unorm(uint8_t * restrict dst_row,unsigned dst_stride,const uint8_t * restrict src_row,unsigned src_stride,unsigned width,unsigned height)321 util_format_rgtc2_unorm_unpack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, const uint8_t *restrict src_row, unsigned src_stride, unsigned width, unsigned height)
322 {
323    const unsigned bw = 4, bh = 4, comps = 4;
324    unsigned x, y, i, j;
325    unsigned block_size = 16;
326 
327    for(y = 0; y < height; y += bh) {
328       const uint8_t *src = src_row;
329       const unsigned h = MIN2(height - y, bh);
330       for(x = 0; x < width; x += bw) {
331          const unsigned w = MIN2(width - x, bw);
332          for(j = 0; j < h; ++j) {
333             for(i = 0; i < w; ++i) {
334                uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
335                util_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
336                util_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
337                dst[2] = 0;
338                dst[3] = 255;
339             }
340          }
341          src += block_size;
342       }
343       src_row += src_stride;
344    }
345 }
346 
347 void
util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t * restrict dst_row,unsigned dst_stride,const uint8_t * restrict src_row,unsigned src_stride,unsigned width,unsigned height)348 util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, const uint8_t *restrict src_row, unsigned src_stride, unsigned width, unsigned height)
349 {
350    const unsigned bw = 4, bh = 4, bytes_per_block = 16;
351    unsigned x, y, i, j;
352 
353    for(y = 0; y < height; y += bh) {
354       uint8_t *dst = dst_row;
355       for(x = 0; x < width; x += bw) {
356          uint8_t tmp_r[4][4];  /* [bh][bw] */
357          uint8_t tmp_g[4][4];  /* [bh][bw] */
358          for(j = 0; j < bh; ++j) {
359             for(i = 0; i < bw; ++i) {
360                tmp_r[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4];
361                tmp_g[j][i] = src_row[((y + j)*src_stride/sizeof(*src_row) + (x + i)*4) + 1];
362             }
363          }
364          util_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
365          util_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
366          dst += bytes_per_block;
367       }
368       dst_row += dst_stride / sizeof(*dst_row);
369    }
370 }
371 
372 void
util_format_rxtc2_unorm_pack_rgba_float(uint8_t * restrict dst_row,unsigned dst_stride,const float * restrict src_row,unsigned src_stride,unsigned width,unsigned height,unsigned chan2off)373 util_format_rxtc2_unorm_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, const float *restrict src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off)
374 {
375    const unsigned bw = 4, bh = 4, bytes_per_block = 16;
376    unsigned x, y, i, j;
377 
378    for(y = 0; y < height; y += bh) {
379       uint8_t *dst = dst_row;
380       for(x = 0; x < width; x += bw) {
381          uint8_t tmp_r[4][4];  /* [bh][bw][comps] */
382          uint8_t tmp_g[4][4];  /* [bh][bw][comps] */
383          for(j = 0; j < bh; ++j) {
384             for(i = 0; i < bw; ++i) {
385                tmp_r[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
386                tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
387             }
388          }
389          util_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
390          util_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
391          dst += bytes_per_block;
392       }
393       dst_row += dst_stride / sizeof(*dst_row);
394    }
395 }
396 
397 void
util_format_rgtc2_unorm_pack_rgba_float(uint8_t * restrict dst_row,unsigned dst_stride,const float * restrict src_row,unsigned src_stride,unsigned width,unsigned height)398 util_format_rgtc2_unorm_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, const float *restrict src_row, unsigned src_stride, unsigned width, unsigned height)
399 {
400    util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1);
401 }
402 
403 void
util_format_rgtc2_unorm_unpack_rgba_float(void * restrict dst_row,unsigned dst_stride,const uint8_t * restrict src_row,unsigned src_stride,unsigned width,unsigned height)404 util_format_rgtc2_unorm_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride, const uint8_t *restrict src_row, unsigned src_stride, unsigned width, unsigned height)
405 {
406    unsigned x, y, i, j;
407    int block_size = 16;
408    for(y = 0; y < height; y += 4) {
409       const uint8_t *src = src_row;
410       const unsigned h = MIN2(height - y, 4);
411       for(x = 0; x < width; x += 4) {
412          const unsigned w = MIN2(width - x, 4);
413          for(j = 0; j < h; ++j) {
414             for(i = 0; i < w; ++i) {
415                float *dst = (float *)((uint8_t *)dst_row + (y + j)*dst_stride + (x + i)*16);
416                uint8_t tmp_r, tmp_g;
417                util_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
418                util_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
419                dst[0] = ubyte_to_float(tmp_r);
420                dst[1] = ubyte_to_float(tmp_g);
421                dst[2] = 0.0;
422                dst[3] = 1.0;
423             }
424          }
425          src += block_size;
426       }
427       src_row += src_stride;
428    }
429 }
430 
431 void
util_format_rgtc2_unorm_fetch_rgba(void * restrict in_dst,const uint8_t * restrict src,unsigned i,unsigned j)432 util_format_rgtc2_unorm_fetch_rgba(void *restrict in_dst, const uint8_t *restrict src, unsigned i, unsigned j)
433 {
434    float *dst = in_dst;
435    uint8_t tmp_r, tmp_g;
436    util_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
437    util_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
438    dst[0] = ubyte_to_float(tmp_r);
439    dst[1] = ubyte_to_float(tmp_g);
440    dst[2] = 0.0;
441    dst[3] = 1.0;
442 }
443 
444 
445 void
util_format_rgtc2_snorm_fetch_rgba_8unorm(UNUSED uint8_t * restrict dst,UNUSED const uint8_t * restrict src,UNUSED unsigned i,UNUSED unsigned j)446 util_format_rgtc2_snorm_fetch_rgba_8unorm(UNUSED uint8_t *restrict dst, UNUSED const uint8_t *restrict src,
447                                           UNUSED unsigned i, UNUSED unsigned j)
448 {
449    fprintf(stderr,"%s\n", __func__);
450 }
451 
452 void
util_format_rgtc2_snorm_unpack_rgba_8unorm(UNUSED uint8_t * restrict dst_row,UNUSED unsigned dst_stride,UNUSED const uint8_t * restrict src_row,UNUSED unsigned src_stride,UNUSED unsigned width,UNUSED unsigned height)453 util_format_rgtc2_snorm_unpack_rgba_8unorm(UNUSED uint8_t *restrict dst_row, UNUSED unsigned dst_stride,
454                                            UNUSED const uint8_t *restrict src_row, UNUSED unsigned src_stride,
455                                            UNUSED unsigned width, UNUSED unsigned height)
456 {
457    fprintf(stderr,"%s\n", __func__);
458 }
459 
460 void
util_format_rgtc2_snorm_unpack_rg_8snorm(int8_t * restrict dst_row,unsigned dst_stride,const uint8_t * restrict src_row,unsigned src_stride,unsigned width,unsigned height)461 util_format_rgtc2_snorm_unpack_rg_8snorm(int8_t *restrict dst_row, unsigned dst_stride,
462                                          const uint8_t *restrict src_row, unsigned src_stride,
463                                          unsigned width, unsigned height)
464 {
465    const unsigned bw = 4, bh = 4, comps = 2;
466    unsigned x, y, i, j;
467    unsigned block_size = 16;
468 
469    for(y = 0; y < height; y += bh) {
470       const uint8_t *src = src_row;
471       const unsigned h = MIN2(height - y, bh);
472       for(x = 0; x < width; x += bw) {
473          const unsigned w = MIN2(width - x, bw);
474          for(j = 0; j < h; ++j) {
475             for(i = 0; i < w; ++i) {
476                int8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
477                util_format_signed_fetch_texel_rgtc(0, (const int8_t *)src, i, j, (int8_t *)dst, 2);
478                util_format_signed_fetch_texel_rgtc(0, (const int8_t *)src + 8, i, j, (int8_t *)dst + 1, 2);
479             }
480          }
481          src += block_size;
482       }
483       src_row += src_stride;
484    }
485 }
486 
487 void
util_format_rgtc2_snorm_pack_rgba_8unorm(UNUSED uint8_t * restrict dst_row,UNUSED unsigned dst_stride,UNUSED const uint8_t * restrict src_row,UNUSED unsigned src_stride,UNUSED unsigned width,UNUSED unsigned height)488 util_format_rgtc2_snorm_pack_rgba_8unorm(UNUSED uint8_t *restrict dst_row, UNUSED unsigned dst_stride,
489                                          UNUSED const uint8_t *restrict src_row, UNUSED unsigned src_stride,
490                                          UNUSED unsigned width, UNUSED unsigned height)
491 {
492    fprintf(stderr,"%s\n", __func__);
493 }
494 
495 void
util_format_rgtc2_snorm_unpack_rgba_float(void * restrict dst_row,unsigned dst_stride,const uint8_t * restrict src_row,unsigned src_stride,unsigned width,unsigned height)496 util_format_rgtc2_snorm_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride, const uint8_t *restrict src_row, unsigned src_stride, unsigned width, unsigned height)
497 {
498    unsigned x, y, i, j;
499    int block_size = 16;
500    for(y = 0; y < height; y += 4) {
501       const int8_t *src = (int8_t *)src_row;
502       const unsigned h = MIN2(height - y, 4);
503       for(x = 0; x < width; x += 4) {
504          const unsigned w = MIN2(width - x, 4);
505          for(j = 0; j < h; ++j) {
506             for(i = 0; i < w; ++i) {
507                float *dst = (float *)((uint8_t *)dst_row + (y + j)*dst_stride + (x + i)*16);
508                int8_t tmp_r, tmp_g;
509                util_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
510                util_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
511                dst[0] = byte_to_float_tex(tmp_r);
512                dst[1] = byte_to_float_tex(tmp_g);
513                dst[2] = 0.0;
514                dst[3] = 1.0;
515             }
516          }
517          src += block_size;
518       }
519       src_row += src_stride;
520    }
521 }
522 
523 void
util_format_rxtc2_snorm_pack_rgba_float(uint8_t * restrict dst_row,unsigned dst_stride,const float * restrict src_row,unsigned src_stride,unsigned width,unsigned height,unsigned chan2off)524 util_format_rxtc2_snorm_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, const float *restrict src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off)
525 {
526    const unsigned bw = 4, bh = 4, bytes_per_block = 16;
527    unsigned x, y, i, j;
528 
529    for(y = 0; y < height; y += bh) {
530       int8_t *dst = (int8_t *)dst_row;
531       for(x = 0; x < width; x += bw) {
532          int8_t tmp_r[4][4];  /* [bh][bw][comps] */
533          int8_t tmp_g[4][4];  /* [bh][bw][comps] */
534          for(j = 0; j < bh; ++j) {
535             for(i = 0; i < bw; ++i) {
536                tmp_r[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
537                tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]);
538             }
539          }
540          util_format_signed_encode_rgtc_ubyte(dst, tmp_r, 4, 4);
541          util_format_signed_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4);
542          dst += bytes_per_block;
543       }
544       dst_row += dst_stride / sizeof(*dst_row);
545    }
546 }
547 
548 void
util_format_rgtc2_snorm_pack_rgba_float(uint8_t * restrict dst_row,unsigned dst_stride,const float * restrict src_row,unsigned src_stride,unsigned width,unsigned height)549 util_format_rgtc2_snorm_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, const float *restrict src_row, unsigned src_stride, unsigned width, unsigned height)
550 {
551    util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1);
552 }
553 
554 void
util_format_rgtc2_snorm_fetch_rgba(void * restrict in_dst,const uint8_t * restrict src,unsigned i,unsigned j)555 util_format_rgtc2_snorm_fetch_rgba(void *restrict in_dst, const uint8_t *restrict src, unsigned i, unsigned j)
556 {
557    float *dst = in_dst;
558    int8_t tmp_r, tmp_g;
559    util_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2);
560    util_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2);
561    dst[0] = byte_to_float_tex(tmp_r);
562    dst[1] = byte_to_float_tex(tmp_g);
563    dst[2] = 0.0;
564    dst[3] = 1.0;
565 }
566 
567