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
33util_format_dxtn_fetch_t util_format_dxt1_rgb_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgb_dxt1;
34util_format_dxtn_fetch_t util_format_dxt1_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt1;
35util_format_dxtn_fetch_t util_format_dxt3_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt3;
36util_format_dxtn_fetch_t util_format_dxt5_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt5;
37
38util_format_dxtn_pack_t util_format_dxtn_pack = (util_format_dxtn_pack_t)tx_compress_dxtn;
39
40
41/*
42 * Pixel fetch.
43 */
44
45void
46util_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
51void
52util_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
57void
58util_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
63void
64util_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
69void
70util_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
81void
82util_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
93void
94util_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
105void
106util_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
122static inline void
123util_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
151void
152util_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
163void
164util_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
175void
176util_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
187void
188util_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
199static inline void
200util_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
234void
235util_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
246void
247util_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
258void
259util_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
270void
271util_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
287static inline void
288util_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
325void
326util_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
335void
336util_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
345void
346util_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
355void
356util_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
365static inline void
366util_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
401void
402util_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
411void
412util_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
421void
422util_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
431void
432util_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
446void
447util_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
457void
458util_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
468void
469util_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
479void
480util_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
490void
491util_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
502void
503util_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
514void
515util_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
526void
527util_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
538void
539util_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
548void
549util_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
558void
559util_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
568void
569util_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
578void
579util_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
588void
589util_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
598void
599util_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
608void
609util_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
618void
619util_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
626void
627util_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
634void
635util_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
642void
643util_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
650void
651util_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
658void
659util_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
666void
667util_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
674void
675util_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