]> git.sesse.net Git - ffmpeg/blob - libavcodec/texturedsp.c
dxva2: Keep code shared between dxva2 and d3d11va under the correct #if
[ffmpeg] / libavcodec / texturedsp.c
1 /*
2  * Texture block decompression
3  * Copyright (C) 2009 Benjamin Dobell, Glass Echidna
4  * Copyright (C) 2012 Matthäus G. "Anteru" Chajdas (http://anteru.net)
5  * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara@gmail.com>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
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 OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24
25 #include <stddef.h>
26 #include <stdint.h>
27
28 #include "libavutil/attributes.h"
29 #include "libavutil/common.h"
30 #include "libavutil/intreadwrite.h"
31
32 #include "texturedsp.h"
33
34 #define RGBA(r, g, b, a) ((uint8_t)(r) <<  0) | \
35                          ((uint8_t)(g) <<  8) | \
36                          ((uint8_t)(b) << 16) | \
37                          ((uint8_t)(a) << 24)
38
39 static av_always_inline void extract_color(uint32_t colors[4],
40                                            uint16_t color0,
41                                            uint16_t color1,
42                                            int dxtn, int alpha)
43 {
44     int tmp;
45     uint8_t r0, g0, b0, r1, g1, b1;
46     uint8_t a = dxtn ? 0 : 255;
47
48     tmp = (color0 >> 11) * 255 + 16;
49     r0  = (uint8_t) ((tmp / 32 + tmp) / 32);
50     tmp = ((color0 & 0x07E0) >> 5) * 255 + 32;
51     g0  = (uint8_t) ((tmp / 64 + tmp) / 64);
52     tmp = (color0 & 0x001F) * 255 + 16;
53     b0  = (uint8_t) ((tmp / 32 + tmp) / 32);
54
55     tmp = (color1 >> 11) * 255 + 16;
56     r1  = (uint8_t) ((tmp / 32 + tmp) / 32);
57     tmp = ((color1 & 0x07E0) >> 5) * 255 + 32;
58     g1  = (uint8_t) ((tmp / 64 + tmp) / 64);
59     tmp = (color1 & 0x001F) * 255 + 16;
60     b1  = (uint8_t) ((tmp / 32 + tmp) / 32);
61
62     if (dxtn || color0 > color1) {
63         colors[0] = RGBA(r0, g0, b0, a);
64         colors[1] = RGBA(r1, g1, b1, a);
65         colors[2] = RGBA((2 * r0 + r1) / 3,
66                          (2 * g0 + g1) / 3,
67                          (2 * b0 + b1) / 3,
68                          a);
69         colors[3] = RGBA((2 * r1 + r0) / 3,
70                          (2 * g1 + g0) / 3,
71                          (2 * b1 + b0) / 3,
72                          a);
73     } else {
74         colors[0] = RGBA(r0, g0, b0, a);
75         colors[1] = RGBA(r1, g1, b1, a);
76         colors[2] = RGBA((r0 + r1) / 2,
77                          (g0 + g1) / 2,
78                          (b0 + b1) / 2,
79                          a);
80         colors[3] = RGBA(0, 0, 0, alpha);
81     }
82 }
83
84 static inline void dxt1_block_internal(uint8_t *dst, ptrdiff_t stride,
85                                        const uint8_t *block, uint8_t alpha)
86 {
87     int x, y;
88     uint32_t colors[4];
89     uint16_t color0 = AV_RL16(block + 0);
90     uint16_t color1 = AV_RL16(block + 2);
91     uint32_t code   = AV_RL32(block + 4);
92
93     extract_color(colors, color0, color1, 0, alpha);
94
95     for (y = 0; y < 4; y++) {
96         for (x = 0; x < 4; x++) {
97             uint32_t pixel = colors[code & 3];
98             code >>= 2;
99             AV_WL32(dst + x * 4, pixel);
100         }
101         dst += stride;
102     }
103 }
104
105 /**
106  * Decompress one block of a DXT1 texture and store the resulting
107  * RGBA pixels in 'dst'. Alpha component is fully opaque.
108  *
109  * @param dst    output buffer.
110  * @param stride scanline in bytes.
111  * @param block  block to decompress.
112  * @return how much texture data has been consumed.
113  */
114 static int dxt1_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
115 {
116     dxt1_block_internal(dst, stride, block, 255);
117
118     return 8;
119 }
120
121 /**
122  * Decompress one block of a DXT1 with 1-bit alpha texture and store
123  * the resulting RGBA pixels in 'dst'. Alpha is either fully opaque or
124  * fully transparent.
125  *
126  * @param dst    output buffer.
127  * @param stride scanline in bytes.
128  * @param block  block to decompress.
129  * @return how much texture data has been consumed.
130  */
131 static int dxt1a_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
132 {
133     dxt1_block_internal(dst, stride, block, 0);
134
135     return 8;
136 }
137
138 static inline void dxt3_block_internal(uint8_t *dst, ptrdiff_t stride,
139                                        const uint8_t *block)
140 {
141     int x, y;
142     uint32_t colors[4];
143     uint16_t color0 = AV_RL16(block +  8);
144     uint16_t color1 = AV_RL16(block + 10);
145     uint32_t code   = AV_RL32(block + 12);
146
147     extract_color(colors, color0, color1, 1, 0);
148
149     for (y = 0; y < 4; y++) {
150         const uint16_t alpha_code = AV_RL16(block + 2 * y);
151         uint8_t alpha_values[4];
152
153         alpha_values[0] = ((alpha_code >>  0) & 0x0F) * 17;
154         alpha_values[1] = ((alpha_code >>  4) & 0x0F) * 17;
155         alpha_values[2] = ((alpha_code >>  8) & 0x0F) * 17;
156         alpha_values[3] = ((alpha_code >> 12) & 0x0F) * 17;
157
158         for (x = 0; x < 4; x++) {
159             uint8_t alpha = alpha_values[x];
160             uint32_t pixel = colors[code & 3] | (alpha << 24);
161             code >>= 2;
162
163             AV_WL32(dst + x * 4, pixel);
164         }
165         dst += stride;
166     }
167 }
168
169 /** Convert a premultiplied alpha pixel to a straight alpha pixel. */
170 static av_always_inline void premult2straight(uint8_t *src)
171 {
172     int r = src[0];
173     int g = src[1];
174     int b = src[2];
175     int a = src[3]; /* unchanged */
176
177     src[0] = (uint8_t) r * a / 255;
178     src[1] = (uint8_t) g * a / 255;
179     src[2] = (uint8_t) b * a / 255;
180 }
181
182 /**
183  * Decompress one block of a DXT2 texture and store the resulting
184  * RGBA pixels in 'dst'.
185  *
186  * @param dst    output buffer.
187  * @param stride scanline in bytes.
188  * @param block  block to decompress.
189  * @return how much texture data has been consumed.
190  */
191 static int dxt2_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
192 {
193     int x, y;
194
195     dxt3_block_internal(dst, stride, block);
196
197     /* This format is DXT3, but returns premultiplied alpha. It needs to be
198      * converted because it's what lavc outputs (and swscale expects). */
199     for (y = 0; y < 4; y++)
200         for (x = 0; x < 4; x++)
201             premult2straight(dst + x * 4 + y * stride);
202
203     return 16;
204 }
205
206 /**
207  * Decompress one block of a DXT3 texture and store the resulting
208  * RGBA pixels in 'dst'.
209  *
210  * @param dst    output buffer.
211  * @param stride scanline in bytes.
212  * @param block  block to decompress.
213  * @return how much texture data has been consumed.
214  */
215 static int dxt3_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
216 {
217     dxt3_block_internal(dst, stride, block);
218
219     return 16;
220 }
221
222 /**
223  * Decompress a BC 16x3 index block stored as
224  *   h g f e
225  *   d c b a
226  *   p o n m
227  *   l k j i
228  *
229  * Bits packed as
230  *  | h | g | f | e | d | c | b | a | // Entry
231  *  |765 432 107 654 321 076 543 210| // Bit
232  *  |0000000000111111111112222222222| // Byte
233  *
234  * into 16 8-bit indices.
235  */
236 static void decompress_indices(uint8_t *dst, const uint8_t *src)
237 {
238     int block, i;
239
240     for (block = 0; block < 2; block++) {
241         int tmp = AV_RL24(src);
242
243         /* Unpack 8x3 bit from last 3 byte block */
244         for (i = 0; i < 8; i++)
245             dst[i] = (tmp >> (i * 3)) & 0x7;
246
247         src += 3;
248         dst += 8;
249     }
250 }
251
252 static inline void dxt5_block_internal(uint8_t *dst, ptrdiff_t stride,
253                                        const uint8_t *block)
254 {
255     int x, y;
256     uint32_t colors[4];
257     uint8_t alpha_indices[16];
258     uint16_t color0 = AV_RL16(block + 8);
259     uint16_t color1 = AV_RL16(block + 10);
260     uint32_t code   = AV_RL32(block + 12);
261     uint8_t alpha0  = *(block);
262     uint8_t alpha1  = *(block + 1);
263
264     decompress_indices(alpha_indices, block + 2);
265
266     extract_color(colors, color0, color1, 1, 0);
267
268     for (y = 0; y < 4; y++) {
269         for (x = 0; x < 4; x++) {
270             int alpha_code = alpha_indices[x + y * 4];
271             uint32_t pixel;
272             uint8_t alpha;
273
274             if (alpha_code == 0) {
275                 alpha = alpha0;
276             } else if (alpha_code == 1) {
277                 alpha = alpha1;
278             } else {
279                 if (alpha0 > alpha1) {
280                     alpha = (uint8_t) (((8 - alpha_code) * alpha0 +
281                                         (alpha_code - 1) * alpha1) / 7);
282                 } else {
283                     if (alpha_code == 6) {
284                         alpha = 0;
285                     } else if (alpha_code == 7) {
286                         alpha = 255;
287                     } else {
288                         alpha = (uint8_t) (((6 - alpha_code) * alpha0 +
289                                             (alpha_code - 1) * alpha1) / 5);
290                     }
291                 }
292             }
293             pixel = colors[code & 3] | (alpha << 24);
294             code >>= 2;
295             AV_WL32(dst + x * 4, pixel);
296         }
297         dst += stride;
298     }
299 }
300
301 /**
302  * Decompress one block of a DXT4 texture and store the resulting
303  * RGBA pixels in 'dst'.
304  *
305  * @param dst    output buffer.
306  * @param stride scanline in bytes.
307  * @param block  block to decompress.
308  * @return how much texture data has been consumed.
309  */
310 static int dxt4_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
311 {
312     int x, y;
313
314     dxt5_block_internal(dst, stride, block);
315
316     /* This format is DXT5, but returns premultiplied alpha. It needs to be
317      * converted because it's what lavc outputs (and swscale expects). */
318     for (y = 0; y < 4; y++)
319         for (x = 0; x < 4; x++)
320             premult2straight(dst + x * 4 + y * stride);
321
322     return 16;
323 }
324
325 /**
326  * Decompress one block of a DXT5 texture and store the resulting
327  * RGBA pixels in 'dst'.
328  *
329  * @param dst    output buffer.
330  * @param stride scanline in bytes.
331  * @param block  block to decompress.
332  * @return how much texture data has been consumed.
333  */
334 static int dxt5_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
335 {
336     dxt5_block_internal(dst, stride, block);
337
338     return 16;
339 }
340
341 /**
342  * Convert a YCoCg buffer to RGBA.
343  *
344  * @param src    input buffer.
345  * @param scaled variant with scaled chroma components and opaque alpha.
346  */
347 static av_always_inline void ycocg2rgba(uint8_t *src, int scaled)
348 {
349     int r = src[0];
350     int g = src[1];
351     int b = src[2];
352     int a = src[3];
353
354     int s  = scaled ? (b >> 3) + 1 : 1;
355     int y  = a;
356     int co = (r - 128) / s;
357     int cg = (g - 128) / s;
358
359     src[0] = av_clip_uint8(y + co - cg);
360     src[1] = av_clip_uint8(y + cg);
361     src[2] = av_clip_uint8(y - co - cg);
362     src[3] = scaled ? 255 : b;
363 }
364
365 /**
366  * Decompress one block of a DXT5 texture with classic YCoCg and store
367  * the resulting RGBA pixels in 'dst'. Alpha component is fully opaque.
368  *
369  * @param dst    output buffer.
370  * @param stride scanline in bytes.
371  * @param block  block to decompress.
372  * @return how much texture data has been consumed.
373  */
374 static int dxt5y_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
375 {
376     int x, y;
377
378     /* This format is basically DXT5, with luma stored in alpha.
379      * Run a normal decompress and then reorder the components. */
380     dxt5_block_internal(dst, stride, block);
381
382     for (y = 0; y < 4; y++)
383         for (x = 0; x < 4; x++)
384             ycocg2rgba(dst + x * 4 + y * stride, 0);
385
386     return 16;
387 }
388
389 /**
390  * Decompress one block of a DXT5 texture with scaled YCoCg and store
391  * the resulting RGBA pixels in 'dst'. Alpha component is fully opaque.
392  *
393  * @param dst    output buffer.
394  * @param stride scanline in bytes.
395  * @param block  block to decompress.
396  * @return how much texture data has been consumed.
397  */
398 static int dxt5ys_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
399 {
400     int x, y;
401
402     /* This format is basically DXT5, with luma stored in alpha.
403      * Run a normal decompress and then reorder the components. */
404     dxt5_block_internal(dst, stride, block);
405
406     for (y = 0; y < 4; y++)
407         for (x = 0; x < 4; x++)
408             ycocg2rgba(dst + x * 4 + y * stride, 1);
409
410     return 16;
411 }
412
413 static inline void rgtc_block_internal(uint8_t *dst, ptrdiff_t stride,
414                                        const uint8_t *block,
415                                        const int *color_tab)
416 {
417     uint8_t indices[16];
418     int x, y;
419
420     decompress_indices(indices, block + 2);
421
422     /* Only one or two channels are stored at most, since it only used to
423      * compress specular (black and white) or normal (red and green) maps.
424      * Although the standard says to zero out unused components, many
425      * implementations fill all of them with the same value. */
426     for (y = 0; y < 4; y++) {
427         for (x = 0; x < 4; x++) {
428             int i = indices[x + y * 4];
429             /* Interval expansion from [-1 1] or [0 1] to [0 255]. */
430             int c = color_tab[i];
431             uint32_t pixel = RGBA(c, c, c, 255);
432             AV_WL32(dst + x * 4 + y * stride, pixel);
433         }
434     }
435 }
436
437 static inline void rgtc1_block_internal(uint8_t *dst, ptrdiff_t stride,
438                                         const uint8_t *block, int sign)
439 {
440     int color_table[8];
441     int r0, r1;
442
443     if (sign) {
444         /* signed data is in [-128 127] so just offset it to unsigned
445          * and it can be treated exactly the same */
446         r0 = ((int8_t) block[0]) + 128;
447         r1 = ((int8_t) block[1]) + 128;
448     } else {
449         r0 = block[0];
450         r1 = block[1];
451     }
452
453     color_table[0] = r0;
454     color_table[1] = r1;
455
456     if (r0 > r1) {
457         /* 6 interpolated color values */
458         color_table[2] = (6 * r0 + 1 * r1) / 7; // bit code 010
459         color_table[3] = (5 * r0 + 2 * r1) / 7; // bit code 011
460         color_table[4] = (4 * r0 + 3 * r1) / 7; // bit code 100
461         color_table[5] = (3 * r0 + 4 * r1) / 7; // bit code 101
462         color_table[6] = (2 * r0 + 5 * r1) / 7; // bit code 110
463         color_table[7] = (1 * r0 + 6 * r1) / 7; // bit code 111
464     } else {
465         /* 4 interpolated color values */
466         color_table[2] = (4 * r0 + 1 * r1) / 5; // bit code 010
467         color_table[3] = (3 * r0 + 2 * r1) / 5; // bit code 011
468         color_table[4] = (2 * r0 + 3 * r1) / 5; // bit code 100
469         color_table[5] = (1 * r0 + 4 * r1) / 5; // bit code 101
470         color_table[6] = 0;    /* min range */  // bit code 110
471         color_table[7] = 255;  /* max range */  // bit code 111
472     }
473
474     rgtc_block_internal(dst, stride, block, color_table);
475 }
476
477 /**
478  * Decompress one block of a RGRC1 texture with signed components
479  * and store the resulting RGBA pixels in 'dst'.
480  *
481  * @param dst    output buffer.
482  * @param stride scanline in bytes.
483  * @param block  block to decompress.
484  * @return how much texture data has been consumed.
485  */
486 static int rgtc1s_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
487 {
488     rgtc1_block_internal(dst, stride, block, 1);
489
490     return 8;
491 }
492
493 /**
494  * Decompress one block of a RGRC1 texture with unsigned components
495  * and store the resulting RGBA pixels in 'dst'.
496  *
497  * @param dst    output buffer.
498  * @param stride scanline in bytes.
499  * @param block  block to decompress.
500  * @return how much texture data has been consumed.
501  */
502 static int rgtc1u_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
503 {
504     rgtc1_block_internal(dst, stride, block, 0);
505
506     return 8;
507 }
508
509 static inline void rgtc2_block_internal(uint8_t *dst, ptrdiff_t stride,
510                                         const uint8_t *block, int sign)
511 {
512     /* 4x4 block containing 4 component pixels. */
513     uint8_t c0[4 * 4 * 4];
514     uint8_t c1[4 * 4 * 4];
515     int x, y;
516
517     /* Decompress the two channels separately and interleave them afterwards. */
518     rgtc1_block_internal(c0, 16, block, sign);
519     rgtc1_block_internal(c1, 16, block + 8, sign);
520
521     /* B is rebuilt exactly like a normal map. */
522     for (y = 0; y < 4; y++) {
523         for (x = 0; x < 4; x++) {
524             uint8_t *p = dst + x * 4 + y * stride;
525             int r = c0[x * 4 + y * 16];
526             int g = c1[x * 4 + y * 16];
527             int b = 127;
528
529             int d = (255 * 255 - r * r - g * g) / 2;
530             if (d > 0)
531                 b = rint(sqrtf(d));
532
533             p[0] = r;
534             p[1] = g;
535             p[2] = b;
536             p[3] = 255;
537         }
538     }
539 }
540
541 /**
542  * Decompress one block of a RGRC2 texture with signed components
543  * and store the resulting RGBA pixels in 'dst'. Alpha is fully opaque.
544  *
545  * @param dst    output buffer.
546  * @param stride scanline in bytes.
547  * @param block  block to decompress.
548  * @return how much texture data has been consumed.
549  */
550 static int rgtc2s_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
551 {
552     rgtc2_block_internal(dst, stride, block, 1);
553
554     return 16;
555 }
556
557 /**
558  * Decompress one block of a RGRC2 texture with unsigned components
559  * and store the resulting RGBA pixels in 'dst'. Alpha is fully opaque.
560  *
561  * @param dst    output buffer.
562  * @param stride scanline in bytes.
563  * @param block  block to decompress.
564  * @return how much texture data has been consumed.
565  */
566 static int rgtc2u_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
567 {
568     rgtc2_block_internal(dst, stride, block, 0);
569
570     return 16;
571 }
572
573 /**
574  * Decompress one block of a 3Dc texture with unsigned components
575  * and store the resulting RGBA pixels in 'dst'. Alpha is fully opaque.
576  *
577  * @param dst    output buffer.
578  * @param stride scanline in bytes.
579  * @param block  block to decompress.
580  * @return how much texture data has been consumed.
581  */
582 static int dxn3dc_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
583 {
584     int x, y;
585     rgtc2_block_internal(dst, stride, block, 0);
586
587     /* This is the 3Dc variant of RGTC2, with swapped R and G. */
588     for (y = 0; y < 4; y++) {
589         for (x = 0; x < 4; x++) {
590             uint8_t *p = dst + x * 4 + y * stride;
591             FFSWAP(uint8_t, p[0], p[1]);
592         }
593     }
594
595     return 16;
596 }
597
598 av_cold void ff_texturedsp_init(TextureDSPContext *c)
599 {
600     c->dxt1_block   = dxt1_block;
601     c->dxt1a_block  = dxt1a_block;
602     c->dxt2_block   = dxt2_block;
603     c->dxt3_block   = dxt3_block;
604     c->dxt4_block   = dxt4_block;
605     c->dxt5_block   = dxt5_block;
606     c->dxt5y_block  = dxt5y_block;
607     c->dxt5ys_block = dxt5ys_block;
608     c->rgtc1s_block = rgtc1s_block;
609     c->rgtc1u_block = rgtc1u_block;
610     c->rgtc2s_block = rgtc2s_block;
611     c->rgtc2u_block = rgtc2u_block;
612     c->dxn3dc_block = dxn3dc_block;
613 }