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