summaryrefslogtreecommitdiff
path: root/src/static_libs
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2014-04-30 14:10:33 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2014-05-27 12:21:30 +0900
commit5582ee016ef031006e4734e561e518041bb9c65e (patch)
treecfda2690d9a96c46d885572ecc061f7a024ad92d /src/static_libs
parent9550b653480f7a7a3af02c7e7712dc9e081605f4 (diff)
Evas rg_etc2: Add ETC2 decoding routines
Simple implementation of the OpenGL ES 3.0 specification, annex C.1.
Diffstat (limited to 'src/static_libs')
-rw-r--r--src/static_libs/rg_etc/rg_etc1.c2
-rw-r--r--src/static_libs/rg_etc/rg_etc1.h6
-rw-r--r--src/static_libs/rg_etc/rg_etc2.c247
3 files changed, 254 insertions, 1 deletions
diff --git a/src/static_libs/rg_etc/rg_etc1.c b/src/static_libs/rg_etc/rg_etc1.c
index f768eaa..bb825e6 100644
--- a/src/static_libs/rg_etc/rg_etc1.c
+++ b/src/static_libs/rg_etc/rg_etc1.c
@@ -1164,7 +1164,7 @@ rg_etc1_block_subblock_color5_delta3_diff_get(unsigned int dst[4],
1164 if (!(table_idx < cETC1IntenModifierValues)) 1164 if (!(table_idx < cETC1IntenModifierValues))
1165 { 1165 {
1166 fprintf(stderr, "table_idx %i < %i\n", table_idx, cETC1IntenModifierValues); 1166 fprintf(stderr, "table_idx %i < %i\n", table_idx, cETC1IntenModifierValues);
1167 return 0; 1167 return 0;
1168 } 1168 }
1169 1169
1170 success = rg_etc1_block_color5_delta3_component_unpack(&r, &g, &b, packed_color5, packed_delta3, 1); 1170 success = rg_etc1_block_color5_delta3_component_unpack(&r, &g, &b, packed_color5, packed_delta3, 1);
diff --git a/src/static_libs/rg_etc/rg_etc1.h b/src/static_libs/rg_etc/rg_etc1.h
index af88701..43a86aa 100644
--- a/src/static_libs/rg_etc/rg_etc1.h
+++ b/src/static_libs/rg_etc/rg_etc1.h
@@ -36,6 +36,12 @@ void rg_etc1_pack_block_init();
36// pack_etc1_block() does not currently support "perceptual" colorspace metrics - it primarily optimizes for RGB RMSE. 36// pack_etc1_block() does not currently support "perceptual" colorspace metrics - it primarily optimizes for RGB RMSE.
37unsigned int rg_etc1_pack_block(void* pETC1_block, const unsigned int* pSrc_pixels_rgba, rg_etc1_pack_params *pack_params); 37unsigned int rg_etc1_pack_block(void* pETC1_block, const unsigned int* pSrc_pixels_rgba, rg_etc1_pack_params *pack_params);
38 38
39// ETC2 support: RGB8_ETC2
40void rg_etc2_rgb8_decode_block(const uint8_t *etc_block, uint32_t *bgra);
41
42// ETC2 support: RGBA8_ETC2_EAC
43//void rg_etc2_rgba8_decode_block(const uint8_t *etc_block, uint32_t *bgra);
44
39//------------------------------------------------------------------------------ 45//------------------------------------------------------------------------------
40// 46//
41// rg_etc1 uses the ZLIB license: 47// rg_etc1 uses the ZLIB license:
diff --git a/src/static_libs/rg_etc/rg_etc2.c b/src/static_libs/rg_etc/rg_etc2.c
new file mode 100644
index 0000000..9204402
--- /dev/null
+++ b/src/static_libs/rg_etc/rg_etc2.c
@@ -0,0 +1,247 @@
1/*
2Copyright (C) 2014 Jean-Philippe ANDRE
3
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are met:
8
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
17INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28/*
29 * ETC2 decoding functions, reimplemented from scratch based on the
30 * OpenGL ES 3.0 spec (annex C.1).
31 *
32 * @author Jean-Philippe ANDRE
33 * @license BSD-2 with advertisement clause
34 */
35
36#include <Eina.h>
37#include "rg_etc1.h"
38
39void rg_etc2_rgb8_decode_block(const uint8_t *etc_block, uint32_t *bgra);
40void rg_etc2_rgba8_decode_block(const uint8_t *etc_block, uint32_t *bgra);
41
42typedef const uint8_t etc_block;
43
44// For T and H modes
45static const int kDistances[8] = {
46 3, 6, 11, 16, 23, 32, 41, 64
47};
48
49// For differential mode
50static const int kSigned3bit[8] = {
51 0, 1, 2, 3, -4, -3, -2, -1
52};
53
54// Use with static constants so the compiler can optimize everything
55#define BITS(byteval, lowbit, highbit) \
56 (((byteval) >> (lowbit)) & ((1 << ((highbit) - (lowbit) + 1)) - 1))
57
58#define BIT(byteval, bit) \
59 (((byteval) >> (bit)) & 0x1)
60
61// Clamps only if value is > 255
62#define CLAMPDOWN(a) ({ int _z = (a); ((_z <= 255) ? _z : 255); })
63
64// Clamps only if value is < 0
65#define CLAMPUP(a) ({ int _z = (a); ((_z >= 0) ? _z : 0); })
66
67// Real clamp
68#define CLAMP(a) ({ int _b = (a); (((_b) >= 0) ? (((_b) < 256) ? (_b) : 255) : 0); })
69
70// Write a BGRA value for output to Evas
71#define BGRA(r,g,b,a) ((a << 24) | (r << 16) | (g << 8) | b)
72
73#define _4to8(a) ({ int _a = (a) & ((1 << 4) - 1); ((_a << 4) | (_a & 0xf)); })
74#define _5to8(a) ({ int _a = (a) & ((1 << 5) - 1); ((_a << 3) | ((_a >> 2) & 0x7)); })
75#define _6to8(a) ({ int _a = (a) & ((1 << 6) - 1); ((_a << 2) | ((_a >> 4) & 0x3)); })
76#define _7to8(a) ({ int _a = (a) & ((1 << 7) - 1); ((_a << 1) | ((_a >> 6) & 0x1)); })
77
78
79static inline void
80_T_mode_color_read(const uint8_t *etc, uint32_t *paint_colors, int alpha)
81{
82 // 4 bit colors
83 const int r1_4 = (BITS(etc[0], 3, 4) << 2) | BITS(etc[0], 0, 1);
84 const int g1_4 = BITS(etc[1], 4, 7);
85 const int b1_4 = BITS(etc[1], 0, 3);
86 const int r2_4 = BITS(etc[2], 4, 7);
87 const int g2_4 = BITS(etc[2], 0, 3);
88 const int b2_4 = BITS(etc[3], 4, 7);
89
90 // Distance index
91 const int didx = (BITS(etc[3], 2, 3) << 1) | BIT(etc[3], 0);
92 const int d = kDistances[didx];
93
94 // Write out paint colors for T mode
95 paint_colors[0] = BGRA(_4to8(r1_4), _4to8(g1_4), _4to8(b1_4), alpha);
96 paint_colors[1] = BGRA(CLAMPDOWN(_4to8(r2_4) + d),
97 CLAMPDOWN(_4to8(g2_4) + d),
98 CLAMPDOWN(_4to8(b2_4) + d),
99 alpha);
100 paint_colors[2] = BGRA(_4to8(r2_4), _4to8(g2_4), _4to8(b2_4), alpha);
101 paint_colors[3] = BGRA(CLAMPUP(_4to8(r2_4) - d),
102 CLAMPUP(_4to8(g2_4) - d),
103 CLAMPUP(_4to8(b2_4) - d),
104 alpha);
105}
106
107static inline void
108_H_mode_color_read(const uint8_t *etc, uint32_t *paint_colors, int alpha)
109{
110 // 4 bit colors
111 const int r1_4 = BITS(etc[0], 3, 6);
112 const int g1_4 = (BITS(etc[0], 0, 2) << 1) | (BIT(etc[1], 4));
113 const int b1_4 = (BIT(etc[1], 3) << 3) | (BITS(etc[1], 0, 1) << 1) | (BIT(etc[2], 7));
114 const int r2_4 = BITS(etc[2], 3, 6);
115 const int g2_4 = (BITS(etc[2], 0, 2) << 1) | (BIT(etc[3], 7));
116 const int b2_4 = BITS(etc[3], 3, 6);
117
118 // Distance index
119 const int basecol1 = (_4to8(r1_4) << 16) | (_4to8(g1_4) << 8) | _4to8(b1_4);
120 const int basecol2 = (_4to8(r2_4) << 16) | (_4to8(g2_4) << 8) | _4to8(b2_4);
121 const int didx =
122 (BIT(etc[3], 2) << 2) |
123 (BIT(etc[3], 0) << 1) |
124 ((basecol1 >= basecol2) ? 1 : 0);
125 const int d = kDistances[didx];
126
127 // Write out paint colors for H mode
128 paint_colors[0] = BGRA(CLAMPDOWN(_4to8(r1_4) + d),
129 CLAMPDOWN(_4to8(g1_4) + d),
130 CLAMPDOWN(_4to8(b1_4) + d),
131 alpha);
132 paint_colors[1] = BGRA(CLAMPUP(_4to8(r1_4) - d),
133 CLAMPUP(_4to8(g1_4) - d),
134 CLAMPUP(_4to8(b1_4) - d),
135 alpha);
136 paint_colors[2] = BGRA(CLAMPDOWN(_4to8(r2_4) + d),
137 CLAMPDOWN(_4to8(g2_4) + d),
138 CLAMPDOWN(_4to8(b2_4) + d),
139 alpha);
140 paint_colors[3] = BGRA(CLAMPUP(_4to8(r2_4) - d),
141 CLAMPUP(_4to8(g2_4) - d),
142 CLAMPUP(_4to8(b2_4) - d),
143 alpha);
144}
145
146static inline void
147_planar_mode_color_read(const uint8_t *etc, uint32_t *bgra, int alpha)
148{
149 // RO: Bits 57-62
150 const int RO = _6to8(BITS(etc[0], 1, 6));
151 // GO: Bits 49-54,56
152 const int GO = _7to8((BIT(etc[0], 0) << 6) | (BITS(etc[1], 1, 6)));
153 // BO: Bits 39,40-41,43-44,48
154 const int BO = _6to8((BIT(etc[1], 0) << 5) | (BITS(etc[2], 3, 4) << 3) | (BITS(etc[2], 0, 1) << 1) | BIT(etc[3], 7));
155 // RH: Bits 32,34-38
156 const int RH = _6to8((BITS(etc[3], 2, 6) << 1) | BIT(etc[3], 0));
157 // GH: Bits 25-31
158 const int GH = _7to8(BITS(etc[4], 1, 7));
159 // BH: Bits 19-23,24
160 const int BH = _6to8((BIT(etc[4], 0) << 5) | (BITS(etc[5], 3, 7)));
161 // RV: Bits 13-15,16-18
162 const int RV = _6to8((BITS(etc[5], 0, 2) << 3) | (BITS(etc[6], 5, 7)));
163 // GV: Bits 6-7,8-12
164 const int GV = _7to8((BITS(etc[6], 0, 4) << 2) | (BITS(etc[7], 6, 7)));
165 // BV: Bits 0-5
166 const int BV = _6to8(BITS(etc[7], 0, 5));
167
168 for (int y = 0; y < 4; y++)
169 for (int x = 0; x < 4; x++)
170 {
171 // Formulas straight from the spec
172 const int R = CLAMP(((x * (RH - RO)) + y * (RV - RO) + 4 * RO + 2) >> 2);
173 const int G = CLAMP(((x * (GH - GO)) + y * (GV - GO) + 4 * GO + 2) >> 2);
174 const int B = CLAMP(((x * (BH - BO)) + y * (BV - BO) + 4 * BO + 2) >> 2);
175 *bgra++ = BGRA(R, G, B, alpha);
176 }
177}
178
179void
180rg_etc2_rgb8_decode_block(const uint8_t *etc, uint32_t *bgra)
181{
182 // Check differential mode bit
183 if ((etc[3] & 0x2) == 0)
184 goto etc1;
185
186 // Read R,G,B
187 const int R = BITS(etc[0], 3, 7);
188 const int dR = kSigned3bit[BITS(etc[0], 0, 2)];
189 const int G = BITS(etc[1], 3, 7);
190 const int dG = kSigned3bit[BITS(etc[1], 0, 2)];
191 const int B = BITS(etc[2], 3, 7);
192 const int dB = kSigned3bit[BITS(etc[2], 0, 2)];
193 uint32_t paint_colors[4];
194
195 if ((R + dR) < 0 || (R + dR) >= 32)
196 {
197 // T mode
198 _T_mode_color_read(etc, paint_colors, 255);
199 goto th_mode;
200 }
201 if ((G + dG) < 0 || (G + dG) >= 32)
202 {
203 // H mode
204 _H_mode_color_read(etc, paint_colors, 255);
205 goto th_mode;
206 }
207 if ((B + dB) < 0 || (B + dB) >= 32)
208 {
209 // Planar mode
210 _planar_mode_color_read(etc, bgra, 255);
211 return;
212 }
213
214etc1:
215 // Valid differential mode or individual mode: ETC1
216 if (!rg_etc1_unpack_block(etc, bgra, 0))
217 fprintf(stderr, "ETC2: Something very strange is happening here!\n");
218 return;
219
220th_mode:
221 // Common code for modes T and H.
222
223 // a,b,c,d
224 bgra[ 0] = paint_colors[(BIT(etc[5], 0) << 1) | (BIT(etc[7], 0))];
225 bgra[ 4] = paint_colors[(BIT(etc[5], 1) << 1) | (BIT(etc[7], 1))];
226 bgra[ 8] = paint_colors[(BIT(etc[5], 2) << 1) | (BIT(etc[7], 2))];
227 bgra[12] = paint_colors[(BIT(etc[5], 3) << 1) | (BIT(etc[7], 3))];
228
229 // e,f,g,h
230 bgra[ 1] = paint_colors[(BIT(etc[5], 4) << 1) | (BIT(etc[7], 4))];
231 bgra[ 5] = paint_colors[(BIT(etc[5], 5) << 1) | (BIT(etc[7], 5))];
232 bgra[ 9] = paint_colors[(BIT(etc[5], 6) << 1) | (BIT(etc[7], 6))];
233 bgra[13] = paint_colors[(BIT(etc[5], 7) << 1) | (BIT(etc[7], 7))];
234
235 // i,j,k,l
236 bgra[ 2] = paint_colors[(BIT(etc[4], 0) << 1) | (BIT(etc[6], 0))];
237 bgra[ 6] = paint_colors[(BIT(etc[4], 1) << 1) | (BIT(etc[6], 1))];
238 bgra[10] = paint_colors[(BIT(etc[4], 2) << 1) | (BIT(etc[6], 2))];
239 bgra[14] = paint_colors[(BIT(etc[4], 3) << 1) | (BIT(etc[6], 3))];
240
241 // m,n,o,p
242 bgra[ 3] = paint_colors[(BIT(etc[4], 4) << 1) | (BIT(etc[6], 4))];
243 bgra[ 7] = paint_colors[(BIT(etc[4], 5) << 1) | (BIT(etc[6], 5))];
244 bgra[11] = paint_colors[(BIT(etc[4], 6) << 1) | (BIT(etc[6], 6))];
245 bgra[15] = paint_colors[(BIT(etc[4], 7) << 1) | (BIT(etc[6], 7))];
246 return;
247}