aboutsummaryrefslogtreecommitdiff
path: root/core/image_quantize.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--core/image_quantize.cpp221
1 files changed, 108 insertions, 113 deletions
diff --git a/core/image_quantize.cpp b/core/image_quantize.cpp
index a594aee60..67b7cd518 100644
--- a/core/image_quantize.cpp
+++ b/core/image_quantize.cpp
@@ -27,41 +27,38 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "image.h"
-#include <stdio.h>
#include "print_string.h"
+#include <stdio.h>
#ifdef TOOLS_ENABLED
+#include "os/os.h"
#include "set.h"
#include "sort.h"
-#include "os/os.h"
//#define QUANTIZE_SPEED_OVER_QUALITY
-
Image::MCBlock::MCBlock() {
-
-
}
-Image::MCBlock::MCBlock(BColorPos *p_colors,int p_color_count) {
+Image::MCBlock::MCBlock(BColorPos *p_colors, int p_color_count) {
- colors=p_colors;
- color_count=p_color_count;
- min_color.color=BColor(255,255,255,255);
- max_color.color=BColor(0,0,0,0);
+ colors = p_colors;
+ color_count = p_color_count;
+ min_color.color = BColor(255, 255, 255, 255);
+ max_color.color = BColor(0, 0, 0, 0);
shrink();
}
int Image::MCBlock::get_longest_axis_index() const {
- int max_dist=-1;
- int max_index=0;
+ int max_dist = -1;
+ int max_index = 0;
- for(int i=0;i<4;i++) {
+ for (int i = 0; i < 4; i++) {
- int d = max_color.color.col[i]-min_color.color.col[i];
- if (d>max_dist) {
- max_index=i;
- max_dist=d;
+ int d = max_color.color.col[i] - min_color.color.col[i];
+ if (d > max_dist) {
+ max_index = i;
+ max_dist = d;
}
}
@@ -69,88 +66,80 @@ int Image::MCBlock::get_longest_axis_index() const {
}
int Image::MCBlock::get_longest_axis_length() const {
- int max_dist=-1;
+ int max_dist = -1;
- for(int i=0;i<4;i++) {
+ for (int i = 0; i < 4; i++) {
- int d = max_color.color.col[i]-min_color.color.col[i];
- if (d>max_dist) {
- max_dist=d;
+ int d = max_color.color.col[i] - min_color.color.col[i];
+ if (d > max_dist) {
+ max_dist = d;
}
}
return max_dist;
}
-bool Image::MCBlock::operator<(const MCBlock& p_block) const {
+bool Image::MCBlock::operator<(const MCBlock &p_block) const {
int alen = get_longest_axis_length();
int blen = p_block.get_longest_axis_length();
- if (alen==blen) {
+ if (alen == blen) {
return colors < p_block.colors;
} else
return alen < blen;
-
}
void Image::MCBlock::shrink() {
- min_color=colors[0];
- max_color=colors[0];
+ min_color = colors[0];
+ max_color = colors[0];
- for(int i=1;i<color_count;i++) {
+ for (int i = 1; i < color_count; i++) {
- for(int j=0;j<4;j++) {
+ for (int j = 0; j < 4; j++) {
- min_color.color.col[j]=MIN(min_color.color.col[j],colors[i].color.col[j]);
- max_color.color.col[j]=MAX(max_color.color.col[j],colors[i].color.col[j]);
+ min_color.color.col[j] = MIN(min_color.color.col[j], colors[i].color.col[j]);
+ max_color.color.col[j] = MAX(max_color.color.col[j], colors[i].color.col[j]);
}
}
}
-
-
-
void Image::quantize() {
- bool has_alpha = detect_alpha()!=ALPHA_NONE;
+ bool has_alpha = detect_alpha() != ALPHA_NONE;
- bool quantize_fast=OS::get_singleton()->has_environment("QUANTIZE_FAST");
+ bool quantize_fast = OS::get_singleton()->has_environment("QUANTIZE_FAST");
convert(FORMAT_RGBA);
- ERR_FAIL_COND( format!=FORMAT_RGBA );
+ ERR_FAIL_COND(format != FORMAT_RGBA);
DVector<uint8_t> indexed_data;
-
{
- int color_count = data.size()/4;
+ int color_count = data.size() / 4;
- ERR_FAIL_COND(color_count==0);
+ ERR_FAIL_COND(color_count == 0);
Set<MCBlock> block_queue;
DVector<BColorPos> data_colors;
data_colors.resize(color_count);
- DVector<BColorPos>::Write dcw=data_colors.write();
+ DVector<BColorPos>::Write dcw = data_colors.write();
DVector<uint8_t>::Read dr = data.read();
- const BColor * drptr=(const BColor*)&dr[0];
- BColorPos *bcptr=&dcw[0];
-
-
+ const BColor *drptr = (const BColor *)&dr[0];
+ BColorPos *bcptr = &dcw[0];
{
- for(int i=0;i<color_count;i++) {
+ for (int i = 0; i < color_count; i++) {
//uint32_t data_ofs=i<<2;
- bcptr[i].color=drptr[i];//BColor(drptr[data_ofs+0],drptr[data_ofs+1],drptr[data_ofs+2],drptr[data_ofs+3]);
- bcptr[i].index=i;
+ bcptr[i].color = drptr[i]; //BColor(drptr[data_ofs+0],drptr[data_ofs+1],drptr[data_ofs+2],drptr[data_ofs+3]);
+ bcptr[i].index = i;
}
-
}
//printf("color count: %i\n",color_count);
@@ -161,11 +150,11 @@ void Image::quantize() {
printf("%i - %i,%i,%i,%i\n",i,bc.r,bc.g,bc.b,bc.a);
}*/
- MCBlock initial_block((BColorPos*)&dcw[0],color_count);
+ MCBlock initial_block((BColorPos *)&dcw[0], color_count);
block_queue.insert(initial_block);
- while( block_queue.size() < 256 && block_queue.back()->get().color_count > 1 ) {
+ while (block_queue.size() < 256 && block_queue.back()->get().color_count > 1) {
MCBlock longest = block_queue.back()->get();
//printf("longest: %i (%i)\n",longest.get_longest_axis_index(),longest.get_longest_axis_length());
@@ -173,7 +162,7 @@ void Image::quantize() {
block_queue.erase(block_queue.back());
BColorPos *first = longest.colors;
- BColorPos *median = longest.colors + (longest.color_count+1)/2;
+ BColorPos *median = longest.colors + (longest.color_count + 1) / 2;
BColorPos *end = longest.colors + longest.color_count;
#if 0
@@ -234,111 +223,122 @@ void Image::quantize() {
block_queue.insert(right);
#else
- switch(longest.get_longest_axis_index()) {
- case 0: { SortArray<BColorPos,BColorPos::SortR> sort; sort.nth_element(0,end-first,median-first,first); } break;
- case 1: { SortArray<BColorPos,BColorPos::SortG> sort; sort.nth_element(0,end-first,median-first,first); } break;
- case 2: { SortArray<BColorPos,BColorPos::SortB> sort; sort.nth_element(0,end-first,median-first,first); } break;
- case 3: { SortArray<BColorPos,BColorPos::SortA> sort; sort.nth_element(0,end-first,median-first,first); } break;
-
+ switch (longest.get_longest_axis_index()) {
+ case 0: {
+ SortArray<BColorPos, BColorPos::SortR> sort;
+ sort.nth_element(0, end - first, median - first, first);
+ } break;
+ case 1: {
+ SortArray<BColorPos, BColorPos::SortG> sort;
+ sort.nth_element(0, end - first, median - first, first);
+ } break;
+ case 2: {
+ SortArray<BColorPos, BColorPos::SortB> sort;
+ sort.nth_element(0, end - first, median - first, first);
+ } break;
+ case 3: {
+ SortArray<BColorPos, BColorPos::SortA> sort;
+ sort.nth_element(0, end - first, median - first, first);
+ } break;
}
- MCBlock left(first,median-first);
- MCBlock right(median,end-median);
+ MCBlock left(first, median - first);
+ MCBlock right(median, end - median);
block_queue.insert(left);
block_queue.insert(right);
-
#endif
-
-
}
- while(block_queue.size() > 256) {
+ while (block_queue.size() > 256) {
- block_queue.erase(block_queue.front());// erase least significant
+ block_queue.erase(block_queue.front()); // erase least significant
}
- int res_colors=0;
+ int res_colors = 0;
- int comp_size = (has_alpha?4:3);
- indexed_data.resize(color_count + 256*comp_size);
+ int comp_size = (has_alpha ? 4 : 3);
+ indexed_data.resize(color_count + 256 * comp_size);
DVector<uint8_t>::Write iw = indexed_data.write();
- uint8_t *iwptr=&iw[0];
+ uint8_t *iwptr = &iw[0];
BColor pallete[256];
- // print_line("applying quantization - res colors "+itos(block_queue.size()));
+ // print_line("applying quantization - res colors "+itos(block_queue.size()));
- while(block_queue.size()) {
+ while (block_queue.size()) {
const MCBlock &b = block_queue.back()->get();
- uint64_t sum[4]={0,0,0,0};
+ uint64_t sum[4] = { 0, 0, 0, 0 };
- for(int i=0;i<b.color_count;i++) {
+ for (int i = 0; i < b.color_count; i++) {
- sum[0]+=b.colors[i].color.col[0];
- sum[1]+=b.colors[i].color.col[1];
- sum[2]+=b.colors[i].color.col[2];
- sum[3]+=b.colors[i].color.col[3];
+ sum[0] += b.colors[i].color.col[0];
+ sum[1] += b.colors[i].color.col[1];
+ sum[2] += b.colors[i].color.col[2];
+ sum[3] += b.colors[i].color.col[3];
}
- BColor c( sum[0]/b.color_count, sum[1]/b.color_count, sum[2]/b.color_count, sum[3]/b.color_count );
-
-
+ BColor c(sum[0] / b.color_count, sum[1] / b.color_count, sum[2] / b.color_count, sum[3] / b.color_count);
//printf(" %i: %i,%i,%i,%i out of %i\n",res_colors,c.r,c.g,c.b,c.a,b.color_count);
-
-
- for(int i=0;i<comp_size;i++) {
- iwptr[ color_count + res_colors * comp_size + i ] = c.col[i];
+ for (int i = 0; i < comp_size; i++) {
+ iwptr[color_count + res_colors * comp_size + i] = c.col[i];
}
if (quantize_fast) {
- for(int i=0;i<b.color_count;i++) {
- iwptr[b.colors[i].index]=res_colors;
+ for (int i = 0; i < b.color_count; i++) {
+ iwptr[b.colors[i].index] = res_colors;
}
} else {
- pallete[res_colors]=c;
+ pallete[res_colors] = c;
}
-
res_colors++;
block_queue.erase(block_queue.back());
-
}
-
if (!quantize_fast) {
- for(int i=0;i<color_count;i++) {
+ for (int i = 0; i < color_count; i++) {
- const BColor &c=drptr[i];
- uint8_t best_dist_idx=0;
- uint32_t dist=0xFFFFFFFF;
+ const BColor &c = drptr[i];
+ uint8_t best_dist_idx = 0;
+ uint32_t dist = 0xFFFFFFFF;
- for(int j=0;j<res_colors;j++) {
+ for (int j = 0; j < res_colors; j++) {
- const BColor &pc=pallete[j];
+ const BColor &pc = pallete[j];
uint32_t d = 0;
- { int16_t v = (int16_t)c.r-(int16_t)pc.r; d+=v*v; }
- { int16_t v = (int16_t)c.g-(int16_t)pc.g; d+=v*v; }
- { int16_t v = (int16_t)c.b-(int16_t)pc.b; d+=v*v; }
- { int16_t v = (int16_t)c.a-(int16_t)pc.a; d+=v*v; }
+ {
+ int16_t v = (int16_t)c.r - (int16_t)pc.r;
+ d += v * v;
+ }
+ {
+ int16_t v = (int16_t)c.g - (int16_t)pc.g;
+ d += v * v;
+ }
+ {
+ int16_t v = (int16_t)c.b - (int16_t)pc.b;
+ d += v * v;
+ }
+ {
+ int16_t v = (int16_t)c.a - (int16_t)pc.a;
+ d += v * v;
+ }
- if (d<=dist) {
- best_dist_idx=j;
- dist=d;
+ if (d <= dist) {
+ best_dist_idx = j;
+ dist = d;
}
}
-
- iwptr[ i ] = best_dist_idx;
-
+ iwptr[i] = best_dist_idx;
}
}
@@ -348,18 +348,13 @@ void Image::quantize() {
}
print_line(itos(indexed_data.size()));
- data=indexed_data;
- format=has_alpha?FORMAT_INDEXED_ALPHA:FORMAT_INDEXED;
-
+ data = indexed_data;
+ format = has_alpha ? FORMAT_INDEXED_ALPHA : FORMAT_INDEXED;
} //do none
-
-
#else
-
void Image::quantize() {} //do none
-
#endif