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_bptc.h"
28#include "u_format_pack.h"
29#include "util/format_srgb.h"
30#include "util/u_math.h"
31
32#define BPTC_BLOCK_DECODE
33#include "../../mesa/main/texcompress_bptc_tmp.h"
34
35void
36util_format_bptc_rgba_unorm_unpack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride,
37                                               const uint8_t *restrict src_row, unsigned src_stride,
38                                               unsigned width, unsigned height)
39{
40  decompress_rgba_unorm(width, height,
41                        src_row, src_stride,
42                        dst_row, dst_stride);
43}
44
45void
46util_format_bptc_rgba_unorm_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride,
47                                             const uint8_t *restrict src_row, unsigned src_stride,
48                                             unsigned width, unsigned height)
49{
50   compress_rgba_unorm(width, height,
51                       src_row, src_stride,
52                       dst_row, dst_stride);
53}
54
55void
56util_format_bptc_rgba_unorm_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride,
57                                              const uint8_t *restrict src_row, unsigned src_stride,
58                                              unsigned width, unsigned height)
59{
60   uint8_t *temp_block;
61   temp_block = malloc(width * height * 4 * sizeof(uint8_t));
62   decompress_rgba_unorm(width, height,
63                         src_row, src_stride,
64                         temp_block, width * 4 * sizeof(uint8_t));
65   /* Direct call to row unpack instead of util_format_rgba_unpack_rect()
66    * to avoid table lookup that would pull in all unpack symbols.
67    */
68   for (int y = 0; y < height; y++) {
69      util_format_r8g8b8a8_unorm_unpack_rgba_float((char *)dst_row + dst_stride * y,
70                                                    temp_block + 4 * width * y,
71                                                    width);
72   }
73   free((void *) temp_block);
74}
75
76void
77util_format_bptc_rgba_unorm_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride,
78                                            const float *restrict src_row, unsigned src_stride,
79                                            unsigned width, unsigned height)
80{
81   uint8_t *temp_block;
82   temp_block = malloc(width * height * 4 * sizeof(uint8_t));
83   /* Direct call to row unpack instead of util_format_rgba_unpack_rect()
84    * to avoid table lookup that would pull in all unpack symbols.
85    */
86   for (int y = 0; y < height; y++) {
87      util_format_r32g32b32a32_float_unpack_rgba_8unorm(
88                        temp_block + 4 * width * y,
89                        (uint8_t *)src_row + src_stride * y,
90                        width);
91   }
92   compress_rgba_unorm(width, height,
93                       temp_block, width * 4 * sizeof(uint8_t),
94                       dst_row, dst_stride);
95   free((void *) temp_block);
96}
97
98void
99util_format_bptc_rgba_unorm_fetch_rgba(void *restrict dst, const uint8_t *restrict src,
100                                             unsigned width, unsigned height)
101{
102   uint8_t temp_block[4];
103
104   fetch_rgba_unorm_from_block(src + ((width * sizeof(uint8_t)) * (height / 4) + (width / 4)) * 16,
105                               temp_block, (width % 4) + (height % 4) * 4);
106
107   util_format_read_4(PIPE_FORMAT_R8G8B8A8_UNORM,
108                      dst, 4 * sizeof(float),
109                      temp_block, 4 * sizeof(uint8_t),
110                      0, 0, 1, 1);
111}
112
113void
114util_format_bptc_srgba_unpack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride,
115                                          const uint8_t *restrict src_row, unsigned src_stride,
116                                          unsigned width, unsigned height)
117{
118   decompress_rgba_unorm(width, height,
119                         src_row, src_stride,
120                         dst_row, dst_stride);
121}
122
123void
124util_format_bptc_srgba_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride,
125                                        const uint8_t *restrict src_row, unsigned src_stride,
126                                        unsigned width, unsigned height)
127{
128   compress_rgba_unorm(width, height,
129                       src_row, src_stride,
130                       dst_row, dst_stride);
131}
132
133void
134util_format_bptc_srgba_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride,
135                                         const uint8_t *restrict src_row, unsigned src_stride,
136                                         unsigned width, unsigned height)
137{
138   uint8_t *temp_block;
139   temp_block = malloc(width * height * 4 * sizeof(uint8_t));
140   decompress_rgba_unorm(width, height,
141                         src_row, src_stride,
142                         temp_block, width * 4 * sizeof(uint8_t));
143
144   /* Direct call to row unpack instead of util_format_rgba_unpack_rect()
145    * to avoid table lookup that would pull in all unpack symbols.
146    */
147   for (int y = 0; y < height; y++) {
148      util_format_r8g8b8a8_srgb_unpack_rgba_float((char *)dst_row + dst_stride * y,
149                                                  temp_block + width * 4 * y,
150                                                  width);
151   }
152
153   free((void *) temp_block);
154}
155
156void
157util_format_bptc_srgba_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride,
158                                       const float *restrict src_row, unsigned src_stride,
159                                       unsigned width, unsigned height)
160{
161   compress_rgb_float(width, height,
162                      src_row, src_stride,
163                      dst_row, dst_stride,
164                      true);
165}
166
167void
168util_format_bptc_srgba_fetch_rgba(void *restrict dst, const uint8_t *restrict src,
169                                        unsigned width, unsigned height)
170{
171   uint8_t temp_block[4];
172
173   fetch_rgba_unorm_from_block(src + ((width * sizeof(uint8_t)) * (height / 4) + (width / 4)) * 16,
174                               temp_block, (width % 4) + (height % 4) * 4);
175   util_format_r8g8b8a8_srgb_fetch_rgba(dst, temp_block, 0, 0);
176}
177
178void
179util_format_bptc_rgb_float_unpack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride,
180                                              const uint8_t *restrict src_row, unsigned src_stride,
181                                              unsigned width, unsigned height)
182{
183   float *temp_block;
184   temp_block = malloc(width * height * 4 * sizeof(float));
185   decompress_rgb_float(width, height,
186                        src_row, src_stride,
187                        temp_block, width * 4 * sizeof(float),
188                        true);
189   /* Direct call to row unpack instead of util_format_rgba_unpack_rect()
190    * to avoid table lookup that would pull in all unpack symbols.
191    */
192   for (int y = 0; y < height; y++) {
193      util_format_r32g32b32a32_float_unpack_rgba_8unorm(
194          dst_row + dst_stride * y,
195          (const uint8_t *)temp_block + width * 4 * sizeof(float) * y,
196          width);
197   }
198   free((void *) temp_block);
199}
200
201void
202util_format_bptc_rgb_float_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride,
203                                            const uint8_t *restrict src_row, unsigned src_stride,
204                                            unsigned width, unsigned height)
205{
206   compress_rgba_unorm(width, height,
207                       src_row, src_stride,
208                       dst_row, dst_stride);
209}
210
211void
212util_format_bptc_rgb_float_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride,
213                                             const uint8_t *restrict src_row, unsigned src_stride,
214                                             unsigned width, unsigned height)
215{
216   decompress_rgb_float(width, height,
217                        src_row, src_stride,
218                        dst_row, dst_stride,
219                        true);
220}
221
222void
223util_format_bptc_rgb_float_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride,
224                                           const float *restrict src_row, unsigned src_stride,
225                                           unsigned width, unsigned height)
226{
227   compress_rgb_float(width, height,
228                      src_row, src_stride,
229                      dst_row, dst_stride,
230                      true);
231}
232
233void
234util_format_bptc_rgb_float_fetch_rgba(void *restrict dst, const uint8_t *restrict src,
235                                            unsigned width, unsigned height)
236{
237   fetch_rgb_float_from_block(src + ((width * sizeof(uint8_t)) * (height / 4) + (width / 4)) * 16,
238                              dst, (width % 4) + (height % 4) * 4, true);
239}
240
241void
242util_format_bptc_rgb_ufloat_unpack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride,
243                                               const uint8_t *restrict src_row, unsigned src_stride,
244                                               unsigned width, unsigned height)
245{
246   float *temp_block;
247   temp_block = malloc(width * height * 4 * sizeof(float));
248   decompress_rgb_float(width, height,
249                        src_row, src_stride,
250                        temp_block, width * 4 * sizeof(float),
251                        false);
252   /* Direct call to row unpack instead of util_format_rgba_unpack_8unorm()
253    * to avoid table lookup that would pull in all unpack symbols.
254    */
255   for (int y = 0; y < height; y++) {
256      util_format_r32g32b32a32_float_unpack_rgba_8unorm(dst_row + dst_stride * y,
257                                                        (void *)(temp_block + 4 * width * y),
258                                                        width);
259   }
260   free((void *) temp_block);
261}
262
263void
264util_format_bptc_rgb_ufloat_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride,
265                                             const uint8_t *restrict src_row, unsigned src_stride,
266                                             unsigned width, unsigned height)
267{
268   compress_rgba_unorm(width, height,
269                       src_row, src_stride,
270                       dst_row, dst_stride);
271}
272
273void
274util_format_bptc_rgb_ufloat_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride,
275                                              const uint8_t *restrict src_row, unsigned src_stride,
276                                              unsigned width, unsigned height)
277{
278   decompress_rgb_float(width, height,
279                        src_row, src_stride,
280                        dst_row, dst_stride,
281                        false);
282}
283
284void
285util_format_bptc_rgb_ufloat_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride,
286                                            const float *restrict src_row, unsigned src_stride,
287                                            unsigned width, unsigned height)
288{
289   compress_rgb_float(width, height,
290                      src_row, src_stride,
291                      dst_row, dst_stride,
292                      false);
293}
294
295void
296util_format_bptc_rgb_ufloat_fetch_rgba(void *restrict dst, const uint8_t *restrict src,
297                                             unsigned width, unsigned height)
298{
299   fetch_rgb_float_from_block(src + ((width * sizeof(uint8_t)) * (height / 4) + (width / 4)) * 16,
300                              dst, (width % 4) + (height % 4) * 4, false);
301}
302