]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/etclib.c
Merge branch 'q3rally-gamepack' into 'master'
[xonotic/netradiant.git] / libs / etclib.c
1 // Copyright 2009 Google Inc.
2 //
3 // Based on the code from Android ETC1Util.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16
17 #include "etclib.h"
18
19 static void ETC_DecodeETC1SubBlock( byte *out, qboolean outRGBA, int r, int g, int b, int tableIndex, unsigned int low, qboolean second, qboolean flipped ){
20         int baseX = 0, baseY = 0;
21         const int modifierTable[] = {
22                 2, 8, -2, -8,
23                 5, 17, -5, -17,
24                 9, 29, -9, -29,
25                 13, 42, -13, -42,
26                 18, 60, -18, -60,
27                 24, 80, -24, -80,
28                 33, 106, -33, -106,
29                 47, 183, -47, -183
30         };
31         const int *table = modifierTable + tableIndex * 4;
32         int i;  
33
34         if ( second ) {
35                 if ( flipped ) {
36                         baseY = 2;
37                 }
38                 else {
39                         baseX = 2;
40                 }
41         }
42
43         for ( i = 0; i < 8; i++ )
44         {
45                 int x, y, k, delta;
46                 int qr, qg, qb;
47                 byte *q;
48
49                 if ( flipped ) {
50                         x = baseX + ( i >> 1 );
51                         y = baseY + ( i & 1 );
52                 }
53                 else {
54                         x = baseX + ( i >> 2 );
55                         y = baseY + ( i & 3 );
56                 }
57                 k = y + ( x * 4 );
58                 delta = table[( ( low >> k ) & 1 ) | ( ( low >> ( k + 15 ) ) & 2 )];
59
60                 qr = r + delta;
61                 qg = g + delta;
62                 qb = b + delta;
63                 if ( outRGBA ) {
64                         q = out + 4 * ( x + 4 * y );
65                 }
66                 else {
67                         q = out + 3 * ( x + 4 * y );
68                 }
69                 *( q++ ) = ( ( qr > 0 ) ? ( ( qr < 255 ) ? qr : 255 ) : 0 );
70                 *( q++ ) = ( ( qg > 0 ) ? ( ( qg < 255 ) ? qg : 255 ) : 0 );
71                 *( q++ ) = ( ( qb > 0 ) ? ( ( qb < 255 ) ? qb : 255 ) : 0 );
72                 if ( outRGBA ) {
73                         *( q++ ) = 255;
74                 }
75         }
76 }
77
78 void ETC_DecodeETC1Block( const byte* in, byte* out, qboolean outRGBA ){
79         unsigned int high = ( in[0] << 24 ) | ( in[1] << 16 ) | ( in[2] << 8 ) | in[3];
80         unsigned int low = ( in[4] << 24 ) | ( in[5] << 16 ) | ( in[6] << 8 ) | in[7];
81         int r1, r2, g1, g2, b1, b2;
82         qboolean flipped = ( ( high & 1 ) != 0 );
83
84         if ( high & 2 ) {
85                 int rBase, gBase, bBase;
86                 const int lookup[] = { 0, 1, 2, 3, -4, -3, -2, -1 };
87
88                 rBase = ( high >> 27 ) & 31;
89                 r1 = ( rBase << 3 ) | ( rBase >> 2 );
90                 rBase = ( rBase + ( lookup[( high >> 24 ) & 7] ) ) & 31;
91                 r2 = ( rBase << 3 ) | ( rBase >> 2 );
92
93                 gBase = ( high >> 19 ) & 31;
94                 g1 = ( gBase << 3 ) | ( gBase >> 2 );
95                 gBase = ( gBase + ( lookup[( high >> 16 ) & 7] ) ) & 31;
96                 g2 = ( gBase << 3 ) | ( gBase >> 2 );
97
98                 bBase = ( high >> 11 ) & 31;
99                 b1 = ( bBase << 3 ) | ( bBase >> 2 );
100                 bBase = ( bBase + ( lookup[( high >> 8 ) & 7] ) ) & 31;
101                 b2 = ( bBase << 3 ) | ( bBase >> 2 );
102         }
103         else {
104                 r1 = ( ( high >> 24 ) & 0xf0 ) | ( ( high >> 28 ) & 0xf );
105                 r2 = ( ( high >> 20 ) & 0xf0 ) | ( ( high >> 24 ) & 0xf );
106                 g1 = ( ( high >> 16 ) & 0xf0 ) | ( ( high >> 20 ) & 0xf );
107                 g2 = ( ( high >> 12 ) & 0xf0 ) | ( ( high >> 16 ) & 0xf );
108                 b1 = ( ( high >> 8 ) & 0xf0 ) | ( ( high >> 12 ) & 0xf );
109                 b2 = ( ( high >> 4 ) & 0xf0 ) | ( ( high >> 8 ) & 0xf );
110         }
111
112         ETC_DecodeETC1SubBlock( out, outRGBA, r1, g1, b1, ( high >> 5 ) & 7, low, qfalse, flipped );
113         ETC_DecodeETC1SubBlock( out, outRGBA, r2, g2, b2, ( high >> 2 ) & 7, low, qtrue, flipped );
114 }