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