diff options
Diffstat (limited to '')
| -rw-r--r-- | core/image_quantize.cpp | 221 |
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 |
