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