summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2014-04-22 11:52:53 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2014-04-22 18:30:26 +0900
commit59b660aae9a912eee8e0bd458352fba435943284 (patch)
treecf6e29b93543bcd30c469d0b4146c2c1ed77db13
parent2ff9b054f9cded810d6be76af2a3e6dd006ac4ac (diff)
rg_etc1: Fix RGBA vs BGRA mishandling of the ETC1 codec
Evas uses BGRA data while rg_etc1 uses RGBA data, so there were incompatibilities between the two. Now, rg_etc1 will take BGRA data as input and output.
-rw-r--r--src/static_libs/rg_etc/rg_etc1.c191
1 files changed, 128 insertions, 63 deletions
diff --git a/src/static_libs/rg_etc/rg_etc1.c b/src/static_libs/rg_etc/rg_etc1.c
index 1b36889..2df3202 100644
--- a/src/static_libs/rg_etc/rg_etc1.c
+++ b/src/static_libs/rg_etc/rg_etc1.c
@@ -46,6 +46,14 @@ typedef unsigned char DATA8;
46#define cUINT64_MAX ULLONG_MAX 46#define cUINT64_MAX ULLONG_MAX
47#define RG_ETC1_ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0])) 47#define RG_ETC1_ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0]))
48 48
49// Some configuration defines
50
51// Disable this constrained function, it produces artifacts (in black areas mostly)
52#define RG_ETC1_CONSTRAINED_SUBBLOCK 0
53// Disable dithering. It uses invalid RGBA order and isn't great visually
54// Dithering should happen AFTER the color selection, not before
55#define RG_ETC1_DITHERING 0
56
49enum RG_Etc_Constants 57enum RG_Etc_Constants
50 { 58 {
51 cETC1BytesPerBlock = 8U, 59 cETC1BytesPerBlock = 8U,
@@ -105,26 +113,48 @@ enum RG_Etc_Constants
105 // 0 1 2 3 -4 -3 -2 -1 113 // 0 1 2 3 -4 -3 -2 -1
106 }; 114 };
107 115
116/*
117 * IMPORTANT NOTE:
118 *
119 * rg_etc1 originally works only on R,G,B,A data
120 * evas works on B,G,R,A data
121 *
122 * ARGB_JOIN() is used for unpacking, so it will directly produce BGRA.
123 *
124 * Upon packing, we convert BGRA to RGBA so we can use the precomputed tables,
125 * so we must use the X_VAL_GET() macros.
126 * Upon unpacking, we directly output BGRA data using ARGB_JOIN() and X_VAL_SET()
127 *
128 * Yes, this is a mess. Maybe a clear BGRA API is needed
129 */
130
108#ifndef WORDS_BIGENDIAN 131#ifndef WORDS_BIGENDIAN
109/* x86 */ 132// BGRA
110#define R_VAL(p) (((DATA8 *)(p))[0]) 133#define A_VAL_SET(p) (((DATA8 *)(p))[3])
111#define G_VAL(p) (((DATA8 *)(p))[1]) 134#define R_VAL_SET(p) (((DATA8 *)(p))[2])
112#define B_VAL(p) (((DATA8 *)(p))[2]) 135#define G_VAL_SET(p) (((DATA8 *)(p))[1])
113#define A_VAL(p) (((DATA8 *)(p))[3]) 136#define B_VAL_SET(p) (((DATA8 *)(p))[0])
114#define BA_VAL(p) ((DATA16 *)(p)[1]) 137// RGBA
115#define RG_VAL(p) ((DATA16 *)(p)[0]) 138#define A_VAL_GET(p) (((DATA8 *)(p))[3])
139#define R_VAL_GET(p) (((DATA8 *)(p))[0])
140#define G_VAL_GET(p) (((DATA8 *)(p))[1])
141#define B_VAL_GET(p) (((DATA8 *)(p))[2])
116#else 142#else
117/* ppc */ 143// BIGENDIAN is untested
118#define R_VAL(p) (((DATA8 *)(p))[3]) 144#define A_VAL_SET(p) (((DATA8 *)(p))[0])
119#define G_VAL(p) (((DATA8 *)(p))[2]) 145#define R_VAL_SET(p) (((DATA8 *)(p))[1])
120#define B_VAL(p) (((DATA8 *)(p))[1]) 146#define G_VAL_SET(p) (((DATA8 *)(p))[2])
121#define A_VAL(p) (((DATA8 *)(p))[0]) 147#define B_VAL_SET(p) (((DATA8 *)(p))[3])
122#define BA_VAL(p) ((DATA16 *)(p)[0]) 148#define A_VAL_GET(p) (((DATA8 *)(p))[0])
123#define RG_VAL(p) ((DATA16 *)(p)[1]) 149#define R_VAL_GET(p) (((DATA8 *)(p))[3])
150#define G_VAL_GET(p) (((DATA8 *)(p))[2])
151#define B_VAL_GET(p) (((DATA8 *)(p))[1])
124#endif 152#endif
125 153
126#define ARGB_JOIN(a,r,g,b) \ 154// For unpacking and writing BGRA output data
127 (((a) << 24) + ((b) << 16) + ((g) << 8) + (r)) 155#define ARGB_JOIN(a,r,g,b) \
156 (((a) << 24) + ((r) << 16) + ((g) << 8) + (b))
157
128static unsigned char rg_etc_quant5_tab[256 + 16]; 158static unsigned char rg_etc_quant5_tab[256 + 16];
129 159
130static const int rg_etc1_inten_tables[cETC1IntenModifierValues][cETC1SelectorValues] = { 160static const int rg_etc1_inten_tables[cETC1IntenModifierValues][cETC1SelectorValues] = {
@@ -428,14 +458,16 @@ typedef union
428 unsigned char a; 458 unsigned char a;
429 } comp; 459 } comp;
430 460
431 unsigned char c[4];
432
433 unsigned int m_u32; 461 unsigned int m_u32;
434} color_quad_u8; 462} color_quad_u8;
435 463
436static inline int 464static inline int
437rg_etc1_color_quad_u8_clamp(int v) 465rg_etc1_color_quad_u8_clamp(int v)
438{ 466{
467 /* FIXME: (From Wikipedia)
468 * "In C, the result of right-shifting a negative value is implementation-defined"
469 * The following code assumes right-shift will duplicate the sign bit.
470 */
439 if (v & 0xFFFFFF00U) 471 if (v & 0xFFFFFF00U)
440 v = ((~v) >> 31) & 0xFF; 472 v = ((~v) >> 31) & 0xFF;
441 return v; 473 return v;
@@ -464,14 +496,13 @@ rg_etc1_color_quad_u8_clear(color_quad_u8 *color)
464static inline unsigned int 496static inline unsigned int
465rg_etc1_color_quad_u8_rgb_squared_distance(color_quad_u8 color1, color_quad_u8 color2) 497rg_etc1_color_quad_u8_rgb_squared_distance(color_quad_u8 color1, color_quad_u8 color2)
466{ 498{
467
468 return SQUARE((color1.comp.r - color2.comp.r)) + SQUARE((color1.comp.g - color2.comp.g)) + SQUARE((color1.comp.b - color2.comp.b)); 499 return SQUARE((color1.comp.r - color2.comp.r)) + SQUARE((color1.comp.g - color2.comp.g)) + SQUARE((color1.comp.b - color2.comp.b));
469} 500}
470 501
502#if RG_ETC1_CONSTRAINED_SUBBLOCK
471static inline void 503static inline void
472rg_etc1_color_quad_u8_component_set(color_quad_u8 *color, unsigned char idx, unsigned char value) 504rg_etc1_color_quad_u8_component_set(color_quad_u8 *color, unsigned char idx, unsigned char value)
473{ 505{
474
475 switch (idx) 506 switch (idx)
476 { 507 {
477 case 0: color->comp.r = value; break; 508 case 0: color->comp.r = value; break;
@@ -480,14 +511,16 @@ rg_etc1_color_quad_u8_component_set(color_quad_u8 *color, unsigned char idx, uns
480 case 3: color->comp.a = value; break; 511 case 3: color->comp.a = value; break;
481 default: abort(); 512 default: abort();
482 } 513 }
483
484} 514}
515#endif
485 516
517#if 0
486static inline unsigned int 518static inline unsigned int
487rg_etc1_color_quad_duplicate_init(unsigned char y, unsigned char alpha) 519rg_etc1_color_quad_duplicate_init(unsigned char y, unsigned char alpha)
488{ 520{
489 return ARGB_JOIN(alpha, y, y, y); 521 return ARGB_JOIN(alpha, y, y, y);
490} 522}
523#endif
491 524
492static inline unsigned int 525static inline unsigned int
493rg_etc1_color_quad_init(unsigned char r, unsigned char g, unsigned char b, unsigned char alpha) 526rg_etc1_color_quad_init(unsigned char r, unsigned char g, unsigned char b, unsigned char alpha)
@@ -502,10 +535,11 @@ rg_etc1_color_quad_set(unsigned int old_color, unsigned int new_color, unsigned
502 { 535 {
503 unsigned char r, g, b, a; 536 unsigned char r, g, b, a;
504 537
505 a = A_VAL(&old_color); 538 // Used for UNPACKING
506 r = R_VAL(&new_color); 539 a = A_VAL_SET(&old_color);
507 g = G_VAL(&new_color); 540 r = R_VAL_SET(&new_color);
508 b = B_VAL(&new_color); 541 g = G_VAL_SET(&new_color);
542 b = B_VAL_SET(&new_color);
509 543
510 return ARGB_JOIN(a, r, g, b); 544 return ARGB_JOIN(a, r, g, b);
511 } 545 }
@@ -515,26 +549,31 @@ rg_etc1_color_quad_set(unsigned int old_color, unsigned int new_color, unsigned
515static inline void 549static inline void
516rg_etc1_color_quad_get(unsigned int color, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *alpha) 550rg_etc1_color_quad_get(unsigned int color, unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *alpha)
517{ 551{
518 if (r) *r = R_VAL(&color); 552 // Used for PACKING
519 if (g) *g = G_VAL(&color); 553 if (r) *r = R_VAL_GET(&color);
520 if (b) *b = B_VAL(&color); 554 if (g) *g = G_VAL_GET(&color);
521 if (alpha) *alpha = A_VAL(&color); 555 if (b) *b = B_VAL_GET(&color);
556 if (alpha) *alpha = A_VAL_GET(&color);
522} 557}
523 558
559#if RG_ETC1_CONSTRAINED_SUBBLOCK
524static inline unsigned char 560static inline unsigned char
525rg_etc1_color_quad_component_get(unsigned int color, unsigned char idx) 561rg_etc1_color_quad_component_get(unsigned int color, unsigned char idx)
526{ 562{
527 switch (idx) 563 switch (idx)
528 { 564 {
529 case 0: return R_VAL(&color); 565 // FIXME: Untested code (RGBA vs BGRA)
530 case 1: return G_VAL(&color); 566 case 0: return R_VAL_GET(&color);
531 case 2: return B_VAL(&color); 567 case 1: return G_VAL_GET(&color);
532 case 3: return A_VAL(&color); 568 case 2: return B_VAL_GET(&color);
569 case 3: return A_VAL_GET(&color);
533 default: abort(); 570 default: abort();
534 } 571 }
535 return 0; 572 return 0;
536} 573}
574#endif
537 575
576#if 0
538static inline unsigned int 577static inline unsigned int
539rg_etc1_color_quad_component_set(unsigned int color, unsigned char idx, unsigned char value) 578rg_etc1_color_quad_component_set(unsigned int color, unsigned char idx, unsigned char value)
540{ 579{
@@ -559,7 +598,7 @@ rg_etc1_color_quad_grayscale_set(unsigned int color, unsigned char l)
559{ 598{
560 unsigned char a; 599 unsigned char a;
561 600
562 a = A_VAL(&color); 601 a = A_VAL_SET(&color);
563 602
564 return rg_etc1_color_quad_init(l, l, l, a); 603 return rg_etc1_color_quad_init(l, l, l, a);
565} 604}
@@ -635,8 +674,8 @@ rg_etc1_color_quad_argb_squared_distance(unsigned int color1, unsigned int color
635static inline unsigned char 674static inline unsigned char
636rg_etc1_color_quad_rgb_equals(unsigned int color1, unsigned int color2) 675rg_etc1_color_quad_rgb_equals(unsigned int color1, unsigned int color2)
637{ 676{
638 A_VAL(&color1) = 0; 677 A_VAL_SET(&color1) = 0;
639 A_VAL(&color2) = 0; 678 A_VAL_SET(&color2) = 0;
640 679
641 return color1 == color2; 680 return color1 == color2;
642} 681}
@@ -676,6 +715,7 @@ rg_etc1_color_quad_del(unsigned int color1, unsigned int color2)
676 715
677 return color1; 716 return color1;
678} 717}
718#endif
679 719
680static inline void 720static inline void
681rg_etc1_vec_init(float v[3], float s) 721rg_etc1_vec_init(float v[3], float s)
@@ -1162,7 +1202,7 @@ rg_etc1_block_subblock_color4_abs_get(unsigned int dst[4], unsigned short packed
1162 1202
1163// This is the exported function to unpack a block 1203// This is the exported function to unpack a block
1164bool 1204bool
1165rg_etc1_unpack_block(const void *ETC1_block, unsigned int *pixels, bool preserve_alpha) 1205rg_etc1_unpack_block(const void *ETC1_block, unsigned int *pDst_pixels_BGRA, bool preserve_alpha)
1166{ 1206{
1167 unsigned char diff_flag, flip_flag, table_index0, table_index1; 1207 unsigned char diff_flag, flip_flag, table_index0, table_index1;
1168 unsigned int subblock_colors0[4] = { 0 }; 1208 unsigned int subblock_colors0[4] = { 0 };
@@ -1216,19 +1256,19 @@ rg_etc1_unpack_block(const void *ETC1_block, unsigned int *pixels, bool preserve
1216 for (y = 0; y < 2; y++) 1256 for (y = 0; y < 2; y++)
1217 { 1257 {
1218 for (x = 0; x < 4; x++) 1258 for (x = 0; x < 4; x++)
1219 pixels[x] = rg_etc1_color_quad_set(pixels[x], 1259 pDst_pixels_BGRA[x] = rg_etc1_color_quad_set(pDst_pixels_BGRA[x],
1220 subblock_colors0[rg_etc1_block_selector_get(ETC1_block, x, y)], 1260 subblock_colors0[rg_etc1_block_selector_get(ETC1_block, x, y)],
1221 preserve_alpha); 1261 preserve_alpha);
1222 pixels += 4; 1262 pDst_pixels_BGRA += 4;
1223 } 1263 }
1224 1264
1225 for (y = 2; y < 4; y++) 1265 for (y = 2; y < 4; y++)
1226 { 1266 {
1227 for (x = 0; x < 4; x++) 1267 for (x = 0; x < 4; x++)
1228 pixels[x] = rg_etc1_color_quad_set(pixels[x], 1268 pDst_pixels_BGRA[x] = rg_etc1_color_quad_set(pDst_pixels_BGRA[x],
1229 subblock_colors1[rg_etc1_block_selector_get(ETC1_block, x, y)], 1269 subblock_colors1[rg_etc1_block_selector_get(ETC1_block, x, y)],
1230 preserve_alpha); 1270 preserve_alpha);
1231 pixels += 4; 1271 pDst_pixels_BGRA += 4;
1232 } 1272 }
1233 } 1273 }
1234 else 1274 else
@@ -1236,15 +1276,15 @@ rg_etc1_unpack_block(const void *ETC1_block, unsigned int *pixels, bool preserve
1236 for (y = 0; y < 4; y++) 1276 for (y = 0; y < 4; y++)
1237 { 1277 {
1238 for (x = 0; x < 2; x++) 1278 for (x = 0; x < 2; x++)
1239 pixels[x] = rg_etc1_color_quad_set(pixels[x], 1279 pDst_pixels_BGRA[x] = rg_etc1_color_quad_set(pDst_pixels_BGRA[x],
1240 subblock_colors0[rg_etc1_block_selector_get(ETC1_block, x, y)], 1280 subblock_colors0[rg_etc1_block_selector_get(ETC1_block, x, y)],
1241 preserve_alpha); 1281 preserve_alpha);
1242 for (; x < 4; x++) 1282 for (; x < 4; x++)
1243 pixels[x] = rg_etc1_color_quad_set(pixels[x], 1283 pDst_pixels_BGRA[x] = rg_etc1_color_quad_set(pDst_pixels_BGRA[x],
1244 subblock_colors1[rg_etc1_block_selector_get(ETC1_block, x, y)], 1284 subblock_colors1[rg_etc1_block_selector_get(ETC1_block, x, y)],
1245 preserve_alpha); 1285 preserve_alpha);
1246 1286
1247 pixels += 4; 1287 pDst_pixels_BGRA += 4;
1248 } 1288 }
1249 } 1289 }
1250 1290
@@ -1438,9 +1478,7 @@ rg_etc1_solution_coordinates_get_scaled_color(color_quad_u8 *color, const Etc1_S
1438 unsigned char br, bg, bb; 1478 unsigned char br, bg, bb;
1439 1479
1440 rg_etc1_solution_coordinates_component_get(coords, &br, &bg, &bb); 1480 rg_etc1_solution_coordinates_component_get(coords, &br, &bg, &bb);
1441 1481 rg_etc1_color_quad_u8_init(color, br, bg, bb, 255);
1442 rg_etc1_color_quad_u8_init(color,br, bg, bb, 255);
1443
1444} 1482}
1445 1483
1446static inline void 1484static inline void
@@ -2112,8 +2150,10 @@ void rg_etc1_pack_block_init()
2112// Packs solid color blocks efficiently using a set of small precomputed tables. 2150// Packs solid color blocks efficiently using a set of small precomputed tables.
2113// For random 888 inputs, MSE results are better than Erricson's ETC1 packer in "slow" mode ~9.5% of the time, is slightly worse only ~.01% of the time, and is equal the rest of the time. 2151// For random 888 inputs, MSE results are better than Erricson's ETC1 packer in "slow" mode ~9.5% of the time, is slightly worse only ~.01% of the time, and is equal the rest of the time.
2114static uint64 2152static uint64
2115rg_etc1_pack_block_solid_color(unsigned char *block, const uint8* pColor, rg_etc1_pack_params *pack_params EINA_UNUSED) 2153rg_etc1_pack_block_solid_color(unsigned char *block, const color_quad_u8 *color, rg_etc1_pack_params *pack_params EINA_UNUSED)
2116{ 2154{
2155 const uint8 *pColor = (uint8 *) &color->m_u32;
2156
2117 if (!rg_etc1_inverse_lookup[0][255]) 2157 if (!rg_etc1_inverse_lookup[0][255])
2118 rg_etc1_pack_block_init(); 2158 rg_etc1_pack_block_init();
2119 2159
@@ -2123,8 +2163,7 @@ rg_etc1_pack_block_solid_color(unsigned char *block, const uint8* pColor, rg_etc
2123 return 0; 2163 return 0;
2124 } 2164 }
2125 2165
2126 static uint s_next_comp[4] = { 1, 2, 0, 1 }; 2166 const uint s_next_comp[4] = { 1, 2, 0, 1 };
2127
2128 uint best_error = cUINT32_MAX, best_i = 0; 2167 uint best_error = cUINT32_MAX, best_i = 0;
2129 int best_x = 0, best_packed_c1 = 0, best_packed_c2 = 0; 2168 int best_x = 0, best_packed_c1 = 0, best_packed_c2 = 0;
2130 uint i; 2169 uint i;
@@ -2133,13 +2172,15 @@ rg_etc1_pack_block_solid_color(unsigned char *block, const uint8* pColor, rg_etc
2133 // that allow that 8-bit value to be encoded with no error. 2172 // that allow that 8-bit value to be encoded with no error.
2134 for (i = 0; i < 3; i++) 2173 for (i = 0; i < 3; i++)
2135 { 2174 {
2136 const uint c1 = pColor[s_next_comp[i]], c2 = pColor[s_next_comp[i + 1]]; 2175 const int c0 = pColor[i];
2176 const int c1 = pColor[s_next_comp[i]];
2177 const int c2 = pColor[s_next_comp[i + 1]];
2137 2178
2138 const int delta_range = 1; 2179 const int delta_range = 1;
2139 int delta; 2180 int delta;
2140 for (delta = -delta_range; delta <= delta_range; delta++) 2181 for (delta = -delta_range; delta <= delta_range; delta++)
2141 { 2182 {
2142 const int c_plus_delta = CLAMP(pColor[i] + delta, 0, 255); 2183 const int c_plus_delta = CLAMP(c0 + delta, 0, 255);
2143 2184
2144 uint16* pTable; 2185 uint16* pTable;
2145 if (!c_plus_delta) 2186 if (!c_plus_delta)
@@ -2168,7 +2209,7 @@ rg_etc1_pack_block_solid_color(unsigned char *block, const uint8* pColor, rg_etc
2168 pInverse_table = rg_etc1_inverse_lookup[x & 0xFF]; 2209 pInverse_table = rg_etc1_inverse_lookup[x & 0xFF];
2169 p1 = pInverse_table[c1]; 2210 p1 = pInverse_table[c1];
2170 p2 = pInverse_table[c2]; 2211 p2 = pInverse_table[c2];
2171 trial_error = SQUARE((c_plus_delta - pColor[i])) + SQUARE((p1 >> 8)) + SQUARE((p2 >> 8)); 2212 trial_error = SQUARE((c_plus_delta - c0)) + SQUARE((p1 >> 8)) + SQUARE((p2 >> 8));
2172 if (trial_error < best_error) 2213 if (trial_error < best_error)
2173 { 2214 {
2174 best_error = trial_error; 2215 best_error = trial_error;
@@ -2216,7 +2257,7 @@ rg_etc1_pack_block_solid_color(unsigned char *block, const uint8* pColor, rg_etc
2216 return best_error; 2257 return best_error;
2217} 2258}
2218 2259
2219#if 0 2260#if RG_ETC1_CONSTRAINED_SUBBLOCK
2220static uint 2261static uint
2221rg_etc1_pack_block_solid_color_constrained(rg_etc1_optimizer_results *results,uint num_colors, 2262rg_etc1_pack_block_solid_color_constrained(rg_etc1_optimizer_results *results,uint num_colors,
2222 const uint8* pColor, rg_etc1_pack_params *pack_params EINA_UNUSED, 2263 const uint8* pColor, rg_etc1_pack_params *pack_params EINA_UNUSED,
@@ -2347,6 +2388,7 @@ rg_etc1_pack_block_solid_color_constrained(rg_etc1_optimizer_results *results,ui
2347} 2388}
2348#endif 2389#endif
2349 2390
2391#if RG_ETC1_DITHERING
2350// Function originally from RYG's public domain real-time DXT1 compressor, modified for 555. 2392// Function originally from RYG's public domain real-time DXT1 compressor, modified for 555.
2351static void 2393static void
2352rg_etc1_dither_block_555(color_quad_u8* dest, color_quad_u8* block) 2394rg_etc1_dither_block_555(color_quad_u8* dest, color_quad_u8* block)
@@ -2393,15 +2435,33 @@ rg_etc1_dither_block_555(color_quad_u8* dest, color_quad_u8* block)
2393 } 2435 }
2394 } 2436 }
2395} 2437}
2438#endif
2439
2440static inline unsigned int
2441_bgra_to_rgba(unsigned int val)
2442{
2443 //(((a) << 24) + ((r) << 16) + ((g) << 8) + (b))
2444 return ARGB_JOIN(A_VAL_GET(&val), R_VAL_GET(&val), G_VAL_GET(&val), B_VAL_GET(&val));
2445}
2446
2447static void
2448_bgra_to_rgba_block(color_quad_u8 *output, const unsigned int *input, int len)
2449{
2450 for (int k = len; k; --k)
2451 {
2452 output->m_u32 = _bgra_to_rgba(*input++);
2453 output++;
2454 }
2455}
2396 2456
2397unsigned int 2457unsigned int
2398rg_etc1_pack_block(void* pETC1_block, const unsigned int* pSrc_pixels_rgba, rg_etc1_pack_params *pack_params) 2458rg_etc1_pack_block(void* pETC1_block, const unsigned int* pSrc_pixels_BGRA, rg_etc1_pack_params *pack_params)
2399{ 2459{
2400 color_quad_u8* pSrc_pixels = (color_quad_u8 *)pSrc_pixels_rgba; 2460 color_quad_u8 pSrc_pixels[16];
2401 unsigned char *dst_block = (unsigned char *)pETC1_block; 2461 unsigned char *dst_block = (unsigned char *)pETC1_block;
2402 unsigned int first_pixel_u32; 2462 unsigned int first_pixel_u32;
2403 int r; 2463 int r;
2404 color_quad_u8 dithered_pixels[16], subblock_pixels[8]; 2464 color_quad_u8 subblock_pixels[8];
2405 uint64 best_error = cUINT64_MAX; 2465 uint64 best_error = cUINT64_MAX;
2406 uint best_use_color4=EINA_FALSE; 2466 uint best_use_color4=EINA_FALSE;
2407 uint best_flip=EINA_FALSE; 2467 uint best_flip=EINA_FALSE;
@@ -2417,7 +2477,6 @@ rg_etc1_pack_block(void* pETC1_block, const unsigned int* pSrc_pixels_rgba, rg_e
2417 static const int s_scan_delta_0_to_4[] = { -4, -3, -2, -1, 0, 1, 2, 3, 4 }; 2477 static const int s_scan_delta_0_to_4[] = { -4, -3, -2, -1, 0, 1, 2, 3, 4 };
2418 static const int s_scan_delta_0_to_1[] = { -1, 0, 1 }; 2478 static const int s_scan_delta_0_to_1[] = { -1, 0, 1 };
2419 static const int s_scan_delta_0[] = { 0 }; 2479 static const int s_scan_delta_0[] = { 0 };
2420 first_pixel_u32 = *pSrc_pixels_rgba;
2421 2480
2422#ifdef RG_ETC1_BUILD_DEBUG 2481#ifdef RG_ETC1_BUILD_DEBUG
2423 // Ensure all alpha values are 0xFF. 2482 // Ensure all alpha values are 0xFF.
@@ -2429,19 +2488,26 @@ rg_etc1_pack_block(void* pETC1_block, const unsigned int* pSrc_pixels_rgba, rg_e
2429#endif 2488#endif
2430 rg_etc1_optimizer_clear(&optimizer); 2489 rg_etc1_optimizer_clear(&optimizer);
2431 2490
2491 // Convert evas BGRA to rg_etc1 RGBA
2492 _bgra_to_rgba_block(pSrc_pixels, pSrc_pixels_BGRA, 16);
2493 first_pixel_u32 = pSrc_pixels[0].m_u32;
2494
2432 // Check for solid block. 2495 // Check for solid block.
2433 for (r = 15; r >= 1; --r) 2496 for (r = 15; r >= 1; --r)
2434 if (pSrc_pixels[r].m_u32 != first_pixel_u32) 2497 if (pSrc_pixels[r].m_u32 != first_pixel_u32)
2435 break; 2498 break;
2436 if (!r) 2499 if (!r)
2437 return (unsigned int)(16 * rg_etc1_pack_block_solid_color(dst_block, &pSrc_pixels[0].comp.r, pack_params)); 2500 return (unsigned int)(16 * rg_etc1_pack_block_solid_color(dst_block, &pSrc_pixels[0], pack_params));
2438 2501
2502#if RG_ETC1_DITHERING
2439 // Dithering gives mitigated results... It would be nice to know when to use it. 2503 // Dithering gives mitigated results... It would be nice to know when to use it.
2504 color_quad_u8 dithered_pixels[16];
2440 if (pack_params->m_dithering) 2505 if (pack_params->m_dithering)
2441 { 2506 {
2442 rg_etc1_dither_block_555(dithered_pixels, pSrc_pixels); 2507 rg_etc1_dither_block_555(dithered_pixels, pSrc_pixels);
2443 pSrc_pixels = dithered_pixels; 2508 pSrc_pixels = dithered_pixels;
2444 } 2509 }
2510#endif
2445 2511
2446 for (i = 0; i < 2; i++) 2512 for (i = 0; i < 2; i++)
2447 { 2513 {
@@ -2473,6 +2539,8 @@ rg_etc1_pack_block(void* pETC1_block, const unsigned int* pSrc_pixels_rgba, rg_e
2473 uint subblock; 2539 uint subblock;
2474 for (subblock = 0; subblock < 2; subblock++) 2540 for (subblock = 0; subblock < 2; subblock++)
2475 { 2541 {
2542 results[2].m_error = cUINT64_MAX;
2543
2476 if (flip) 2544 if (flip)
2477 // subblock is top or bottom, copy source 2545 // subblock is top or bottom, copy source
2478 memcpy(subblock_pixels, pSrc_pixels + subblock * 8, sizeof(color_quad_u8) * 8); 2546 memcpy(subblock_pixels, pSrc_pixels + subblock * 8, sizeof(color_quad_u8) * 8);
@@ -2490,10 +2558,7 @@ rg_etc1_pack_block(void* pETC1_block, const unsigned int* pSrc_pixels_rgba, rg_e
2490 rg_etc1_color_quad_u8_copy(&subblock_pixels[7], &pSrc_col[13]); 2558 rg_etc1_color_quad_u8_copy(&subblock_pixels[7], &pSrc_col[13]);
2491 } 2559 }
2492 2560
2493 results[2].m_error = cUINT64_MAX; 2561#if RG_ETC1_CONSTRAINED_SUBBLOCK
2494
2495#if 0
2496 // This feature is disabled because it will produce some visual artifacts
2497 if ((params.base_params->m_quality >= rg_etc1_medium_quality) && ((subblock) || (use_color4))) 2562 if ((params.base_params->m_quality >= rg_etc1_medium_quality) && ((subblock) || (use_color4)))
2498 { 2563 {
2499 const uint32 subblock_pixel0_u32 = subblock_pixels[0].m_u32; 2564 const uint32 subblock_pixel0_u32 = subblock_pixels[0].m_u32;