summaryrefslogtreecommitdiff
path: root/src/static_libs/rg_etc
diff options
context:
space:
mode:
authorJean-Philippe ANDRE <jpeg@videolan.org>2014-06-22 18:35:33 +0900
committerJean-Philippe ANDRE <jpeg@videolan.org>2014-06-22 18:59:52 +0900
commit60895e1a140e9db30cfd9c2d8ce3f8e2cb86f271 (patch)
tree18534140ba7a756b58beef6c8faff3bb6ad0a2d1 /src/static_libs/rg_etc
parent4d35471e8e7fe91f657c1dca05bbb2dbd6cda8e3 (diff)
Evas ETC2: Remove some C99/GCC extensions code
There is still some C99 code in the file in the form of for (int k = 0; ...) If there's a strong requirement not to use this form, I'll change it, otherwise I find this specific code style more readable (k is local to this iteration). This patch and the previous one even give a ~10% speedup on the encoding time. Sweet :)
Diffstat (limited to 'src/static_libs/rg_etc')
-rw-r--r--src/static_libs/rg_etc/etc2_encoder.c123
1 files changed, 73 insertions, 50 deletions
diff --git a/src/static_libs/rg_etc/etc2_encoder.c b/src/static_libs/rg_etc/etc2_encoder.c
index d4bc11c3d5..54481e83af 100644
--- a/src/static_libs/rg_etc/etc2_encoder.c
+++ b/src/static_libs/rg_etc/etc2_encoder.c
@@ -88,19 +88,38 @@ static const int kBlockWalk[16] = {
88 (((byteval) >> (bit)) & 0x1) 88 (((byteval) >> (bit)) & 0x1)
89 89
90// Real clamp 90// Real clamp
91#define CLAMP(a) ({ int _b = (a); (((_b) >= 0) ? (((_b) < 256) ? (_b) : 255) : 0); }) 91static inline int
92 92clampi(int a)
93// Simple min 93{
94#define MIN(a,b) ({ int _z = (a), _y = (b); ((_z <= _y) ? _z : _y); }) 94 if (EINA_LIKELY(!(a & ~0xFF)))
95 95 return a;
96// Simple max 96 else if (a < 0)
97#define MAX(a,b) ({ int __z = (a), __y = (b); ((__z > __y) ? __z : __y); }) 97 return 0;
98 else
99 return 0xFF;
100}
98 101
99// Simple clamp between two values 102// Simple clamp between two values
100#define MINMAX(a,b,c) (MIN(c,MAX(a,b))) 103static inline int
104minmaxi(int val, int m, int M)
105{
106 if (EINA_LIKELY((val >= m) && (val <= M)))
107 return val;
108 else if (val < m)
109 return m;
110 else
111 return M;
112}
101 113
102// Simple abs 114// Simple abs
103#define ABS(a) ({ int _a = (a); ((_a >= 0) ? _a : (-_a)); }) 115static inline int
116absi(int a)
117{
118 if (EINA_LIKELY(a >= 0))
119 return a;
120 else
121 return (-a);
122}
104 123
105// Write a BGRA value for output to Evas 124// Write a BGRA value for output to Evas
106#define BGRA(r,g,b,a) ((a << 24) | (r << 16) | (g << 8) | b) 125#define BGRA(r,g,b,a) ((a << 24) | (r << 16) | (g << 8) | b)
@@ -149,8 +168,8 @@ _etc2_alpha_block_pack(uint8_t *etc2_alpha,
149 // Brute force -- find modifier index 168 // Brute force -- find modifier index
150 for (int k = 0; (k < 8) && minErr; k++) 169 for (int k = 0; (k < 8) && minErr; k++)
151 { 170 {
152 int tryA = CLAMP(base_codeword + alphaModifiers[k] * multiplier); 171 int tryA = clampi(base_codeword + alphaModifiers[k] * multiplier);
153 int err = ABS(realA - tryA); 172 int err = absi(realA - tryA);
154 if (err < minErr) 173 if (err < minErr)
155 { 174 {
156 minErr = err; 175 minErr = err;
@@ -203,8 +222,9 @@ _etc2_alpha_encode(uint8_t *etc2_alpha, const uint32_t *bgra,
203 222
204 for (int i = 0; i < 16; i++) 223 for (int i = 0; i < 16; i++)
205 { 224 {
206 int thisDiff = ABS(alphas[i] - avg); 225 int thisDiff = absi(alphas[i] - avg);
207 maxDiff = MAX(thisDiff, maxDiff); 226 if (thisDiff > maxDiff)
227 maxDiff = thisDiff;
208 diff += thisDiff; 228 diff += thisDiff;
209 } 229 }
210 230
@@ -239,13 +259,13 @@ _etc2_alpha_encode(uint8_t *etc2_alpha, const uint32_t *bgra,
239 259
240 // for loop avg, avg-1, avg+1, avg-2, avg+2, ... 260 // for loop avg, avg-1, avg+1, avg-2, avg+2, ...
241 for (int step = 0; step < base_range; step += base_step) 261 for (int step = 0; step < base_range; step += base_step)
242 for (base_codeword = CLAMP(avg - step); 262 for (base_codeword = clampi(avg - step);
243 base_codeword <= CLAMP(avg + step);) 263 base_codeword <= clampi(avg + step);)
244 { 264 {
245 for (modifierIdx = 0; modifierIdx < 16; modifierIdx++) 265 for (modifierIdx = 0; modifierIdx < 16; modifierIdx++)
246 for (multiplier = 0; multiplier < 16; multiplier++) 266 for (multiplier = 0; multiplier < 16; multiplier++)
247 { 267 {
248 if ((ABS(multiplier * kAlphaModifiers[modifierIdx][3]) + ABS(base_codeword - avg)) < maxDiff) 268 if ((absi(multiplier * kAlphaModifiers[modifierIdx][3]) + absi(base_codeword - avg)) < maxDiff)
249 continue; 269 continue;
250 270
251 err = _etc2_alpha_block_pack(etc2_alpha, base_codeword, 271 err = _etc2_alpha_block_pack(etc2_alpha, base_codeword,
@@ -263,7 +283,7 @@ _etc2_alpha_encode(uint8_t *etc2_alpha, const uint32_t *bgra,
263 } 283 }
264 if (step <= 0) break; 284 if (step <= 0) break;
265 if (base_codeword < 255) 285 if (base_codeword < 255)
266 base_codeword = CLAMP(base_codeword + 2 * step); 286 base_codeword = clampi(base_codeword + 2 * step);
267 else 287 else
268 break; 288 break;
269 } 289 }
@@ -350,13 +370,13 @@ _etc2_h_mode_header_pack(uint8_t *etc2, Eina_Bool *swap_colors,
350 // Note: if c1 == c2, no big deal because H is not the best choice of mode 370 // Note: if c1 == c2, no big deal because H is not the best choice of mode
351 if (distanceSpecialBit) 371 if (distanceSpecialBit)
352 { 372 {
353 c1 = MAX(color1, color2); 373 c1 = (color1 > color2) ? color1 : color2;
354 c2 = MIN(color1, color2); 374 c2 = (color1 <= color2) ? color1 : color2;
355 } 375 }
356 else 376 else
357 { 377 {
358 c1 = MIN(color1, color2); 378 c1 = (color1 <= color2) ? color1 : color2;
359 c2 = MAX(color1, color2); 379 c2 = (color1 > color2) ? color1 : color2;
360 } 380 }
361 381
362 // Return flag so we use the proper colors when packing the block 382 // Return flag so we use the proper colors when packing the block
@@ -433,34 +453,37 @@ _rgb_distance_euclid(uint32_t color1, uint32_t color2)
433 453
434static unsigned int 454static unsigned int
435_etc2_th_mode_block_pack(uint8_t *etc2, Eina_Bool h_mode, 455_etc2_th_mode_block_pack(uint8_t *etc2, Eina_Bool h_mode,
436 uint32_t color1, uint32_t color2, int distance, 456 uint32_t c1, uint32_t c2, int distance,
437 const uint32_t *bgra, Eina_Bool write, 457 const uint32_t *bgra, Eina_Bool write,
438 Eina_Bool *swap_colors) 458 Eina_Bool *swap_colors)
439{ 459{
440 union { 460 union {
441 uint8_t c[4]; 461 uint8_t c[4];
442 uint32_t v; 462 uint32_t v;
443 } paint_colors[4]; 463 } paint_colors[4], color1, color2;
444 int errAcc = 0; 464 int errAcc = 0;
445 465
466 color1.v = c1;
467 color2.v = c2;
468
446 if (write) 469 if (write)
447 { 470 {
448 memset(etc2 + 4, 0, 4); 471 memset(etc2 + 4, 0, 4);
449 if (!h_mode) 472 if (!h_mode)
450 { 473 {
451 if (!_etc2_t_mode_header_pack(etc2, color1, color2, distance)) 474 if (!_etc2_t_mode_header_pack(etc2, color1.v, color2.v, distance))
452 return INT_MAX; // assert 475 return INT_MAX; // assert
453 } 476 }
454 else 477 else
455 { 478 {
456 if (!_etc2_h_mode_header_pack(etc2, swap_colors, 479 if (!_etc2_h_mode_header_pack(etc2, swap_colors,
457 color1, color2, distance)) 480 color1.v, color2.v, distance))
458 return INT_MAX; // assert 481 return INT_MAX; // assert
459 if (*swap_colors) 482 if (*swap_colors)
460 { 483 {
461 uint32_t tmp = color1; 484 uint32_t tmp = color1.v;
462 color1 = color2; 485 color1.v = color2.v;
463 color2 = tmp; 486 color2.v = tmp;
464 } 487 }
465 } 488 }
466 } 489 }
@@ -469,17 +492,17 @@ _etc2_th_mode_block_pack(uint8_t *etc2, Eina_Bool h_mode,
469 { 492 {
470 if (!h_mode) 493 if (!h_mode)
471 { 494 {
472 paint_colors[0].c[k] = ((uint8_t *) &color1)[k]; 495 paint_colors[0].c[k] = color1.c[k];
473 paint_colors[1].c[k] = CLAMP(((uint8_t *) &color2)[k] + distance); 496 paint_colors[1].c[k] = clampi(color2.c[k] + distance);
474 paint_colors[2].c[k] = ((uint8_t *) &color2)[k]; 497 paint_colors[2].c[k] = color2.c[k];
475 paint_colors[3].c[k] = CLAMP(((uint8_t *) &color2)[k] - distance); 498 paint_colors[3].c[k] = clampi(color2.c[k] - distance);
476 } 499 }
477 else 500 else
478 { 501 {
479 paint_colors[0].c[k] = CLAMP(((uint8_t *) &color1)[k] + distance); 502 paint_colors[0].c[k] = clampi(color1.c[k] + distance);
480 paint_colors[1].c[k] = CLAMP(((uint8_t *) &color1)[k] - distance); 503 paint_colors[1].c[k] = clampi(color1.c[k] - distance);
481 paint_colors[2].c[k] = CLAMP(((uint8_t *) &color2)[k] + distance); 504 paint_colors[2].c[k] = clampi(color2.c[k] + distance);
482 paint_colors[3].c[k] = CLAMP(((uint8_t *) &color2)[k] - distance); 505 paint_colors[3].c[k] = clampi(color2.c[k] - distance);
483 } 506 }
484 } 507 }
485 508
@@ -527,9 +550,9 @@ _color_reduce_444(uint32_t color)
527 B1 = (B & 0xF0) | (B >> 4); 550 B1 = (B & 0xF0) | (B >> 4);
528 B2 = ((B & 0xF0) + 0x10) | ((B >> 4) + 1); 551 B2 = ((B & 0xF0) + 0x10) | ((B >> 4) + 1);
529 552
530 R = (ABS(R - R1) <= ABS(R - R2)) ? R1 : R2; 553 R = (absi(R - R1) <= absi(R - R2)) ? R1 : R2;
531 G = (ABS(G - G1) <= ABS(G - G2)) ? G1 : G2; 554 G = (absi(G - G1) <= absi(G - G2)) ? G1 : G2;
532 B = (ABS(B - B1) <= ABS(B - B2)) ? B1 : B2; 555 B = (absi(B - B1) <= absi(B - B2)) ? B1 : B2;
533 556
534 return BGRA(R, G, B, 255); 557 return BGRA(R, G, B, 255);
535} 558}
@@ -868,9 +891,9 @@ _etc2_planar_mode_block_pack(uint8_t *etc2,
868 for (int y = 0; y < 4; y++) 891 for (int y = 0; y < 4; y++)
869 for (int x = 0; x < 4; x++) 892 for (int x = 0; x < 4; x++)
870 { 893 {
871 const int R = CLAMP(((x * (RH - RO)) + y * (RV - RO) + 4 * RO + 2) >> 2); 894 const int R = clampi(((x * (RH - RO)) + y * (RV - RO) + 4 * RO + 2) >> 2);
872 const int G = CLAMP(((x * (GH - GO)) + y * (GV - GO) + 4 * GO + 2) >> 2); 895 const int G = clampi(((x * (GH - GO)) + y * (GV - GO) + 4 * GO + 2) >> 2);
873 const int B = CLAMP(((x * (BH - BO)) + y * (BV - BO) + 4 * BO + 2) >> 2); 896 const int B = clampi(((x * (BH - BO)) + y * (BV - BO) + 4 * BO + 2) >> 2);
874 uint32_t color = BGRA(R, G, B, 255); 897 uint32_t color = BGRA(R, G, B, 255);
875 898
876 err += _rgb_distance_euclid(color, bgra[x + y * 4]); 899 err += _rgb_distance_euclid(color, bgra[x + y * 4]);
@@ -901,14 +924,14 @@ _etc2_planar_mode_block_encode(uint8_t *etc2, const uint32_t *bgra,
901 BO = B_VAL((bgra[0])); 924 BO = B_VAL((bgra[0]));
902 Ocol = _color_reduce_676(bgra[0]); 925 Ocol = _color_reduce_676(bgra[0]);
903 926
904 Rx = CLAMP(RO + (4 * (R_VAL((bgra[3])) - RO)) / 3); 927 Rx = clampi(RO + (4 * (R_VAL((bgra[3])) - RO)) / 3);
905 Gx = CLAMP(GO + (4 * (G_VAL((bgra[3])) - GO)) / 3); 928 Gx = clampi(GO + (4 * (G_VAL((bgra[3])) - GO)) / 3);
906 Bx = CLAMP(BO + (4 * (B_VAL((bgra[3])) - BO)) / 3); 929 Bx = clampi(BO + (4 * (B_VAL((bgra[3])) - BO)) / 3);
907 Hcol = _color_reduce_676(BGRA(Rx, Gx, Bx, 0xFF)); 930 Hcol = _color_reduce_676(BGRA(Rx, Gx, Bx, 0xFF));
908 931
909 Rx = CLAMP(RO + (4 * (R_VAL((bgra[12])) - RO)) / 3); 932 Rx = clampi(RO + (4 * (R_VAL((bgra[12])) - RO)) / 3);
910 Gx = CLAMP(GO + (4 * (G_VAL((bgra[12])) - GO)) / 3); 933 Gx = clampi(GO + (4 * (G_VAL((bgra[12])) - GO)) / 3);
911 Bx = CLAMP(BO + (4 * (B_VAL((bgra[12])) - BO)) / 3); 934 Bx = clampi(BO + (4 * (B_VAL((bgra[12])) - BO)) / 3);
912 Vcol = _color_reduce_676(BGRA(Rx, Gx, Bx, 0xFF)); 935 Vcol = _color_reduce_676(BGRA(Rx, Gx, Bx, 0xFF));
913 936
914 err = _etc2_planar_mode_block_pack(etc2, Ocol, Hcol, Vcol, bgra, EINA_TRUE); 937 err = _etc2_planar_mode_block_pack(etc2, Ocol, Hcol, Vcol, bgra, EINA_TRUE);
@@ -949,7 +972,7 @@ etc2_rgba8_block_pack(unsigned char *etc2, const unsigned int *bgra,
949#endif 972#endif
950 973
951 safe_params.m_dithering = !!params->m_dithering; 974 safe_params.m_dithering = !!params->m_dithering;
952 safe_params.m_quality = MINMAX(params->m_quality, 0, 2); 975 safe_params.m_quality = minmaxi(params->m_quality, 0, 2);
953 976
954 errors[0] = rg_etc1_pack_block(etc2_try[0], bgra, &safe_params); 977 errors[0] = rg_etc1_pack_block(etc2_try[0], bgra, &safe_params);
955 errors[1] = _etc2_th_mode_block_encode(etc2_try[1], bgra, &safe_params); 978 errors[1] = _etc2_th_mode_block_encode(etc2_try[1], bgra, &safe_params);
@@ -1005,7 +1028,7 @@ etc2_rgb8_block_pack(unsigned char *etc2, const unsigned int *bgra,
1005 int bestSolution = 0; 1028 int bestSolution = 0;
1006 1029
1007 safe_params.m_dithering = !!params->m_dithering; 1030 safe_params.m_dithering = !!params->m_dithering;
1008 safe_params.m_quality = MINMAX(params->m_quality, 0, 2); 1031 safe_params.m_quality = minmaxi(params->m_quality, 0, 2);
1009 1032
1010 errors[0] = rg_etc1_pack_block(etc2_try[0], bgra, &safe_params); 1033 errors[0] = rg_etc1_pack_block(etc2_try[0], bgra, &safe_params);
1011 errors[1] = _etc2_th_mode_block_encode(etc2_try[1], bgra, &safe_params); 1034 errors[1] = _etc2_th_mode_block_encode(etc2_try[1], bgra, &safe_params);